Add Docker configuration for port 3500

- Add Dockerfile with multi-stage build for production
- Add docker-compose.yml for easy deployment
- Add .dockerignore to exclude unnecessary files
- Add DOCKER_SETUP.md with comprehensive setup guide
- Update next.config.js to enable standalone output mode
- Configure app to run on port 3500
- Keep MySQL server external to Docker
This commit is contained in:
2025-12-02 10:09:13 +00:00
parent b2a59eecf1
commit 0d26087049
5 changed files with 265 additions and 0 deletions

18
.dockerignore Normal file
View File

@@ -0,0 +1,18 @@
Dockerfile
.dockerignore
.git
.gitignore
.next
.kiro
.vscode
node_modules
npm-debug.log
README.md
*.md
.env
.env.local
.env.*.local
coverage
.DS_Store
*.pem
tsconfig.tsbuildinfo

153
DOCKER_SETUP.md Normal file
View File

@@ -0,0 +1,153 @@
# Docker Setup Guide
This guide explains how to run the Ultimate Lists App using Docker on port 3500.
## Prerequisites
- Docker and Docker Compose installed
- MySQL server running (external to Docker)
- Environment variables configured
## Configuration
### 1. Update next.config.js
The application needs to be configured for standalone output. Update your `next.config.js`:
```javascript
const nextConfig = {
output: 'standalone',
// ... rest of your config
}
```
### 2. Environment Variables
Create a `.env` file in the project root with your MySQL connection details:
```env
# MySQL Connection (external server)
DATABASE_URL="mysql://user:password@host:port/database"
# For Docker host machine MySQL, use:
# DATABASE_URL="mysql://user:password@host.docker.internal:3306/database"
# NextAuth Configuration
NEXTAUTH_URL=http://localhost:3500
NEXTAUTH_SECRET=your-secret-key-here
AUTH_SECRET=your-secret-key-here
# Optional: MySQL connection check variables
DB_HOST=host.docker.internal
DB_PORT=3306
DB_USER=your-db-user
DB_PASSWORD=your-db-password
```
**Important:** If your MySQL server is running on your host machine (localhost), use `host.docker.internal` instead of `localhost` in the DATABASE_URL.
### 3. Run Database Migrations
Before building the Docker image, ensure your database schema is up to date:
```bash
npm install
npx prisma generate
npx prisma db push
```
## Building and Running
### Option 1: Using Docker Compose (Recommended)
```bash
# Build and start the container
docker-compose up -d
# View logs
docker-compose logs -f app
# Stop the container
docker-compose down
```
### Option 2: Using Docker directly
```bash
# Build the image
docker build -t ultimate-lists-app .
# Run the container
docker run -d \
-p 3500:3500 \
--env-file .env \
--name ultimate-lists-app \
ultimate-lists-app
# View logs
docker logs -f ultimate-lists-app
# Stop the container
docker stop ultimate-lists-app
docker rm ultimate-lists-app
```
## Accessing the Application
Once running, access the application at:
- **http://localhost:3500**
## Troubleshooting
### Cannot connect to MySQL
If you see database connection errors:
1. Verify MySQL is running and accessible
2. Check that you're using `host.docker.internal` instead of `localhost` in DATABASE_URL
3. Ensure MySQL allows connections from Docker containers
4. Verify firewall settings allow the connection
### Build fails
If the build fails:
1. Ensure `output: 'standalone'` is set in `next.config.js`
2. Check that all dependencies are properly installed
3. Verify Prisma schema is valid
### Port already in use
If port 3500 is already in use:
```bash
# Find what's using the port
lsof -i :3500
# Change the port in docker-compose.yml or use a different port:
docker run -p 3501:3500 ...
```
## Development vs Production
This Docker setup is configured for production use. For development:
```bash
# Use the regular dev server
npm run dev
```
## Updating the Application
To update after code changes:
```bash
# Rebuild and restart
docker-compose up -d --build
# Or with Docker directly
docker build -t ultimate-lists-app .
docker stop ultimate-lists-app
docker rm ultimate-lists-app
docker run -d -p 3500:3500 --env-file .env --name ultimate-lists-app ultimate-lists-app
```

50
Dockerfile Normal file
View File

@@ -0,0 +1,50 @@
# Use Node.js LTS version
FROM node:20-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Copy package files
COPY package.json package-lock.json* ./
RUN npm ci
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Generate Prisma Client
RUN npx prisma generate
# Build Next.js application
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build
# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
# Copy necessary files
COPY --from=builder /app/public ./public
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma
COPY --from=builder /app/prisma ./prisma
USER nextjs
EXPOSE 3500
ENV PORT 3500
ENV HOSTNAME "0.0.0.0"
CMD ["node", "server.js"]

43
docker-compose.yml Normal file
View File

@@ -0,0 +1,43 @@
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3500:3500"
environment:
- NODE_ENV=production
- DATABASE_URL=${DATABASE_URL}
- NEXTAUTH_URL=${NEXTAUTH_URL:-http://localhost:3500}
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
- AUTH_SECRET=${AUTH_SECRET}
restart: unless-stopped
depends_on:
- db-check
networks:
- app-network
# Health check service to ensure MySQL is accessible
db-check:
image: mysql:8.0
command: >
sh -c "
until mysqladmin ping -h$${DB_HOST} -P$${DB_PORT} -u$${DB_USER} -p$${DB_PASSWORD} --silent; do
echo 'Waiting for MySQL...';
sleep 2;
done;
echo 'MySQL is ready!';
"
environment:
- DB_HOST=${DB_HOST:-localhost}
- DB_PORT=${DB_PORT:-3306}
- DB_USER=${DB_USER:-root}
- DB_PASSWORD=${DB_PASSWORD}
networks:
- app-network
networks:
app-network:
driver: bridge

View File

@@ -1,5 +1,6 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
output: 'standalone',
experimental: { experimental: {
optimizePackageImports: ['lucide-react'], optimizePackageImports: ['lucide-react'],
}, },