services: # =========================================== # Infrastructure # =========================================== postgres: image: postgres:16-alpine networks: - fictionarchive environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} volumes: - /srv/docker_volumes/fictionarchive/postgres:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 5s timeout: 5s retries: 5 restart: unless-stopped ports: - 4321:5432 rabbitmq: image: rabbitmq:3-management-alpine networks: - fictionarchive environment: RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER:-guest} RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD:-guest} volumes: - /srv/docker_volumes/fictionarchive/rabbitmq:/var/lib/rabbitmq healthcheck: test: ["CMD", "rabbitmq-diagnostics", "check_running"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped vpn: image: dperson/openvpn-client # or gluetun, wireguard, etc. networks: fictionarchive: aliases: - novel-service cap_add: - NET_ADMIN devices: - /dev/net/tun volumes: - /srv/docker_volumes/korean_vpn:/vpn restart: unless-stopped # =========================================== # Backend Services # =========================================== novel-service: image: git.orfl.xyz/conco/fictionarchive-novel-service:latest environment: ConnectionStrings__DefaultConnection: Host=postgres;Database=FictionArchive_NovelService;Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres} RabbitMQ__ConnectionString: amqp://${RABBITMQ_USER:-guest}:${RABBITMQ_PASSWORD:-guest}@rabbitmq Novelpia__Username: ${NOVELPIA_USERNAME} Novelpia__Password: ${NOVELPIA_PASSWORD} UpdateService__PendingImageUrl: https://files.fictionarchive.orfl.xyz/api/pendingupload.png depends_on: postgres: condition: service_healthy rabbitmq: condition: service_healthy vpn: condition: service_started network_mode: "service:vpn" restart: unless-stopped scheduler-service: image: git.orfl.xyz/conco/fictionarchive-scheduler-service:latest networks: - fictionarchive environment: ConnectionStrings__DefaultConnection: Host=postgres;Database=FictionArchive_SchedulerService;Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres} RabbitMQ__ConnectionString: amqp://${RABBITMQ_USER:-guest}:${RABBITMQ_PASSWORD:-guest}@rabbitmq depends_on: postgres: condition: service_healthy rabbitmq: condition: service_healthy restart: unless-stopped user-service: image: git.orfl.xyz/conco/fictionarchive-user-service:latest networks: - fictionarchive environment: ConnectionStrings__DefaultConnection: Host=postgres;Database=FictionArchive_UserService;Username=${POSTGRES_USER:-postgres};Password=${POSTGRES_PASSWORD:-postgres} RabbitMQ__ConnectionString: amqp://${RABBITMQ_USER:-guest}:${RABBITMQ_PASSWORD:-guest}@rabbitmq Authentik__BaseUrl: https://auth.orfl.xyz Authentik__ApiToken: ${AUTHENTIK_API_TOKEN} Authentik__EmailStageId: 10df0c18-8802-4ec7-852e-3cdd355514d3 depends_on: postgres: condition: service_healthy rabbitmq: condition: service_healthy restart: unless-stopped file-service: image: git.orfl.xyz/conco/fictionarchive-file-service:latest networks: - web - fictionarchive environment: RabbitMQ__ConnectionString: amqp://${RABBITMQ_USER:-guest}:${RABBITMQ_PASSWORD:-guest}@rabbitmq S3__AccessKey: ${S3_ACCESS_KEY} S3__SecretKey: ${S3_SECRET_KEY} ProxyConfiguration__BaseUrl: https://files.fictionarchive.orfl.xyz/api labels: - "traefik.enable=true" - "traefik.http.routers.file-service.rule=Host(`files.fictionarchive.orfl.xyz`)" - "traefik.http.routers.file-service.tls=true" - "traefik.http.routers.file-service.tls.certresolver=lets-encrypt" - "traefik.http.services.file-service.loadbalancer.server.port=8080" depends_on: rabbitmq: condition: service_healthy restart: unless-stopped # =========================================== # API Gateway # =========================================== api-gateway: image: git.orfl.xyz/conco/fictionarchive-api:latest networks: - web - fictionarchive environment: Cors__AllowedOrigin: https://fictionarchive.orfl.xyz labels: - "traefik.enable=true" - "traefik.http.routers.api-gateway.rule=Host(`api.fictionarchive.orfl.xyz`)" - "traefik.http.routers.api-gateway.tls=true" - "traefik.http.routers.api-gateway.tls.certresolver=lets-encrypt" - "traefik.http.services.api-gateway.loadbalancer.server.port=8080" depends_on: - novel-service - scheduler-service - file-service - user-service restart: unless-stopped # =========================================== # Frontend # =========================================== frontend: image: git.orfl.xyz/conco/fictionarchive-frontend:latest networks: - web labels: - traefik.http.routers.fafrontend.rule=Host(`fictionarchive.orfl.xyz`) - traefik.http.routers.fafrontend.tls=true - traefik.http.routers.fafrontend.tls.certresolver=lets-encrypt - traefik.http.services.fafrontend.loadbalancer.server.port=80 - traefik.enable=true restart: unless-stopped networks: web: external: yes fictionarchive: