docker-compose.yml 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. services:
  2. postgres:
  3. image: postgres:16-alpine
  4. container_name: vidreview-db
  5. environment:
  6. POSTGRES_USER: ${POSTGRES_USER:-vidreview}
  7. POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Required}
  8. POSTGRES_DB: ${POSTGRES_DB:-vidreview}
  9. ports:
  10. - '5432:5432'
  11. volumes:
  12. - postgres_data:/var/lib/postgresql/data
  13. healthcheck:
  14. test: ['CMD-SHELL', 'pg_isready -U vidreview']
  15. interval: 5s
  16. timeout: 5s
  17. retries: 5
  18. # ── Init: runs once on fresh deploy ─────────────────────────────────────
  19. # Creates admin account, locks registration, saves credentials to seed_output.
  20. # Skips silently if DB already has an admin (safe to re-run on updates).
  21. init:
  22. build:
  23. context: .
  24. dockerfile: Dockerfile.api
  25. container_name: vidreview-init
  26. entrypoint: ['bash', '/scripts/init-admin.sh']
  27. environment:
  28. DB_HOST: postgres
  29. DB_NAME: ${POSTGRES_DB:-vidreview}
  30. DB_USER: ${POSTGRES_USER:-vidreview}
  31. DB_PASS: ${POSTGRES_PASSWORD:?Required}
  32. API_CONTAINER: vidreview-api
  33. OUTPUT_DIR: /seed-output
  34. ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@vidreview.local}
  35. ADMIN_NAME: ${ADMIN_NAME:-Admin}
  36. volumes:
  37. - /var/run/docker.sock:/var/run/docker.sock:rw
  38. - /usr/bin/docker:/usr/bin/docker:rw
  39. - ./scripts:/scripts
  40. - seed_output:/seed-output
  41. depends_on:
  42. postgres:
  43. condition: service_healthy
  44. api:
  45. condition: service_healthy
  46. restart: 'no'
  47. # ── API ─────────────────────────────────────────────────────────────────
  48. api:
  49. build:
  50. context: .
  51. dockerfile: Dockerfile.api
  52. container_name: vidreview-api
  53. environment:
  54. DATABASE_URL: ${DATABASE_URL:?Required}
  55. JWT_SECRET: ${JWT_SECRET:?Required}
  56. JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
  57. API_PORT: 3001
  58. NODE_ENV: ${NODE_ENV:-production}
  59. UPLOAD_DIR: /app/uploads
  60. MAX_FILE_SIZE_MB: ${MAX_FILE_SIZE_MB:-500}
  61. ALLOWED_ORIGINS: ${ALLOWED_ORIGINS}
  62. FRONTEND_URL: ${FRONTEND_URL}
  63. RESEND_API_KEY: ${RESEND_API_KEY:-}
  64. ports:
  65. - '3001:3001'
  66. depends_on:
  67. postgres:
  68. condition: service_healthy
  69. volumes:
  70. - uploads:/app/uploads
  71. healthcheck:
  72. test: ['CMD-SHELL', 'wget -qO- http://localhost:3001/health || exit 1']
  73. interval: 10s
  74. timeout: 5s
  75. retries: 5
  76. # ── Transcode Worker ─────────────────────────────────────────────────────
  77. worker:
  78. build:
  79. context: .
  80. dockerfile: Dockerfile.api
  81. container_name: vidreview-worker
  82. command: node src/worker/index.js
  83. environment:
  84. DATABASE_URL: ${DATABASE_URL:?Required}
  85. NODE_ENV: ${NODE_ENV:-production}
  86. UPLOAD_DIR: /app/uploads
  87. POLL_INTERVAL_MS: ${POLL_INTERVAL_MS:-2000}
  88. depends_on:
  89. postgres:
  90. condition: service_healthy
  91. volumes:
  92. - uploads:/app/uploads
  93. restart: unless-stopped
  94. # ── Caddy Reverse Proxy ──────────────────────────────────────────────────
  95. caddy:
  96. image: caddy:2-alpine
  97. container_name: vidreview-caddy
  98. ports:
  99. - '80:80'
  100. - '443:443'
  101. volumes:
  102. - ./Caddyfile:/etc/caddy/Caddyfile:ro
  103. - caddy_data:/data
  104. - caddy_config:/config
  105. depends_on:
  106. - frontend
  107. - api
  108. # ── Frontend ────────────────────────────────────────────────────────────
  109. frontend:
  110. build:
  111. context: .
  112. dockerfile: Dockerfile.frontend
  113. container_name: vidreview-frontend
  114. environment:
  115. NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
  116. NODE_ENV: ${NODE_ENV:-production}
  117. expose:
  118. - '3000'
  119. depends_on:
  120. api:
  121. condition: service_healthy
  122. volumes:
  123. postgres_data:
  124. uploads:
  125. seed_output:
  126. caddy_data:
  127. caddy_config: