Skip to content

Pull Request: How to open the CVAT 8080 port for External Network use: docker-compose.yml #9243

@AntDX316

Description

@AntDX316

Change: docker-compose.yml to be able to access CVAT container address from outside the PC.
Great for using with the Samsung Tablet S Pen Stylus, as it makes labeling quicker and more efficient.

With this, you can then access the 8080 from out of the network as you would like with: npm run dev -- --host 0.0.0.0
(port forwarding, zerotier, etc.)

docker-compose.yml modification:

Lines 254 and 255, I think those are the only 2 changes:

traefik.http.routers.cvat-ui.rule: PathPrefix(`/`)
traefik.http.routers.cvat-ui.priority: 1
# 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: 80
  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.7.0
    restart: always
    command: [
      "--dir", "/var/lib/kvrocks/data"
    ]
    # 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:
    # <https://stackoverflow.com/a/77109064>. 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/data
    networks:
      - cvat

  cvat_server:
    container_name: cvat_server
    image: cvat/server:${CVAT_VERSION:-dev}
    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: PathPrefix(`/api/`) || PathPrefix(`/static/`) || PathPrefix(`/admin`) || PathPrefix(`/django-rq`)
      traefik.http.routers.cvat.priority: 10
      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_utils:
    container_name: cvat_utils
    image: cvat/server:${CVAT_VERSION:-dev}
    restart: always
    depends_on: *backend-deps
    environment:
      <<: *backend-env
      CVAT_REDIS_INMEM_PASSWORD: ''
      NUMPROCS: 1
    command: run utils
    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:-dev}
    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:-dev}
    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:-dev}
    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:-dev}
    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:-dev}
    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:-dev}
    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:-dev}
    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:-dev}
    restart: always
    depends_on:
      - cvat_server
    labels:
      traefik.enable: "true"
      traefik.http.services.cvat-ui.loadbalancer.server.port: "80"
      traefik.http.routers.cvat-ui.rule: PathPrefix(`/`)
      traefik.http.routers.cvat-ui.priority: 1
      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
    restart: always
    depends_on:
      - cvat_clickhouse
    environment:
      <<: *clickhouse-env
    networks:
      cvat:
        aliases:
          - vector
    volumes:
      - ./components/analytics/vector/vector.toml:/etc/vector/vector.toml:ro

  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_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: grafana-clickhouse-datasource
      GF_SERVER_ROOT_URL: http://${CVAT_HOST:-localhost}/analytics
      GF_INSTALL_PLUGINS: https://github.com/grafana/clickhouse-datasource/releases/download/v4.0.8/grafana-clickhouse-datasource-4.0.8.linux_amd64.zip;grafana-clickhouse-datasource
      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:

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions