/
/
/
Ansible role that deployes services on my runner machine
1---
2
3- name: Configure Git safe directory for CVAT
4 command: git config --global --add safe.directory "{{ cvat_config_dir }}"
5 changed_when: false
6
7- name: Clone CVAT upstream at pinned version
8 git:
9 repo: "{{ cvat_repo_url }}"
10 dest: "{{ cvat_config_dir }}"
11 version: "{{ cvat_repo_version }}"
12 force: yes
13
14- name: Set ownership on CVAT install dir
15 file:
16 path: "{{ cvat_config_dir }}"
17 state: directory
18 owner: "{{ runner_user }}"
19 group: "{{ runner_group }}"
20 mode: '2775'
21 recurse: true
22
23- name: Check CVAT share dir exists
24 stat:
25 path: "{{ cvat_share_dir }}"
26 register: cvat_share_stat
27
28- name: Fail if CVAT share dir missing
29 fail:
30 msg: "CVAT share {{ cvat_share_dir }} not found. Ensure NFS mounts ran first."
31 when: not cvat_share_stat.stat.exists
32
33- name: Write .env for compose
34 template:
35 src: "cvat.env.j2"
36 dest: "{{ cvat_config_dir }}/.env"
37 owner: "{{ runner_user }}"
38 group: "{{ runner_group }}"
39 mode: '0664'
40
41- name: Modify base Docker Compose file ports
42 lineinfile:
43 path: "{{ cvat_config_dir }}/docker-compose.yml"
44 regexp: '^\s+- "?8080:8080"?$'
45 line: ' - "{{ cvat_http_port }}:8080"'
46 backrefs: yes
47 notify: restart cvat
48
49- name: Modify base Docker Compose dashboard ports
50 lineinfile:
51 path: "{{ cvat_config_dir }}/docker-compose.yml"
52 regexp: '^\s+- "?8090:8090"?$'
53 line: ' - "{{ cvat_dashboard_port }}:8090"'
54 backrefs: yes
55 notify: restart cvat
56
57- name: Add share volume mount to base Docker Compose
58 lineinfile:
59 path: "{{ cvat_config_dir }}/docker-compose.yml"
60 insertafter: '^\s+- cvat_keys:/home/django/keys'
61 line: ' - "{{ cvat_share_dir }}:/home/django/share:ro"'
62 notify: restart cvat
63
64- name: Add share volume mount to worker services
65 lineinfile:
66 path: "{{ cvat_config_dir }}/docker-compose.yml"
67 insertafter: '^\s+ cvat_worker_.*:'
68 line: ' volumes:'
69 loop:
70 - cvat_worker_utils
71 - cvat_worker_import
72 - cvat_worker_export
73 - cvat_worker_annotation
74 - cvat_worker_webhooks
75 - cvat_worker_quality_reports
76 - cvat_worker_chunks
77 - cvat_worker_consensus
78 notify: restart cvat
79
80- name: Add share volume line to worker services
81 lineinfile:
82 path: "{{ cvat_config_dir }}/docker-compose.yml"
83 insertafter: '^\s+ volumes:'
84 line: ' - "{{ cvat_share_dir }}:/home/django/share:ro"'
85 loop:
86 - cvat_worker_utils
87 - cvat_worker_import
88 - cvat_worker_export
89 - cvat_worker_annotation
90 - cvat_worker_webhooks
91 - cvat_worker_quality_reports
92 - cvat_worker_chunks
93 - cvat_worker_consensus
94 notify: restart cvat
95
96
97
98 # - name: Validate Docker Compose files
99 # command: docker compose --project-directory "{{ cvat_config_dir }}" config
100 # register: compose_validate
101 # failed_when: compose_validate.rc != 0
102 # changed_when: false
103
104
105- name: Build compose file list
106 set_fact:
107 cvat_compose_files: >-
108 {{ [ 'docker-compose.yml' ]
109 + (cvat_https_enabled | ternary(['docker-compose.https.yml'], []))
110 + (cvat_serverless_enabled | ternary(['components/serverless/docker-compose.serverless.yml'], []))
111 + (cvat_external_db_enabled | ternary(['docker-compose.external_db.yml'], [])) }}
112
113- name: Show compose files being used
114 debug:
115 var: cvat_compose_files
116
117- name: Validate Docker Compose files (exact set)
118 command: >
119 docker compose
120 {% for f in cvat_compose_files %} -f {{ cvat_config_dir }}/{{ f }}{% endfor %}
121 config
122 args:
123 chdir: "{{ cvat_config_dir }}"
124 register: compose_validate
125 changed_when: false
126 failed_when: compose_validate.rc != 0
127
128- name: Parse merged compose YAML
129 set_fact:
130 merged_compose: "{{ compose_validate.stdout | from_yaml }}"
131
132- name: Show merged Traefik ports
133 debug:
134 var: merged_compose.services.traefik.ports
135
136
137- name: Pull CVAT images
138 community.docker.docker_compose_v2:
139 project_src: "{{ cvat_config_dir }}"
140 files: "{{ cvat_compose_files }}"
141 pull: always
142 state: present
143 register: cvat_pull_result
144
145- name: Start CVAT
146 community.docker.docker_compose_v2:
147 project_src: "{{ cvat_config_dir }}"
148 files: "{{ cvat_compose_files }}"
149 state: present
150 remove_orphans: true
151 register: cvat_start_result
152
153- name: Wait for CVAT health_check
154 command: docker exec -t cvat_server python manage.py health_check
155 register: cvat_hc
156 retries: 20
157 delay: 6
158 until: cvat_hc.rc == 0
159 changed_when: false
160 failed_when: cvat_hc.rc != 0
161
162- name: Bootstrap CVAT admin superuser
163 when: cvat_bootstrap_admin | default(true)
164 shell: |
165 docker exec -i cvat_server bash -lc "python3 - <<'PY'
166 import os
167 import django
168 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'cvat.settings.production')
169 django.setup()
170 from django.contrib.auth import get_user_model
171 User = get_user_model()
172 u='{{ cvat_admin_username | default("admin") }}'
173 e='{{ cvat_admin_email | default("[email protected]") }}'
174 p='{{ cvat_admin_password | default("ChangeMe!123") }}'
175 if not User.objects.filter(username=u).exists():
176 User.objects.create_superuser(u, e, p)
177 PY"
178 args:
179 executable: /bin/bash
180 changed_when: false
181
182- name: Display CVAT deployment summary
183 debug:
184 msg: |
185 CVAT Deployment:
186 - Status: {{ 'Updated' if (cvat_pull_result.changed or cvat_start_result.changed) else 'Already running' }}
187 - URL: {{ (cvat_https_enabled | default(false)) | ternary('https','http') }}://{{ cvat_domain }}{{ (cvat_https_enabled | default(false)) | ternary('', ':' ~ cvat_http_port | default(':8080')) }}
188 - Repo: {{ cvat_repo_url }} @ {{ cvat_repo_version }}
189 - Images: CVAT_VERSION={{ cvat_image_tag }}
190 - NAS Share (host): {{ cvat_share_dir }} â (in-container): /home/django/share
191 - Compose files: {{ cvat_compose_files | join(', ') }}
192 - Admin User: {{ cvat_admin_username | default('admin') }}
193
194