Add Docker deployment configuration for dokindthings.fund

- Add Dockerfile with multi-stage build for optimized production image
- Add docker-compose.yml for easy container management
- Add Nginx reverse proxy configuration with SSL support
- Update next.config.mjs to enable standalone output mode
- Add .dockerignore to optimize build process
- Add DEPLOYMENT.md with comprehensive deployment instructions

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2025-11-22 17:49:56 -08:00
parent 0631320df7
commit b1bc3bd38b
6 changed files with 243 additions and 1 deletions

9
.dockerignore Normal file
View File

@ -0,0 +1,9 @@
Dockerfile
.dockerignore
node_modules
npm-debug.log
.next
.git
.gitignore
README.md
nginx

119
DEPLOYMENT.md Normal file
View File

@ -0,0 +1,119 @@
# Deployment Instructions for dokindthings.fund
This guide will help you deploy the Kindness Fund website to your private server at dokindthings.fund.
## Prerequisites
- Docker and Docker Compose installed on your server
- Nginx installed and configured
- Domain `dokindthings.fund` pointing to your server's IP address
- SSL certificate (Let's Encrypt recommended)
## Step 1: Clone the Repository
On your server, clone the repository from your Gitea instance:
```bash
git clone https://gitea.jeffemmett.com/jeffemmett/kindness-fund-website.git
cd kindness-fund-website
```
## Step 2: Build and Start the Docker Container
```bash
# Create the external network if it doesn't exist
docker network create web
# Build and start the container
docker compose up -d --build
```
The application will be available on port 3001 locally.
## Step 3: Configure Nginx
Copy the Nginx configuration to your Nginx sites-available directory:
```bash
sudo cp nginx/dokindthings.fund.conf /etc/nginx/sites-available/dokindthings.fund
sudo ln -s /etc/nginx/sites-available/dokindthings.fund /etc/nginx/sites-enabled/
```
## Step 4: Set Up SSL Certificate
If you don't have an SSL certificate yet, use Let's Encrypt:
```bash
sudo certbot --nginx -d dokindthings.fund -d www.dokindthings.fund
```
This will automatically obtain and configure the SSL certificate.
If you already have certificates, update the paths in the Nginx configuration file.
## Step 5: Test and Reload Nginx
Test the Nginx configuration:
```bash
sudo nginx -t
```
If the test passes, reload Nginx:
```bash
sudo systemctl reload nginx
```
## Step 6: Verify Deployment
Visit https://dokindthings.fund in your browser to verify the site is working.
## Updating the Site
To update the site with new changes:
```bash
cd kindness-fund-website
git pull
docker compose down
docker compose up -d --build
```
## Troubleshooting
### Check Docker Container Logs
```bash
docker logs kindness-fund-website
```
### Check Nginx Logs
```bash
sudo tail -f /var/log/nginx/dokindthings.fund.error.log
sudo tail -f /var/log/nginx/dokindthings.fund.access.log
```
### Check Container Status
```bash
docker ps
```
### Rebuild Container
If you need to completely rebuild:
```bash
docker compose down
docker compose build --no-cache
docker compose up -d
```
## Notes
- The application runs on port 3001 internally
- Nginx acts as a reverse proxy, forwarding HTTPS traffic from port 443 to port 3001
- The Docker container will automatically restart unless stopped manually
- Make sure your firewall allows traffic on ports 80 and 443

50
Dockerfile Normal file
View File

@ -0,0 +1,50 @@
FROM node:20-alpine AS base
# Install dependencies only when needed
FROM base AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json pnpm-lock.yaml* ./
RUN corepack enable pnpm && pnpm i --frozen-lockfile
# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Disable telemetry during build
ENV NEXT_TELEMETRY_DISABLED=1
RUN corepack enable pnpm && pnpm 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 --from=builder /app/public ./public
# Set the correct permission for prerender cache
RUN mkdir .next
RUN chown nextjs:nodejs .next
# Automatically leverage output traces to reduce image size
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]

17
docker-compose.yml Normal file
View File

@ -0,0 +1,17 @@
services:
kindness-fund-website:
build:
context: .
dockerfile: Dockerfile
container_name: kindness-fund-website
restart: unless-stopped
ports:
- "3001:3000"
environment:
- NODE_ENV=production
networks:
- web
networks:
web:
external: true

View File

@ -1,12 +1,13 @@
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
output: 'standalone',
typescript: { typescript: {
ignoreBuildErrors: true, ignoreBuildErrors: true,
}, },
images: { images: {
unoptimized: true, unoptimized: true,
}, },
} }
export default nextConfig export default nextConfig

View File

@ -0,0 +1,46 @@
server {
listen 80;
listen [::]:80;
server_name dokindthings.fund www.dokindthings.fund;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name dokindthings.fund www.dokindthings.fund;
# SSL Certificate paths (update these with your actual certificate paths)
ssl_certificate /etc/letsencrypt/live/dokindthings.fund/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dokindthings.fund/privkey.pem;
# SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Logging
access_log /var/log/nginx/dokindthings.fund.access.log;
error_log /var/log/nginx/dokindthings.fund.error.log;
# Proxy settings
location / {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
}