feat: add Docker deployment support

- Add multi-stage Dockerfile for Next.js standalone build
- Add docker-compose.yml with app and MySQL 8.0 services
- Add .dockerignore for optimized builds
- Update next.config.ts with standalone output
This commit is contained in:
2026-04-13 00:13:24 +08:00
parent 12f7114f7d
commit 875743369d
4 changed files with 157 additions and 1 deletions
+61
View File
@@ -0,0 +1,61 @@
# Dependencies
node_modules
.npm
# Next.js build output
.next
out
build
# Git
.git
.gitignore
# Environment files
.env
.env.local
.env.*.local
# IDE
.idea
.vscode
*.swp
*.swo
# OS
.DS_Store
Thumbs.db
# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Test
coverage
# Docker
docker-compose*.yml
Dockerfile*
.dockerignore
# Data files (keep structure but ignore content)
data/*
# env.docker (template, not actual env)
.env.docker
# Misc
README.md
AGENTS.md
*.md
# TypeScript
*.tsbuildinfo
next-env.d.ts
# Debug
npm
pnpm-lock.yaml
yarn.lock
+43
View File
@@ -0,0 +1,43 @@
# Dockerfile for Recipe Translation Tool
# Stage 1: Builder
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package.json pnpm-lock.yaml ./
# Install dependencies
RUN corepack enable && pnpm install --frozen-lockfile
# Copy source code
COPY . .
# Build the application
RUN pnpm build
# Stage 2: Runner
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
# Create non-root user
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# Copy built application
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
# Set ownership
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
+52
View File
@@ -0,0 +1,52 @@
services:
app:
build:
context: .
dockerfile: Dockerfile
container_name: recipe_tool_app
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
- DB_PORT=3306
- DB_USER=${DB_USER:-root}
- DB_PASSWORD=${DB_PASSWORD:-123456}
- DB_NAME=${DB_NAME:-recipe_tools}
- AI_API_KEY=${AI_API_KEY}
- AI_BASE_URL=${AI_BASE_URL:-https://api.openai.com/v1}
- AI_MODEL=${AI_MODEL:-gpt-3.5-turbo}
depends_on:
db:
condition: service_healthy
networks:
- recipe_network
db:
image: mysql:8.0
container_name: recipe_tool_db
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${DB_PASSWORD:-123456}
- MYSQL_DATABASE=${DB_NAME:-recipe_tools}
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
# 初始化脚本(可选)
# - ./docker/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
networks:
- recipe_network
networks:
recipe_network:
driver: bridge
volumes:
mysql_data:
+1 -1
View File
@@ -1,7 +1,7 @@
import type { NextConfig } from "next"; import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ output: "standalone",
}; };
export default nextConfig; export default nextConfig;