diff --git a/Dockerfile b/Dockerfile index 19ff66c..22e1b4d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -38,6 +38,8 @@ ENV NEXT_TELEMETRY_DISABLED 1 RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs +RUN apk add --no-cache wget + RUN mkdir .next RUN chown nextjs:nodejs .next diff --git a/app/api/health/route.ts b/app/api/health/route.ts new file mode 100644 index 0000000..4e09dd5 --- /dev/null +++ b/app/api/health/route.ts @@ -0,0 +1,5 @@ +import { NextResponse } from 'next/server'; + +export async function GET() { + return NextResponse.json({ status: 'ok' }, { status: 200 }); +} diff --git a/docker-compose.yml b/docker-compose.yml index bbf12f3..ce13f31 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,13 +1,48 @@ -version: '3.8' services: web: build: context: . dockerfile: Dockerfile - ports: - - "3000:3000" + args: + - NEXT_PUBLIC_FIREBASE_API_KEY=${NEXT_PUBLIC_FIREBASE_API_KEY:?NEXT_PUBLIC_FIREBASE_API_KEY is required} + - NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=${NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN:?NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN is required} + - NEXT_PUBLIC_FIREBASE_PROJECT_ID=${NEXT_PUBLIC_FIREBASE_PROJECT_ID:?NEXT_PUBLIC_FIREBASE_PROJECT_ID is required} + - NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=${NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET:?NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET is required} + - NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=${NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID:?NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID is required} + - NEXT_PUBLIC_FIREBASE_APP_ID=${NEXT_PUBLIC_FIREBASE_APP_ID:?NEXT_PUBLIC_FIREBASE_APP_ID is required} + expose: + # Expose port 3000 internally to Nginx, but block it from the host machine + - "3000" env_file: - .env environment: - NODE_ENV=production - restart: unless-stopped \ No newline at end of file + restart: unless-stopped + networks: + - systemcraft_net + healthcheck: + test: ["CMD-SHELL", "wget --spider --tries=1 http://127.0.0.1:3000/api/health || exit 1"] + interval: 10s + timeout: 5s + retries: 3 + start_period: 15s + + nginx: + # Use the tiny official Nginx image + image: nginx:alpine + ports: + # Open port 80 to your computer/the internet + - "80:80" + volumes: + # Mount the configuration file you just wrote directly into the Nginx container + - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + depends_on: + web: + condition: service_healthy + restart: unless-stopped + networks: + - systemcraft_net + +# Create an isolated internal network for them to talk securely +networks: + systemcraft_net: diff --git a/nginx/default.conf b/nginx/default.conf new file mode 100644 index 0000000..9299ca4 --- /dev/null +++ b/nginx/default.conf @@ -0,0 +1,25 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 80; + server_name localhost; + + # Enable runtime DNS re-resolution (use Docker's internal DNS resolver) + resolver 127.0.0.11 valid=30s; + set $upstream_endpoint http://web:3000; + + location / { + proxy_pass $upstream_endpoint; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_set_header Host $host; + proxy_cache_bypass $http_upgrade; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } +} \ No newline at end of file