version: '3.4' services: # mongodb: # image: bitnami/mongodb:latest # ports: # - "27017" # volumes: # - data:/bitnami/mongodb # redis: # image: redis:6.2-alpine # hostname: redis # container_name: redis # command: # - 'redis-server' # - '--requirepass myStrongPassword' # ports: # - 36379:6379 # restart: always # deploy: # placement: # constraints: # - "node.labels.type==queue" # restart_policy: # condition: on-failure # delay: 5s # max_attempts: 3 # window: 120s # update_config: # parallelism: 2 # delay: 10s # order: stop-first # rollback_config: # parallelism: 2 # delay: 10s # order: stop-first nginx: image: nginx:1.17 volumes: - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf command: '/bin/sh -c ''while :; do sleep 336h & wait $${!}; nginx -s reload; done & nginx -g "daemon off;"''' ports: - 80:80 - 443:443 depends_on: - backend - frontend deploy: placement: constraints: - node.role == manager restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s update_config: parallelism: 2 delay: 10s order: stop-first rollback_config: parallelism: 2 delay: 10s order: stop-first resources: limits: cpus: '0.20' memory: 100M reservations: cpus: '0.05' memory: 20M ports: - 80:80 - 443:443 # certbot: # container_name: certbot # entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 118h & wait $${!}; done;'" # image: certbot/certbot # volumes: # - ./docker/nginx/certbot/conf:/etc/letsencrypt # - ./docker/nginx/certbot/www:/var/www/certbot # rabbitmq: # image: rabbitmq:3.8.4-management # container_name: rabbitmq # env_file: # - .prod.env # volumes: # - ./docker/rabbitmq/etc/:/etc/rabbitmq/ # - ./docker/rabbitmq/data/:/var/lib/rabbitmq/ # - ./docker/rabbitmq/logs/:/var/log/rabbitmq/ # ports: # - 5672 # - 15672 # deploy: # placement: # constraints: # - "node.labels.type==queue" # restart_policy: # condition: on-failure # delay: 5s # max_attempts: 3 # window: 120s # update_config: # parallelism: 2 # delay: 10s # order: stop-first # rollback_config: # parallelism: 2 # delay: 10s # order: stop-first db: container_name: db image: postgres:12 restart: always volumes: - app-db-data:/var/lib/postgresql/data/pgdata env_file: - .env networks: - traefik-public environment: - PGDATA=/var/lib/postgresql/data/pgdata - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set} - POSTGRES_USER=${POSTGRES_USER?Variable not set} - POSTGRES_DB=${POSTGRES_DB?Variable not set} adminer: container_name: db-adminer image: adminer restart: always networks: - traefik-public depends_on: - db environment: - ADMINER_DESIGN=pepa-linha-dark labels: - traefik.enable=true - traefik.docker.network=traefik-public - traefik.constraint-label=traefik-public - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.rule=Host(`adminer.${DOMAIN?Variable not set}`) - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.entrypoints=http - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-http.middlewares=https-redirect - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.rule=Host(`adminer.${DOMAIN?Variable not set}`) - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.entrypoints=https - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.tls=true - traefik.http.routers.${STACK_NAME?Variable not set}-adminer-https.tls.certresolver=le - traefik.http.services.${STACK_NAME?Variable not set}-adminer.loadbalancer.server.port=8080 ports: - 8081:8080 backend: container_name: backend image: 'jianboy/${DOCKER_IMAGE_BACKEND?Variable not set}:${TAG-latest}' # build: # context: ./backend # dockerfile: ./Dockerfile restart: always networks: - traefik-public depends_on: - db ports: - 8080:8080 - 8000:8000 env_file: - .env environment: - DOMAIN=${DOMAIN} - ENVIRONMENT=${ENVIRONMENT} - BACKEND_CORS_ORIGINS=${BACKEND_CORS_ORIGINS} - SECRET_KEY=${SECRET_KEY?Variable not set} - FIRST_SUPERUSER=${FIRST_SUPERUSER?Variable not set} - FIRST_SUPERUSER_PASSWORD=${FIRST_SUPERUSER_PASSWORD?Variable not set} - USERS_OPEN_REGISTRATION=${USERS_OPEN_REGISTRATION} - SMTP_HOST=${SMTP_HOST} - SMTP_USER=${SMTP_USER} - SMTP_PASSWORD=${SMTP_PASSWORD} - EMAILS_FROM_EMAIL=${EMAILS_FROM_EMAIL} - POSTGRES_SERVER=db - POSTGRES_PORT=${POSTGRES_PORT} - POSTGRES_DB=${POSTGRES_DB} - POSTGRES_USER=${POSTGRES_USER?Variable not set} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD?Variable not set} - SENTRY_DSN=${SENTRY_DSN} deploy: mode: replicated replicas: 4 restart_policy: condition: on-failure delay: 5s max_attempts: 3 window: 120s update_config: parallelism: 2 delay: 10s order: stop-first rollback_config: parallelism: 2 delay: 10s order: stop-first resources: limits: cpus: '0.50' memory: 150M reservations: cpus: '0.20' memory: 40M # build: # context: ./backend # args: # INSTALL_DEV: ${INSTALL_DEV-false} # platform: linux/amd64 # Patch for M1 Mac # labels: # - traefik.enable=true # - traefik.docker.network=traefik-public # - traefik.constraint-label=traefik-public # - traefik.http.services.${STACK_NAME?Variable not set}-backend.loadbalancer.server.port=80 # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.rule=Host(`${DOMAIN?Variable not set}`, `www.${DOMAIN?Variable not set}`) && PathPrefix(`/api`, `/docs`, `/redoc`) # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.entrypoints=http # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.rule=Host(`${DOMAIN?Variable not set}`, `www.${DOMAIN?Variable not set}`) && PathPrefix(`/api`, `/docs`, `/redoc`) # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.entrypoints=https # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls=true # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.tls.certresolver=le # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-http.middlewares=https-redirect,${STACK_NAME?Variable not set}-www-redirect # - traefik.http.routers.${STACK_NAME?Variable not set}-backend-https.middlewares=${STACK_NAME?Variable not set}-www-redirect # frontend: # container_name: frontend # image: 'jianboy/${DOCKER_IMAGE_FRONTEND?Variable not set}:${TAG-latest}' # restart: always # networks: # - traefik-public # build: # context: ./frontend # args: # - VITE_API_URL=https://${DOMAIN?Variable not set} # - NODE_ENV=production # labels: # - traefik.enable=true # - traefik.docker.network=traefik-public # - traefik.constraint-label=traefik-public # - traefik.http.services.${STACK_NAME?Variable not set}-frontend.loadbalancer.server.port=80 # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.rule=Host(`${DOMAIN?Variable not set}`, `www.${DOMAIN?Variable not set}`) # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.entrypoints=http # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.rule=Host(`${DOMAIN?Variable not set}`, `www.${DOMAIN?Variable not set}`) # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.entrypoints=https # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls=true # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.tls.certresolver=le # # Handle domain with and without "www" to redirect to only one # # To disable www redirection remove the next line # - traefik.http.middlewares.${STACK_NAME?Variable not set}-www-redirect.redirectregex.regex=^http(s)?://www.(${DOMAIN?Variable not set})/(.*) # # Redirect a domain with www to non-www # # To disable it remove the next line # - traefik.http.middlewares.${STACK_NAME?Variable not set}-www-redirect.redirectregex.replacement=http$${1}://${DOMAIN?Variable not set}/$${3} # # Middleware to redirect www, to disable it remove the next line # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-https.middlewares=${STACK_NAME?Variable not set}-www-redirect # # Middleware to redirect www, and redirect HTTP to HTTPS # # to disable www redirection remove the section: ${STACK_NAME?Variable not set}-www-redirect, # - traefik.http.routers.${STACK_NAME?Variable not set}-frontend-http.middlewares=https-redirect,${STACK_NAME?Variable not set}-www-redirect volumes: app-db-data: networks: traefik-public: # external: true