From 84200ac1750a3328b3d871686b8b5d35df071202 Mon Sep 17 00:00:00 2001 From: ASOwnerYT Date: Fri, 20 Mar 2026 14:33:43 +1300 Subject: [PATCH] Docker support --- .github/workflows/docker-build.yml | 60 ++++++++++++++++++++++++++++++ Dockerfile | 46 +++++++++++++++++++++++ docker-compose.yml | 18 +++++++++ next-env.d.ts | 6 +++ tsconfig.json | 22 +++++++++-- 5 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/docker-build.yml create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 next-env.d.ts diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 0000000..654873d --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,60 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + - develop + tags: + - 'v*.*.*' + pull_request: + branches: + - main + - develop + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Container Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6875b36 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,46 @@ +# Build stage +FROM node:20-alpine AS builder + +WORKDIR /app + +# Install pnpm +RUN npm install -g pnpm + +# Copy package files +COPY pnpm-lock.yaml package.json ./ + +# Install dependencies +RUN pnpm install --frozen-lockfile + +# Copy source code +COPY . . + +# Build application +RUN pnpm run build + +# Production stage +FROM node:20-alpine + +WORKDIR /app + +# Install pnpm +RUN npm install -g pnpm + +# Set environment to production +ENV NODE_ENV=production + +# Copy package files from builder +COPY package.json pnpm-lock.yaml ./ + +# Install production dependencies only +RUN pnpm install --prod --frozen-lockfile + +# Copy built application from builder stage +COPY --from=builder /app/.next ./.next +COPY --from=builder /app/public ./public + +# Expose port +EXPOSE 3000 + +# Start application +CMD ["pnpm", "start"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..49b675a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,18 @@ +version: '3.8' + +services: + app: + build: + context: . + dockerfile: Dockerfile + ports: + - "3000:3000" + environment: + - NODE_ENV=production + restart: unless-stopped + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..c4b7818 --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +import "./.next/dev/types/routes.d.ts"; + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/tsconfig.json b/tsconfig.json index 2a062b3..48d6d82 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,10 @@ { "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "target": "ES6", "skipLibCheck": true, @@ -19,9 +23,19 @@ } ], "paths": { - "@/*": ["./*"] + "@/*": [ + "./*" + ] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] }