From 19f5056befe9c186df2af82da587d64b77f68c4e Mon Sep 17 00:00:00 2001 From: Godopu Date: Tue, 25 Aug 2026 10:49:21 +0900 Subject: [PATCH] feat(docker): implement full frontend Next.js containerization and multi-service docker-compose - Create multi-stage standalone Dockerfile for Next.js frontend (node:20-alpine, non-root nextjs:nodejs user) - Configure output: 'standalone' in refer_landing_page/next.config.js - Add refer_landing_page/.dockerignore for build context optimization - Wire anl-backend and anl-frontend services in root docker-compose.yml with healthchecks, network dependencies, and persistent volume storage --- docker-compose.yml | 26 ++++++++++++++- refer_landing_page/.dockerignore | 14 ++++++++ refer_landing_page/Dockerfile | 54 +++++++++++++++++++++++++++++++ refer_landing_page/next.config.js | 1 + 4 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 refer_landing_page/.dockerignore create mode 100644 refer_landing_page/Dockerfile diff --git a/docker-compose.yml b/docker-compose.yml index 6f80940..57cb04f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -14,13 +14,37 @@ services: - GIN_MODE=release - CORS_ALLOW_ORIGINS=* - AUTO_MIGRATE=true + - ADMIN_TOKEN=${ADMIN_TOKEN:-anl-admin-secret-token-2026} volumes: - anl-db-data:/app/data healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/api/v1/health"] - interval: 30s + interval: 10s timeout: 3s retries: 3 + start_period: 5s + + anl-frontend: + build: + context: ./refer_landing_page + dockerfile: Dockerfile + container_name: anl-frontend-web + restart: unless-stopped + ports: + - "3000:3000" + environment: + - NODE_ENV=production + - PORT=3000 + - NEXT_PUBLIC_API_URL=http://localhost:8080/api/v1 + depends_on: + anl-backend: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000"] + interval: 15s + timeout: 3s + retries: 3 + start_period: 10s volumes: anl-db-data: diff --git a/refer_landing_page/.dockerignore b/refer_landing_page/.dockerignore new file mode 100644 index 0000000..3adde5c --- /dev/null +++ b/refer_landing_page/.dockerignore @@ -0,0 +1,14 @@ +Dockerfile +.dockerignore +node_modules +npm-debug.log +README.md +.next +.git +.gitignore +.env*.local +tests +scripts +.mam +.agents +.venv diff --git a/refer_landing_page/Dockerfile b/refer_landing_page/Dockerfile new file mode 100644 index 0000000..2ae8427 --- /dev/null +++ b/refer_landing_page/Dockerfile @@ -0,0 +1,54 @@ +# ============================================================================== +# Stage 1: Install dependencies +# ============================================================================== +FROM node:20-alpine AS deps +WORKDIR /app + +# Install libc6-compat for compatibility +RUN apk add --no-cache libc6-compat + +COPY package.json package-lock.json ./ +RUN npm ci + +# ============================================================================== +# Stage 2: Build the Next.js application +# ============================================================================== +FROM node:20-alpine AS builder +WORKDIR /app + +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# Set build-time environment variables +ENV NEXT_TELEMETRY_DISABLED=1 +ENV NODE_ENV=production + +RUN npm run build + +# ============================================================================== +# Stage 3: Production runner +# ============================================================================== +FROM node:20-alpine AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +RUN addgroup --system --gid 1001 nodejs && \ + adduser --system --uid 1001 nextjs + +# Copy static assets and standalone build output +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static + +USER nextjs + +EXPOSE 3000 + +HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://localhost:3000 || exit 1 + +CMD ["node", "server.js"] diff --git a/refer_landing_page/next.config.js b/refer_landing_page/next.config.js index 1efc74c..219ce47 100644 --- a/refer_landing_page/next.config.js +++ b/refer_landing_page/next.config.js @@ -1,6 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, + output: "standalone", async redirects() { return [ {