--- # Atlas OS — Core Services Compose Stack # Deploy: docker compose -f atlas-core.yml --env-file /opt/atlas/secrets/atlas.env up -d # # Services: Authentik (SSO), Nextcloud (files), Stalwart (mail), # Forgejo (git), Vaultwarden (passwords) # # All services on internal network only — Caddy is the sole public entry point. version: "3.8" networks: atlas-net: external: false driver: bridge volumes: ak-db-data: ak-redis-data: ak-media: ak-certs: ak-custom-templates: nc-data: nc-db-data: nc-redis-data: stalwart-data: forgejo-data: forgejo-db-data: vault-data: services: # ─── Authentik SSO ──────────────────────────────────────────────────────── authentik-db: image: docker.io/library/postgres:16-alpine container_name: atlas-ak-db restart: unless-stopped environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_USER: authentik POSTGRES_DB: authentik volumes: - ak-db-data:/var/lib/postgresql/data networks: [atlas-net] healthcheck: test: ["CMD-SHELL", "pg_isready -U authentik"] interval: 10s timeout: 5s retries: 5 authentik-redis: image: docker.io/library/redis:alpine container_name: atlas-ak-redis restart: unless-stopped command: --save 60 1 --loglevel warning volumes: - ak-redis-data:/data networks: [atlas-net] authentik-server: image: ghcr.io/goauthentik/server:latest container_name: atlas-authentik-server restart: unless-stopped command: server environment: AUTHENTIK_REDIS__HOST: authentik-redis AUTHENTIK_POSTGRESQL__HOST: authentik-db AUTHENTIK_POSTGRESQL__USER: authentik AUTHENTIK_POSTGRESQL__NAME: authentik AUTHENTIK_POSTGRESQL__PASSWORD: ${POSTGRES_PASSWORD} AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_ERROR_REPORTING__ENABLED: "false" AUTHENTIK_EMAIL__FROM: admin@${DOMAIN} volumes: - ak-media:/media - ak-custom-templates:/templates - ak-certs:/certs ports: - "127.0.0.1:9000:9000" - "127.0.0.1:9443:9443" networks: [atlas-net] depends_on: [authentik-db, authentik-redis] authentik-worker: image: ghcr.io/goauthentik/server:latest container_name: atlas-authentik-worker restart: unless-stopped command: worker environment: AUTHENTIK_REDIS__HOST: authentik-redis AUTHENTIK_POSTGRESQL__HOST: authentik-db AUTHENTIK_POSTGRESQL__USER: authentik AUTHENTIK_POSTGRESQL__NAME: authentik AUTHENTIK_POSTGRESQL__PASSWORD: ${POSTGRES_PASSWORD} AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY} AUTHENTIK_EMAIL__FROM: admin@${DOMAIN} volumes: - ak-media:/media - ak-certs:/certs - /var/run/docker.sock:/var/run/docker.sock networks: [atlas-net] depends_on: [authentik-db, authentik-redis] # ─── Nextcloud Files ────────────────────────────────────────────────────── nextcloud-db: image: docker.io/library/mariadb:11 container_name: atlas-nc-db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${POSTGRES_PASSWORD} MYSQL_DATABASE: nextcloud MYSQL_USER: nextcloud MYSQL_PASSWORD: ${POSTGRES_PASSWORD} volumes: - nc-db-data:/var/lib/mysql networks: [atlas-net] command: --transaction-isolation=READ-COMMITTED --log-bin=binlog --binlog-format=ROW nextcloud-redis: image: docker.io/library/redis:alpine container_name: atlas-nc-redis restart: unless-stopped networks: [atlas-net] nextcloud: image: nextcloud:31-apache container_name: atlas-nc-app restart: unless-stopped environment: MYSQL_HOST: nextcloud-db MYSQL_DATABASE: nextcloud MYSQL_USER: nextcloud MYSQL_PASSWORD: ${POSTGRES_PASSWORD} NEXTCLOUD_ADMIN_USER: admin NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD} NEXTCLOUD_TRUSTED_DOMAINS: cloud.${DOMAIN} REDIS_HOST: nextcloud-redis OVERWRITEPROTOCOL: https OVERWRITECLIURL: https://cloud.${DOMAIN} volumes: - nc-data:/var/www/html ports: - "127.0.0.1:8443:80" networks: [atlas-net] depends_on: [nextcloud-db, nextcloud-redis] # ─── Stalwart Mail ──────────────────────────────────────────────────────── stalwart: image: docker.io/stalwartlabs/mail-server:latest container_name: atlas-stalwart restart: unless-stopped ports: - "127.0.0.1:8080:8080" # web admin - "25:25" # SMTP - "465:465" # SMTPS - "587:587" # Submission - "993:993" # IMAPS - "4190:4190" # Sieve volumes: - stalwart-data:/opt/stalwart-mail networks: [atlas-net] # ─── Forgejo Git ────────────────────────────────────────────────────────── forgejo-db: image: docker.io/library/postgres:16-alpine container_name: atlas-forgejo-db restart: unless-stopped environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_USER: forgejo POSTGRES_DB: forgejo volumes: - forgejo-db-data:/var/lib/postgresql/data networks: [atlas-net] forgejo: image: codeberg.org/forgejo/forgejo:10 container_name: atlas-forgejo restart: unless-stopped environment: USER_UID: "1000" USER_GID: "1000" FORGEJO__database__DB_TYPE: postgres FORGEJO__database__HOST: forgejo-db:5432 FORGEJO__database__NAME: forgejo FORGEJO__database__USER: forgejo FORGEJO__database__PASSWD: ${POSTGRES_PASSWORD} FORGEJO__server__DOMAIN: git.${DOMAIN} FORGEJO__server__ROOT_URL: https://git.${DOMAIN} volumes: - forgejo-data:/data ports: - "127.0.0.1:3000:3000" - "22:22" networks: [atlas-net] depends_on: [forgejo-db] # ─── Vaultwarden Passwords ──────────────────────────────────────────────── vaultwarden: image: vaultwarden/server:latest container_name: atlas-vaultwarden restart: unless-stopped environment: DOMAIN: https://vault.${DOMAIN} ADMIN_TOKEN: ${VAULTWARDEN_ADMIN_TOKEN} SIGNUPS_ALLOWED: "false" INVITATIONS_ALLOWED: "true" WEBSOCKET_ENABLED: "true" volumes: - vault-data:/data ports: - "127.0.0.1:8222:80" networks: [atlas-net]