build: add Dockerfile and .dockerignore for Next.js containerization

This commit is contained in:
2026-04-02 12:00:41 -06:00
parent 166ac4350f
commit 796c952890
6 changed files with 186 additions and 148 deletions
+134
View File
@@ -0,0 +1,134 @@
############################################################
# Production-ready .dockerignore for a Next.js app
# Keeps Docker builds fast, lean, and free of development files.
############################################################
# Dependencies (installed inside Docker, never copied)
node_modules/
.pnpm-store/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Next.js build outputs (always generated during `next build`)
.next/
out/
dist/
build/
.vercel/
# Tests and testing output (not needed in production images)
coverage/
.nyc_output/
__tests__/
__mocks__/
jest/
cypress/
cypress/screenshots/
cypress/videos/
playwright-report/
test-results/
.vitest/
vitest.config.*
jest.config.*
cypress.config.*
playwright.config.*
*.test.*
*.spec.*
# Local development and editor files
.git/
.gitignore
.gitattributes
.vscode/
.idea/
*.swp
*.swo
*~
*.log
# Environment variables (only commit template files)
.env
.env*.local
.env.development
.env.test
.env.production.local
# Docker configuration files (not needed inside build context)
Dockerfile*
.dockerignore
compose.yaml
compose.yml
docker-compose*.yaml
docker-compose*.yml
# Documentation
*.md
docs/
# CI/CD configuration files
.github/
.gitlab-ci.yml
.travis.yml
.circleci/
Jenkinsfile
# Cache directories and temporary data
.cache/
.parcel-cache/
.eslintcache
.stylelintcache
.swc/
.turbo/
.tmp/
.temp/
# TypeScript build metadata
*.tsbuildinfo
# Sensitive or unnecessary configuration files
*.pem
.editorconfig
.prettierrc*
prettier.config.*
.eslintrc*
eslint.config.*
.stylelintrc*
stylelint.config.*
.babelrc*
*.iml
*.ipr
*.iws
# OS-specific junk
.DS_Store
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
Desktop.ini
# AI/ML tool metadata and configs
.cursor/
.cursorrules
.copilot/
.copilotignore
.github/copilot/
.gemini/
.anthropic/
.kiro
.claude
AGENTS.md
.agents/
# AI-generated temp files
*.aider*
*.copilot*
*.chatgpt*
*.claude*
*.gemini*
*.openai*
*.anthropic*
-38
View File
@@ -1,38 +0,0 @@
name: CI deploy preview
on:
push:
branches: ["preview"]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
environment: preview
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- uses: kielabokkie/ssh-key-and-known-hosts-action@v1
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
ssh-host: ${{ secrets.DEPLOY_HOST }}
- name: Install pm2
run: bun install pm2 -g
shell: bash
- name: Deploy using pm2
run: pm2 deploy ecosystem.config.js preview
env:
# Deploy environment variables
APP_NAME: ${{ secrets.APP_NAME }}
PORT: ${{ secrets.PORT }}
SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
# Appwrite variables
NEXT_PUBLIC_APPWRITE_ENDPOINT: ${{ secrets.NEXT_PUBLIC_APPWRITE_ENDPOINT }}
NEXT_PUBLIC_APPWRITE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_APPWRITE_PROJECT_ID }}
APPWRITE_API_KEY: ${{ secrets.APPWRITE_API_KEY }}
# Website variables
SITE_NAME: ${{ secrets.SITE_NAME }}
NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }}
IMAGE_DOMAINS: ${{ secrets.IMAGE_DOMAINS }}
shell: bash
-38
View File
@@ -1,38 +0,0 @@
name: CI deploy production
on:
push:
branches: ["production"]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- uses: kielabokkie/ssh-key-and-known-hosts-action@v1
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
ssh-host: ${{ secrets.DEPLOY_HOST }}
- name: Install pm2
run: bun install pm2 -g
shell: bash
- name: Deploy using pm2
run: pm2 deploy ecosystem.config.js production
env:
# Deploy environment variables
APP_NAME: ${{ secrets.APP_NAME }}
PORT: ${{ secrets.PORT }}
SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
# Appwrite variables
NEXT_PUBLIC_APPWRITE_ENDPOINT: ${{ secrets.NEXT_PUBLIC_APPWRITE_ENDPOINT }}
NEXT_PUBLIC_APPWRITE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_APPWRITE_PROJECT_ID }}
APPWRITE_API_KEY: ${{ secrets.APPWRITE_API_KEY }}
# Website variables
SITE_NAME: ${{ secrets.SITE_NAME }}
NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }}
IMAGE_DOMAINS: ${{ secrets.IMAGE_DOMAINS }}
shell: bash
-36
View File
@@ -1,36 +0,0 @@
name: CI setup preview
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
environment: preview
steps:
- uses: actions/checkout@v3
- uses: oven-sh/setup-bun@v1
- uses: kielabokkie/ssh-key-and-known-hosts-action@v1
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
ssh-host: ${{ secrets.DEPLOY_HOST }}
- name: Install pm2
run: bun install pm2 -g
shell: bash
- name: Deploy using pm2
run: pm2 deploy ecosystem.config.js preview setup
env:
# Deploy environment variables
APP_NAME: ${{ secrets.APP_NAME }}
PORT: ${{ secrets.PORT }}
SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
# Appwrite variables
NEXT_PUBLIC_APPWRITE_ENDPOINT: ${{ secrets.NEXT_PUBLIC_APPWRITE_ENDPOINT }}
NEXT_PUBLIC_APPWRITE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_APPWRITE_PROJECT_ID }}
APPWRITE_API_KEY: ${{ secrets.APPWRITE_API_KEY }}
# Website variables
SITE_NAME: ${{ secrets.SITE_NAME }}
NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }}
IMAGE_DOMAINS: ${{ secrets.IMAGE_DOMAINS }}
shell: bash
-36
View File
@@ -1,36 +0,0 @@
name: CI setup production
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v3
- uses: oven-sh/setup-bun@v1
- uses: kielabokkie/ssh-key-and-known-hosts-action@v1
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
ssh-host: ${{ secrets.DEPLOY_HOST }}
- name: Install pm2
run: bun install pm2 -g
shell: bash
- name: Deploy using pm2
run: pm2 deploy ecosystem.config.js production setup
env:
# Deploy environment variables
APP_NAME: ${{ secrets.APP_NAME }}
PORT: ${{ secrets.PORT }}
SSH_USERNAME: ${{ secrets.SSH_USERNAME }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
# Appwrite variables
NEXT_PUBLIC_APPWRITE_ENDPOINT: ${{ secrets.NEXT_PUBLIC_APPWRITE_ENDPOINT }}
NEXT_PUBLIC_APPWRITE_PROJECT_ID: ${{ secrets.NEXT_PUBLIC_APPWRITE_PROJECT_ID }}
APPWRITE_API_KEY: ${{ secrets.APPWRITE_API_KEY }}
# Website variables
SITE_NAME: ${{ secrets.SITE_NAME }}
NEXT_PUBLIC_SITE_URL: ${{ secrets.NEXT_PUBLIC_SITE_URL }}
IMAGE_DOMAINS: ${{ secrets.IMAGE_DOMAINS }}
shell: bash
+52
View File
@@ -0,0 +1,52 @@
FROM oven/bun:1.3-alpine AS builder
WORKDIR /app
COPY . .
ARG NEXT_PUBLIC_APPWRITE_ENDPOINT=""
ARG NEXT_PUBLIC_APPWRITE_PROJECT_ID=""
ARG SITE_NAME="EntGamers"
ARG NEXT_PUBLIC_SITE_URL="https://entgamers.pro"
ARG IMAGE_DOMAINS="https://api.entgamers.pro"
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
ENV CI=1
ENV HUSKY=0
ENV DOCKER_BUILD="true"
RUN bun install --frozen-lockfile
RUN --mount=type=secret,id=APPWRITE_API_KEY,env=APPWRITE_API_KEY \
NEXT_PUBLIC_APPWRITE_ENDPOINT=${NEXT_PUBLIC_APPWRITE_ENDPOINT} \
NEXT_PUBLIC_APPWRITE_PROJECT_ID=${NEXT_PUBLIC_APPWRITE_PROJECT_ID} \
SITE_NAME=${SITE_NAME} \
NEXT_PUBLIC_SITE_URL=${NEXT_PUBLIC_SITE_URL} \
IMAGE_DOMAINS=${IMAGE_DOMAINS} \
bun run build
FROM oven/bun:1.3-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
ENV NEXT_TELEMETRY_DISABLED=1
COPY --from=builder --chown=bun:bun /app/public ./public
COPY --from=builder --chown=bun:bun /app/.next/standalone ./
COPY --from=builder --chown=bun:bun /app/.next/static ./.next/static
USER bun
EXPOSE 3000
CMD ["bun", "server.js"]