# Copyright (C) 2018-2022 Intel Corporation # Copyright (C) CVAT.ai Corporation # # SPDX-License-Identifier: MIT name: cvat x-backend-env: &backend-env CVAT_POSTGRES_HOST: cvat_db CVAT_REDIS_INMEM_HOST: cvat_redis_inmem CVAT_REDIS_INMEM_PORT: 6379 CVAT_REDIS_ONDISK_HOST: cvat_redis_ondisk CVAT_REDIS_ONDISK_PORT: 6666 CVAT_LOG_IMPORT_ERRORS: 'true' CVAT_ALLOW_STATIC_CACHE: '${CVAT_ALLOW_STATIC_CACHE:-no}' DJANGO_LOG_SERVER_HOST: vector DJANGO_LOG_SERVER_PORT: 8282 no_proxy: clickhouse,grafana,vector,nuclio,opa,${no_proxy:-} SMOKESCREEN_OPTS: ${SMOKESCREEN_OPTS:-} x-backend-deps: &backend-deps cvat_redis_inmem: condition: service_started cvat_redis_ondisk: condition: service_started cvat_db: condition: service_started x-clickhouse-env: &clickhouse-env CLICKHOUSE_HOST: clickhouse CLICKHOUSE_PORT: 8123 CLICKHOUSE_DB: cvat CLICKHOUSE_USER: user CLICKHOUSE_PASSWORD: user services: cvat_db: container_name: cvat_db image: postgres:15-alpine restart: always environment: POSTGRES_USER: root POSTGRES_DB: cvat POSTGRES_HOST_AUTH_METHOD: trust volumes: - cvat_db:/var/lib/postgresql/data networks: - cvat cvat_redis_inmem: container_name: cvat_redis_inmem image: redis:7.2.3-alpine restart: always command: [ "redis-server", "--save", "60", "100", "--appendonly", "yes", ] volumes: - cvat_inmem_db:/data networks: - cvat cvat_redis_ondisk: container_name: cvat_redis_ondisk image: apache/kvrocks:2.12.1 restart: always # The kvrocks image a) has a healthcheck command, and b) has a root process # that doesn't reap children, so it's susceptible to the problem described here: # . Kvrocks also uses a tiny timeout for # its healthcheck command (1s), which makes the problem more likely to manifest. # Use a separate init process as a workaround. init: true volumes: - cvat_cache_db:/var/lib/kvrocks networks: - cvat command: [ "--compact-cron", "0 3 * * *", ] cvat_server: container_name: cvat_server image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: <<: *backend-deps cvat_opa: condition: service_started environment: <<: [*backend-env, *clickhouse-env] DJANGO_MODWSGI_EXTRA_ARGS: '' ALLOWED_HOSTS: '*' ADAPTIVE_AUTO_ANNOTATION: 'false' NUMPROCS: 2 CVAT_ANALYTICS: 1 CVAT_BASE_URL: ONE_RUNNING_JOB_IN_QUEUE_PER_USER: command: init run server labels: traefik.enable: "true" traefik.http.services.cvat.loadbalancer.server.port: "8080" traefik.http.routers.cvat.rule: Host(`${CVAT_HOST:-localhost}`) && (PathPrefix(`/api/`) || PathPrefix(`/static/`) || PathPrefix(`/admin`) || PathPrefix(`/django-rq`)) traefik.http.routers.cvat.entrypoints: web volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: cvat: aliases: - cvat-server cvat_worker_utils: container_name: cvat_worker_utils image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: *backend-env CVAT_REDIS_INMEM_PASSWORD: '' NUMPROCS: 1 command: run worker notifications cleaning volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_worker_import: container_name: cvat_worker_import image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: *backend-env NUMPROCS: 2 command: run worker import volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_worker_export: container_name: cvat_worker_export image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: [*backend-env, *clickhouse-env] NUMPROCS: 2 command: run worker export volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_worker_annotation: container_name: cvat_worker_annotation image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: *backend-env NUMPROCS: 1 command: run worker annotation volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_worker_webhooks: container_name: cvat_worker_webhooks image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: *backend-env NUMPROCS: 1 command: run worker webhooks volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_worker_quality_reports: container_name: cvat_worker_quality_reports image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: *backend-env NUMPROCS: 1 command: run worker quality_reports volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_worker_chunks: container_name: cvat_worker_chunks image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: *backend-env NUMPROCS: 2 command: run worker chunks volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_worker_consensus: container_name: cvat_worker_consensus image: cvat/server:${CVAT_VERSION:-v2.44.3} restart: always depends_on: *backend-deps environment: <<: *backend-env NUMPROCS: 1 command: run worker consensus volumes: - cvat_data:/home/django/data - cvat_keys:/home/django/keys - cvat_logs:/home/django/logs networks: - cvat cvat_ui: container_name: cvat_ui image: cvat/ui:${CVAT_VERSION:-v2.44.3} restart: always depends_on: - cvat_server labels: traefik.enable: "true" traefik.http.services.cvat-ui.loadbalancer.server.port: "8000" traefik.http.routers.cvat-ui.rule: Host(`${CVAT_HOST:-localhost}`) traefik.http.routers.cvat-ui.entrypoints: web networks: - cvat traefik: image: traefik:v3.3 container_name: traefik restart: always ports: - 8080:8080 - 8090:8090 environment: CVAT_HOST: ${CVAT_HOST:-localhost} DJANGO_LOG_VIEWER_HOST: grafana DJANGO_LOG_VIEWER_PORT: 3000 TRAEFIK_ACCESSLOG_FORMAT: json TRAEFIK_ACCESSLOG_FIELDS_DEFAULTMODE: drop TRAEFIK_ACCESSLOG_FIELDS_NAMES_ClientHost: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_DownstreamContentSize: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_DownstreamStatus: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_Duration: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_RequestHost: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_RequestMethod: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_RequestPath: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_RequestPort: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_RequestProtocol: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_RouterName: keep TRAEFIK_ACCESSLOG_FIELDS_NAMES_StartUTC: keep TRAEFIK_LOG_FORMAT: json TRAEFIK_ENTRYPOINTS_web_ADDRESS: :8080 TRAEFIK_PROVIDERS_DOCKER_EXPOSEDBYDEFAULT: "false" TRAEFIK_PROVIDERS_DOCKER_NETWORK: cvat TRAEFIK_PROVIDERS_FILE_DIRECTORY: /etc/traefik/rules # Uncomment to get Traefik dashboard # TRAEFIK_API_DASHBOARD: "true" # TRAEFIK_ENTRYPOINTS_dashboard_ADDRESS: :8090 # labels: # traefik.enable: "true" # traefik.http.routers.dashboard.entrypoints: dashboard # traefik.http.routers.dashboard.service: api@internal # traefik.http.routers.dashboard.rule: Host(`${CVAT_HOST:-localhost}`) volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./components/analytics/grafana_conf.yml:/etc/traefik/rules/grafana_conf.yml:ro networks: - cvat logging: driver: "json-file" options: max-size: 100m max-file: "10" cvat_opa: container_name: cvat_opa image: openpolicyagent/opa:0.63.0 restart: always networks: cvat: aliases: - opa command: - run - --server - --log-level=error - --set=services.cvat.url=http://cvat-server:8080 - --set=bundles.cvat.service=cvat - --set=bundles.cvat.resource=/api/auth/rules - --set=bundles.cvat.polling.min_delay_seconds=5 - --set=bundles.cvat.polling.max_delay_seconds=15 cvat_clickhouse: container_name: cvat_clickhouse image: clickhouse/clickhouse-server:23.11-alpine restart: always environment: <<: *clickhouse-env networks: cvat: aliases: - clickhouse volumes: - ./components/analytics/clickhouse/init.sh:/docker-entrypoint-initdb.d/init.sh:ro - cvat_events_db:/var/lib/clickhouse/ cvat_vector: container_name: cvat_vector image: timberio/vector:0.26.0-alpine user: "1000:1000" # Workaround for . restart: always depends_on: - cvat_clickhouse environment: <<: *clickhouse-env networks: cvat: aliases: - vector volumes: - type: bind source: ./components/analytics/vector/vector.toml target: /etc/vector/vector.toml read_only: true - type: tmpfs target: /vector-data-dir cvat_grafana: image: grafana/grafana-oss:10.1.2 restart: always container_name: cvat_grafana environment: <<: *clickhouse-env GF_PATHS_PROVISIONING: /etc/grafana/provisioning GF_AUTH_BASIC_ENABLED: false GF_AUTH_ANONYMOUS_ENABLED: true GF_AUTH_ANONYMOUS_ORG_ROLE: Admin GF_AUTH_DISABLE_LOGIN_FORM: true GF_SERVER_ROOT_URL: http://${CVAT_HOST:-localhost}/analytics GF_INSTALL_PLUGINS: 'grafana-clickhouse-datasource 4.8.2' GF_DASHBOARDS_DEFAULT_HOME_DASHBOARD_PATH: /var/lib/grafana/dashboards/all_events.json volumes: - ./components/analytics/grafana/dashboards/:/var/lib/grafana/dashboards/:ro entrypoint: - sh - -euc - | mkdir -p /etc/grafana/provisioning/datasources cat << 'EOF' > /etc/grafana/provisioning/datasources/ds.yaml apiVersion: 1 datasources: - name: 'ClickHouse' type: 'grafana-clickhouse-datasource' isDefault: true jsonData: defaultDatabase: $${CLICKHOUSE_DB} port: $${CLICKHOUSE_PORT} server: $${CLICKHOUSE_HOST} username: $${CLICKHOUSE_USER} tlsSkipVerify: false protocol: http secureJsonData: password: $${CLICKHOUSE_PASSWORD} editable: true EOF mkdir -p /etc/grafana/provisioning/dashboards cat << EOF > /etc/grafana/provisioning/dashboards/dashboard.yaml apiVersion: 1 providers: - name: cvat-logs type: file updateIntervalSeconds: 30 options: path: /var/lib/grafana/dashboards foldersFromFilesStructure: true EOF exec /run.sh networks: cvat: aliases: - grafana volumes: cvat_db: cvat_data: cvat_keys: cvat_logs: cvat_inmem_db: cvat_events_db: cvat_cache_db: networks: cvat: