version: "3.9" networks: core: name: core driver: bridge volumes: pg_data: driver: local mysql_data: driver: local redis_data: driver: local gitea_data: driver: local harbor_data: driver: local prometheus_data: driver: local grafana_data: driver: local gitlab_data: driver: local gitlab_logs: driver: local gitlab_config: driver: local services: traefik: image: traefik:v3.1 container_name: traefik command: - --providers.docker=true - --providers.docker.exposedbydefault=false - --entrypoints.web.address=:80 - --entrypoints.websecure.address=:443 - --api.insecure=true ports: - "20080:80" - "20443:443" - "28080:8080" networks: [core] volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./acme:/acme restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.traefik.rule=Host(`traefik.local.lan`) - traefik.http.services.traefik.loadbalancer.server.port=8080 postgres: image: postgres:16 container_name: postgres environment: POSTGRES_USER: ${PG_USER:-postgres} POSTGRES_PASSWORD: ${PG_PASSWORD:-123456} POSTGRES_DB: ${PG_DB:-postgres} volumes: - pg_data:/var/lib/postgresql/data networks: [core] ports: - "25432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${PG_USER:-postgres}"] interval: 10s timeout: 3s retries: 10 start_period: 30s restart: unless-stopped mysql: image: mysql:8 container_name: mysql environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-123456} MYSQL_DATABASE: ${MYSQL_DB:-mysql} MYSQL_USER: ${MYSQL_USER:-mysql} MYSQL_PASSWORD: ${MYSQL_PASSWORD:-123456} volumes: - mysql_data:/var/lib/mysql networks: [core] ports: - "23306:3306" healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] interval: 10s timeout: 3s retries: 10 start_period: 30s restart: unless-stopped redis: image: redis:7 container_name: redis command: ["redis-server", "--appendonly", "yes", "--requirepass", "${REDIS_PASSWORD:-redis123}"] volumes: - redis_data:/data networks: [core] ports: - "26379:6379" healthcheck: test: ["CMD", "redis-cli", "--raw", "incr", "ping"] interval: 10s timeout: 3s retries: 10 restart: unless-stopped gitea: image: gitea/gitea:1.22 container_name: gitea environment: - USER_UID=1000 - USER_GID=1000 - GITEA__server__DOMAIN=${GITEA_DOMAIN:-gitea.local.lan} - GITEA__server__ROOT_URL=https://${GITEA_DOMAIN:-gitea.local.lan}/ - GITEA__server__HTTP_PORT=3000 - GITEA__database__DB_TYPE=postgres - GITEA__database__HOST=postgres:5432 - GITEA__database__NAME=${GITEA_DB_NAME:-gitea} - GITEA__database__USER=${PG_USER:-postgres} - GITEA__database__PASSWD=${PG_PASSWORD:-postgres} volumes: - gitea_data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ports: - "23000:3000" - "2022:22" networks: [core] depends_on: postgres: condition: service_healthy restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.gitea.rule=Host(`${GITEA_DOMAIN:-gitea.local.lan}`) - traefik.http.services.gitea.loadbalancer.server.port=3000 gitlab: image: gitlab/gitlab-ce:16.9.1-ce.0 container_name: gitlab environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://${GITLAB_DOMAIN:-gitlab.local.lan}:28082' gitlab_rails['gitlab_shell_ssh_port'] = 2023 postgresql['enable'] = false redis['enable'] = false gitlab_rails['db_adapter'] = 'postgresql' gitlab_rails['db_host'] = 'postgres' gitlab_rails['db_port'] = 5432 gitlab_rails['db_database'] = 'gitlabhq_production' gitlab_rails['db_username'] = 'postgres' gitlab_rails['db_password'] = '123456' gitlab_rails['redis_host'] = 'redis' gitlab_rails['redis_port'] = 6379 gitlab_rails['redis_password'] = '123456' prometheus_monitoring['enable'] = false grafana['enable'] = false gitaly['enable'] = true nginx['listen_port'] = 80 nginx['listen_https'] = false volumes: - gitlab_config:/etc/gitlab - gitlab_logs:/var/log/gitlab - gitlab_data:/var/opt/gitlab networks: [core] ports: - "28082:80" - "24443:443" - "2023:22" depends_on: postgres: condition: service_healthy redis: condition: service_healthy restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.gitlab.rule=Host(`${GITLAB_DOMAIN:-gitlab.local.lan}`) - traefik.http.services.gitlab.loadbalancer.server.port=80 harbor: image: registry:2.8 container_name: harbor environment: - REGISTRY_HTTP_SECRET=${HARBOR_REGISTRY_SECRET:-harbor-secret} - REGISTRY_HTTP_ADDR=0.0.0.0:5000 volumes: - harbor_data:/var/lib/registry networks: [core] ports: - "28081:5000" restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.harbor.rule=Host(`${HARBOR_DOMAIN:-harbor.local.lan}`) - traefik.http.services.harbor.loadbalancer.server.port=5000 prometheus: image: prom/prometheus:v2.45.0 container_name: prometheus command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--web.console.libraries=/etc/prometheus/console_libraries' - '--web.console.templates=/etc/prometheus/consoles' - '--storage.tsdb.retention.time=200h' - '--web.enable-lifecycle' volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml - prometheus_data:/prometheus networks: [core] ports: - "29090:9090" restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.prometheus.rule=Host(`prometheus.local.lan`) - traefik.http.services.prometheus.loadbalancer.server.port=9090 grafana: image: grafana/grafana:10.0.0 container_name: grafana environment: - GF_SECURITY_ADMIN_USER=${GRAFANA_USER:-admin} - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_PASSWORD:-123456} - GF_USERS_ALLOW_SIGN_UP=false volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning networks: [core] ports: - "23001:3000" restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.grafana.rule=Host(`${GRAFANA_DOMAIN:-grafana.local.lan}`) - traefik.http.services.grafana.loadbalancer.server.port=3000 cadvisor: image: gcr.io/cadvisor/cadvisor:v0.47.2 container_name: cadvisor privileged: true devices: - /dev/kmsg volumes: - /:/rootfs:ro - /var/run:/var/run:rw - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro - /dev/disk/:/dev/disk:ro ports: - "28089:8080" networks: [core] restart: unless-stopped labels: - traefik.enable=true - traefik.http.routers.cadvisor.rule=Host(`cadvisor.local.lan`) - traefik.http.services.cadvisor.loadbalancer.server.port=8080