services: traefik: image: traefik:v3.6 command: - "--api.dashboard=true" - "--api.insecure=false" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.letsencrypt.acme.email=contact@mota-thomas.com" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" environment: DOCKER_HOST: unix:///var/run/docker.sock DOCKER_API_VERSION: "1.54" ports: - "80:80" - "443:443" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - traefik_letsencrypt:/letsencrypt labels: - "traefik.enable=true" - "traefik.http.routers.traefik.rule=Host(`traefik.mota-thomas.com`)" - "traefik.http.routers.traefik.entrypoints=websecure" - "traefik.http.routers.traefik.tls.certresolver=letsencrypt" - "traefik.http.routers.traefik.service=api@internal" - "traefik.http.routers.traefik.middlewares=traefik-errors-403,traefik-errors-401,traefik-auth" - "traefik.http.routers.traefik.priority=1" - "traefik.http.middlewares.traefik-auth.forwardauth.address=http://oauth2-proxy:4180/oauth2/auth" - "traefik.http.middlewares.traefik-auth.forwardauth.trustForwardHeader=true" - "traefik.http.middlewares.traefik-auth.forwardauth.authResponseHeaders=X-Auth-Request-User,X-Auth-Request-Email" - "traefik.http.middlewares.traefik-errors-401.errors.status=401" - "traefik.http.middlewares.traefik-errors-401.errors.service=oauth2-proxy@docker" - "traefik.http.middlewares.traefik-errors-401.errors.query=/oauth2/sign_in?rd=https://traefik.mota-thomas.com/dashboard/" - "traefik.http.middlewares.traefik-errors-403.errors.status=403" - "traefik.http.middlewares.traefik-errors-403.errors.service=oauth2-proxy@docker" - "traefik.http.middlewares.traefik-errors-403.errors.query=/oauth2/sign_out?rd=/oauth2/sign_in" oauth2-proxy: image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0 restart: unless-stopped environment: OAUTH2_PROXY_PROVIDER: oidc OAUTH2_PROXY_OIDC_ISSUER_URL: https://keycloak.mota-thomas.com/auth/realms/dev-platform OAUTH2_PROXY_CLIENT_ID: ${OAUTH2_PROXY_CLIENT_ID} OAUTH2_PROXY_CLIENT_SECRET: ${OAUTH2_PROXY_CLIENT_SECRET} OAUTH2_PROXY_COOKIE_SECRET: ${OAUTH2_PROXY_COOKIE_SECRET} OAUTH2_PROXY_EMAIL_DOMAINS: "*" OAUTH2_PROXY_REDIRECT_URL: https://traefik.mota-thomas.com/oauth2/callback OAUTH2_PROXY_UPSTREAMS: static://200 OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:4180 OAUTH2_PROXY_REVERSE_PROXY: "true" OAUTH2_PROXY_SCOPE: "openid email profile" OAUTH2_PROXY_OIDC_GROUPS_CLAIM: groups OAUTH2_PROXY_ALLOWED_GROUPS: admins OAUTH2_PROXY_PROMPT: "login" labels: - "traefik.enable=true" - "traefik.http.routers.oauth2.rule=Host(`traefik.mota-thomas.com`) && PathPrefix(`/oauth2/`)" - "traefik.http.routers.oauth2.entrypoints=websecure" - "traefik.http.routers.oauth2.tls.certresolver=letsencrypt" - "traefik.http.routers.oauth2.priority=100" - "traefik.http.services.oauth2.loadbalancer.server.port=4180" gitea-db: image: postgres:15 environment: POSTGRES_USER: gitea POSTGRES_PASSWORD: ${GITEA_DB_PASSWORD} POSTGRES_DB: gitea volumes: - gitea_db_data:/var/lib/postgresql/data gitea: image: gitea/gitea:latest depends_on: - gitea-db environment: GITEA__database__DB_TYPE: postgres GITEA__database__HOST: gitea-db:5432 GITEA__database__NAME: gitea GITEA__database__USER: gitea GITEA__database__PASSWD: ${GITEA_DB_PASSWORD} GITEA__server__ROOT_URL: https://gitea.mota-thomas.com/ GITEA__actions__ENABLED: "true" volumes: - gitea_data:/data labels: - "traefik.enable=true" - "traefik.http.routers.gitea.rule=Host(`gitea.mota-thomas.com`)" - "traefik.http.routers.gitea.entrypoints=websecure" - "traefik.http.routers.gitea.tls.certresolver=letsencrypt" - "traefik.http.services.gitea.loadbalancer.server.port=3000" gitea-runner: image: gitea/act_runner:latest restart: unless-stopped depends_on: - gitea environment: CONFIG_FILE: /config.yaml GITEA_INSTANCE_URL: https://gitea.mota-thomas.com GITEA_RUNNER_REGISTRATION_TOKEN: ${GITEA_RUNNER_REGISTRATION_TOKEN} GITEA_RUNNER_NAME: dev-platform-runner GITEA_RUNNER_LABELS: ubuntu-latest:docker://node:20-bookworm volumes: - ./gitea-runner/config.yaml:/config.yaml - gitea_runner_data:/data - /var/run/docker.sock:/var/run/docker.sock keycloak-db: image: postgres:15 environment: POSTGRES_DB: keycloak POSTGRES_USER: keycloak POSTGRES_PASSWORD: ${KEYCLOAK_DB_PASSWORD} volumes: - keycloak_db_data:/var/lib/postgresql/data keycloak: image: quay.io/keycloak/keycloak:24.0 command: start-dev environment: KC_DB: postgres KC_DB_URL_HOST: keycloak-db KC_DB_URL_DATABASE: keycloak KC_DB_USERNAME: keycloak KC_DB_PASSWORD: ${KEYCLOAK_DB_PASSWORD} KEYCLOAK_ADMIN: admin KEYCLOAK_ADMIN_PASSWORD: admin KC_HTTP_RELATIVE_PATH: /auth KC_PROXY_HEADERS: xforwarded KC_HOSTNAME_STRICT: false KC_HTTP_ENABLED: true depends_on: - keycloak-db labels: - "traefik.enable=true" - "traefik.http.routers.keycloak.rule=Host(`keycloak.mota-thomas.com`)" - "traefik.http.routers.keycloak.entrypoints=websecure" - "traefik.http.routers.keycloak.tls.certresolver=letsencrypt" - "traefik.http.services.keycloak.loadbalancer.server.port=8080" sonarqube-db: image: postgres:15 container_name: sonarqube-db environment: POSTGRES_USER: sonar POSTGRES_PASSWORD: ${SONAR_DB_PASSWORD} POSTGRES_DB: sonarqube volumes: - sonarqube_db_data:/var/lib/postgresql/data sonarqube: image: sonarqube:community container_name: sonarqube depends_on: - sonarqube-db environment: SONAR_JDBC_URL: jdbc:postgresql://sonarqube-db:5432/sonarqube SONAR_JDBC_USERNAME: sonar SONAR_JDBC_PASSWORD: ${SONAR_DB_PASSWORD} volumes: - sonarqube_data:/opt/sonarqube/data - sonarqube_logs:/opt/sonarqube/logs - ./sonarqube/extensions:/opt/sonarqube/extensions labels: - "traefik.enable=true" - "traefik.http.routers.sonarqube.rule=Host(`sonarqube.mota-thomas.com`)" - "traefik.http.routers.sonarqube.entrypoints=websecure" - "traefik.http.routers.sonarqube.tls.certresolver=letsencrypt" - "traefik.http.services.sonarqube.loadbalancer.server.port=9000" code-server: image: lscr.io/linuxserver/code-server:latest container_name: code-server environment: PUID: 1000 PGID: 1000 TZ: Europe/Zurich DEFAULT_WORKSPACE: /config/workspace volumes: - code_server_config:/config - ./workspace:/config/workspace networks: - default restart: unless-stopped oauth2-proxy-code: image: quay.io/oauth2-proxy/oauth2-proxy:v7.8.1 container_name: oauth2-proxy-code depends_on: - code-server environment: OAUTH2_PROXY_PROVIDER: keycloak-oidc OAUTH2_PROXY_CLIENT_ID: ${CODE_SERVER_OAUTH2_CLIENT_ID} OAUTH2_PROXY_CLIENT_SECRET: ${CODE_SERVER_OAUTH2_CLIENT_SECRET} OAUTH2_PROXY_COOKIE_SECRET: ${CODE_SERVER_OAUTH2_COOKIE_SECRET} OAUTH2_PROXY_COOKIE_SECURE: "true" OAUTH2_PROXY_EMAIL_DOMAINS: "*" OAUTH2_PROXY_REDIRECT_URL: https://code.mota-thomas.com/oauth2/callback OAUTH2_PROXY_OIDC_ISSUER_URL: https://keycloak.mota-thomas.com/auth/realms/dev-platform OAUTH2_PROXY_UPSTREAMS: http://code-server:8443 OAUTH2_PROXY_HTTP_ADDRESS: 0.0.0.0:4180 OAUTH2_PROXY_REVERSE_PROXY: "true" OAUTH2_PROXY_PASS_ACCESS_TOKEN: "true" OAUTH2_PROXY_PASS_USER_HEADERS: "true" OAUTH2_PROXY_SET_XAUTHREQUEST: "true" OAUTH2_PROXY_WHITELIST_DOMAINS: .mota-thomas.com OAUTH2_PROXY_COOKIE_DOMAINS: .mota-thomas.com OAUTH2_PROXY_COOKIE_NAME: "_oauth2_proxy_code" OAUTH2_PROXY_CODE_CHALLENGE_METHOD: S256 labels: traefik.enable: "true" traefik.http.routers.code-server.rule: Host(`code.mota-thomas.com`) traefik.http.routers.code-server.entrypoints: websecure traefik.http.routers.code-server.tls.certresolver: letsencrypt traefik.http.services.code-server.loadbalancer.server.port: "4180" networks: - default restart: unless-stopped volumes: gitea_db_data: gitea_data: gitea_runner_data: keycloak_db_data: traefik_letsencrypt: sonarqube_db_data: sonarqube_data: sonarqube_logs: code_server_config: