docker-compose.yml 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. DB_CONTAINER: vidreview-db
  34. OUTPUT_DIR: /seed-output
  35. ADMIN_EMAIL: ${ADMIN_EMAIL:-admin@vidreview.local}
  36. ADMIN_NAME: ${ADMIN_NAME:-Admin}
  37. volumes:
  38. - /var/run/docker.sock:/var/run/docker.sock:rw
  39. - /usr/bin/docker:/usr/bin/docker:rw
  40. - ./scripts:/scripts
  41. - seed_output:/seed-output
  42. depends_on:
  43. postgres:
  44. condition: service_healthy
  45. api:
  46. condition: service_healthy
  47. restart: 'no'
  48. # ── API ─────────────────────────────────────────────────────────────────
  49. api:
  50. image: vidreview-api:v0.2
  51. container_name: vidreview-api
  52. environment:
  53. DATABASE_URL: ${DATABASE_URL:?Required}
  54. JWT_SECRET: ${JWT_SECRET:?Required}
  55. JWT_EXPIRES_IN: ${JWT_EXPIRES_IN:-7d}
  56. API_PORT: 3001
  57. NODE_ENV: ${NODE_ENV:-production}
  58. UPLOAD_DIR: /app/uploads
  59. MAX_FILE_SIZE_MB: ${MAX_FILE_SIZE_MB:-10000}
  60. ALLOWED_ORIGINS: ${ALLOWED_ORIGINS}
  61. FRONTEND_URL: ${FRONTEND_URL}
  62. RESEND_API_KEY: ${RESEND_API_KEY:-}
  63. ports:
  64. - '3001:3001'
  65. depends_on:
  66. postgres:
  67. condition: service_healthy
  68. volumes:
  69. - uploads:/app/uploads
  70. healthcheck:
  71. test: ['CMD-SHELL', 'wget -qO- http://localhost:3001/health || exit 1']
  72. interval: 10s
  73. timeout: 5s
  74. retries: 5
  75. # ── Transcode Worker ─────────────────────────────────────────────────────
  76. worker:
  77. image: vidreview-worker:v0.2
  78. container_name: vidreview-worker
  79. command: node src/worker/index.js
  80. environment:
  81. DATABASE_URL: ${DATABASE_URL:?Required}
  82. NODE_ENV: ${NODE_ENV:-production}
  83. UPLOAD_DIR: /app/uploads
  84. POLL_INTERVAL_MS: ${POLL_INTERVAL_MS:-2000}
  85. WORKER_CONCURRENCY: ${WORKER_CONCURRENCY:-4}
  86. ENCODER: ${ENCODER:-libx264}
  87. STUCK_TIMEOUT_MS: ${STUCK_TIMEOUT_MS:-300000}
  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. - '${CADDY_HTTP_PORT:-8080}:8080'
  100. - '${CADDY_HTTPS_PORT:-8443}:8443'
  101. volumes:
  102. - ./Caddyfile:/etc/caddy/Caddyfile:ro
  103. - caddy_data:/data
  104. - caddy_config:/config
  105. - uploads:/app/uploads
  106. depends_on:
  107. - frontend
  108. - api
  109. # ── Frontend ────────────────────────────────────────────────────────────
  110. frontend:
  111. build:
  112. context: .
  113. dockerfile: Dockerfile.frontend
  114. args:
  115. NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
  116. container_name: vidreview-frontend
  117. environment:
  118. NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL}
  119. NODE_ENV: ${NODE_ENV:-production}
  120. expose:
  121. - '3000'
  122. depends_on:
  123. api:
  124. condition: service_healthy
  125. volumes:
  126. postgres_data:
  127. uploads:
  128. seed_output:
  129. caddy_data:
  130. caddy_config: