Add Docker-based production deployment

- Multi-stage Dockerfile with Node builder and nginx server
- Nginx configuration with gzip, security headers, and caching
- Docker Compose setup with health checks
- Updated README with deployment instructions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Thomas Richter
2025-12-16 23:34:05 +01:00
parent 09fd0629af
commit 0064773eaa
5 changed files with 168 additions and 0 deletions

34
.dockerignore Normal file
View File

@@ -0,0 +1,34 @@
# Dependencies
node_modules
npm-debug.log*
# Build output
dist
# Git
.git
.gitignore
# IDE
.vscode
.idea
# OS files
.DS_Store
Thumbs.db
# Environment
.env
.env.local
# Docker
Dockerfile
docker-compose.yml
.dockerignore
# Documentation
README.md
# Misc
*.log
.cache

37
Dockerfile Normal file
View File

@@ -0,0 +1,37 @@
# Multi-stage build for production deployment
# Stage 1: Build the application
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy source code
COPY . .
# Build the application
RUN npm run build
# Stage 2: Serve with nginx
FROM nginx:alpine
# Copy built files from builder stage
COPY --from=builder /app/dist /usr/share/nginx/html
# Copy nginx configuration
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Expose port 80
EXPOSE 80
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/ || exit 1
# Start nginx
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -26,6 +26,48 @@ npm run build
The built files will be in the `dist/` directory.
## Docker Deployment
### Using Docker Compose (Recommended)
```bash
# Build and start the container
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the container
docker-compose down
```
The game will be available at `http://localhost:8080`
### Using Docker directly
```bash
# Build the image
docker build -t whalehunting-game .
# Run the container
docker run -d -p 8080:80 --name whalehunting whalehunting-game
# View logs
docker logs -f whalehunting
# Stop and remove container
docker stop whalehunting
docker rm whalehunting
```
### Production Deployment Notes
- The Docker image uses nginx to serve static files
- Includes gzip compression for better performance
- Health checks are configured for container monitoring
- Security headers are enabled
- Static assets are cached for 1 year
## Project Structure
```

24
docker-compose.yml Normal file
View File

@@ -0,0 +1,24 @@
version: '3.8'
services:
whalehunting-game:
build:
context: .
dockerfile: Dockerfile
image: whalehunting-game:latest
container_name: whalehunting-game
ports:
- "8080:80"
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/"]
interval: 30s
timeout: 3s
retries: 3
start_period: 5s
networks:
- whalehunting-network
networks:
whalehunting-network:
driver: bridge

31
nginx.conf Normal file
View File

@@ -0,0 +1,31 @@
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/x-javascript application/xml+rss;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Serve index.html for all routes (SPA support)
location / {
try_files $uri $uri/ /index.html;
}
# Error pages
error_page 404 /index.html;
}