Merge pull request 'feat: create production docker-compose.yml (#38)' (#60) from feature/issue-38-docker-compose into develop
Some checks failed
Deploy to Coolify / Code Quality (push) Has been cancelled
Deploy to Coolify / Run Tests (push) Has been cancelled
Deploy to Coolify / Deploy to Development (push) Has been cancelled
Deploy to Coolify / Deploy to Production (push) Has been cancelled
Deploy to Coolify / Deploy to Test (push) Has been cancelled

 Self-review passed

Production deployment ready with comprehensive documentation.
This commit was merged in pull request #60.
This commit is contained in:
2026-02-25 00:14:13 +00:00
4 changed files with 411 additions and 0 deletions

12
.env.production.example Normal file
View File

@@ -0,0 +1,12 @@
# Production Environment Variables
# Copy this file to .env.production and fill in your values
# Supabase Configuration (REQUIRED)
# Get these from your Supabase project settings
NUXT_PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co
NUXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here
# Server Configuration (optional)
# HOST=0.0.0.0
# PORT=3000
# NODE_ENV=production

347
DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,347 @@
# Deployment Guide
## Prerequisites
- Supabase project (managed or self-hosted)
- Docker and Docker Compose installed
- Domain name (optional, for production)
- SSL certificate (for HTTPS, recommended)
## Quick Start (Docker Compose)
### 1. Clone the repository
```bash
git clone https://gitea.jeanlucmakiola.de/pantry-app/pantry.git
cd pantry
```
### 2. Configure environment
```bash
cp .env.production.example .env.production
# Edit .env.production with your Supabase credentials
nano .env.production
```
Required environment variables:
- `NUXT_PUBLIC_SUPABASE_URL` - Your Supabase project URL
- `NUXT_PUBLIC_SUPABASE_ANON_KEY` - Your Supabase anonymous key
### 3. Build and run
```bash
docker-compose -f docker-compose.prod.yml --env-file .env.production up -d
```
The app will be available at `http://localhost:3000`
### 4. Verify deployment
```bash
# Check health
curl http://localhost:3000/api/health
# View logs
docker-compose -f docker-compose.prod.yml logs -f app
# Check status
docker-compose -f docker-compose.prod.yml ps
```
## Supabase Setup
### Option 1: Supabase Cloud (Recommended)
1. Create a free account at [supabase.com](https://supabase.com)
2. Create a new project
3. Run migrations: `supabase/migrations/*.sql`
4. Copy project URL and anon key to `.env.production`
### Option 2: Self-Hosted Supabase
Use the included `docker-compose.yml` for local Supabase:
```bash
# Create .env file
cp .env.example .env
# Edit .env with secure passwords
nano .env
# Start Supabase stack
docker-compose up -d
# Wait for services to be ready
docker-compose ps
# Run migrations
docker-compose exec db psql -U postgres -f /docker-entrypoint-initdb.d/001_initial_schema.sql
```
Supabase will be available at:
- API: http://localhost:54321
- Studio: http://localhost:54323
## Production Deployment Options
### Option 1: Coolify (Recommended)
1. Add new Resource → Docker Compose
2. Paste `docker-compose.prod.yml`
3. Add environment variables in Coolify UI
4. Deploy
### Option 2: Docker Standalone
```bash
# Build image
docker build -t pantry:latest .
# Run container
docker run -d \
--name pantry \
-p 3000:3000 \
-e NUXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co \
-e NUXT_PUBLIC_SUPABASE_ANON_KEY=your-key \
--restart unless-stopped \
pantry:latest
```
### Option 3: Kubernetes
Example deployment manifest:
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: pantry
spec:
replicas: 2
selector:
matchLabels:
app: pantry
template:
metadata:
labels:
app: pantry
spec:
containers:
- name: pantry
image: pantry:latest
ports:
- containerPort: 3000
env:
- name: NUXT_PUBLIC_SUPABASE_URL
valueFrom:
secretKeyRef:
name: pantry-secrets
key: supabase-url
- name: NUXT_PUBLIC_SUPABASE_ANON_KEY
valueFrom:
secretKeyRef:
name: pantry-secrets
key: supabase-key
livenessProbe:
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 40
periodSeconds: 30
resources:
limits:
memory: "512Mi"
cpu: "1000m"
requests:
memory: "256Mi"
cpu: "500m"
```
### Option 4: VPS with Nginx
```nginx
# /etc/nginx/sites-available/pantry
server {
listen 80;
server_name pantry.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
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;
}
}
```
## HTTPS/SSL
### Using Let's Encrypt (Certbot)
```bash
# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Get certificate
sudo certbot --nginx -d pantry.yourdomain.com
# Auto-renewal
sudo certbot renew --dry-run
```
### Using Cloudflare
1. Add your domain to Cloudflare
2. Enable "Full (strict)" SSL/TLS mode
3. Point DNS A record to your server IP
4. Cloudflare handles SSL automatically
## Monitoring
### Health Checks
```bash
# Manual check
curl http://localhost:3000/api/health
# With watch
watch -n 5 'curl -s http://localhost:3000/api/health | jq'
```
### Docker Stats
```bash
docker stats pantry-app
```
### Logs
```bash
# Follow logs
docker-compose -f docker-compose.prod.yml logs -f
# Last 100 lines
docker logs --tail 100 pantry-app
# Since timestamp
docker logs --since "2024-01-01T00:00:00" pantry-app
```
## Updating
### Pull latest changes
```bash
cd pantry
git pull origin main
# Rebuild and restart
docker-compose -f docker-compose.prod.yml build
docker-compose -f docker-compose.prod.yml up -d
```
### Rolling back
```bash
# Tag before upgrading
docker tag pantry:latest pantry:backup-20240101
# Rollback if needed
docker-compose -f docker-compose.prod.yml down
docker tag pantry:backup-20240101 pantry:latest
docker-compose -f docker-compose.prod.yml up -d
```
## Backup
### Database (Supabase)
```bash
# Manual backup
pg_dump -h localhost -U postgres -d postgres > backup.sql
# Restore
psql -h localhost -U postgres -d postgres < backup.sql
```
### Docker Volumes
```bash
# Backup
docker run --rm -v pantry_db-data:/data -v $(pwd):/backup ubuntu tar czf /backup/db-backup.tar.gz /data
# Restore
docker run --rm -v pantry_db-data:/data -v $(pwd):/backup ubuntu tar xzf /backup/db-backup.tar.gz -C /
```
## Troubleshooting
### Container won't start
```bash
# Check logs
docker logs pantry-app
# Verify environment variables
docker exec pantry-app env | grep NUXT
# Inspect container
docker inspect pantry-app
```
### Supabase connection issues
1. Verify Supabase URL and key
2. Check network connectivity
3. Verify RLS policies in Supabase
4. Check CORS settings
### Performance issues
1. Check resource limits
2. Monitor with `docker stats`
3. Increase memory/CPU limits in docker-compose
4. Enable compression in Nginx
### PWA not updating
1. Clear browser cache
2. Unregister service worker
3. Check that service worker is being served with correct headers
4. Verify manifest.json is accessible
## Security Checklist
- [ ] Use HTTPS (SSL certificate)
- [ ] Set secure environment variables
- [ ] Don't commit .env files
- [ ] Use strong Supabase passwords
- [ ] Enable RLS policies in Supabase
- [ ] Keep Docker images updated
- [ ] Use firewall rules
- [ ] Regular backups
- [ ] Monitor logs for suspicious activity
## Performance Optimization
- Enable CDN (Cloudflare)
- Use HTTP/2
- Enable gzip/brotli compression
- Set proper cache headers
- Optimize images
- Use Supabase CDN for assets
## Support
- Documentation: [docs/](docs/)
- Issues: [Gitea Issues](https://gitea.jeanlucmakiola.de/pantry-app/pantry/issues)
- Wiki: Coming soon
---
**Happy hosting! 🚀**

52
docker-compose.prod.yml Normal file
View File

@@ -0,0 +1,52 @@
# Production Docker Compose for Pantry App
#
# This compose file only runs the Nuxt frontend.
# Supabase should be hosted separately (managed service or self-hosted).
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: pantry:latest
container_name: pantry-app
restart: unless-stopped
ports:
- "3000:3000"
environment:
# Supabase connection (REQUIRED - set these in .env.production)
NUXT_PUBLIC_SUPABASE_URL: ${NUXT_PUBLIC_SUPABASE_URL}
NUXT_PUBLIC_SUPABASE_ANON_KEY: ${NUXT_PUBLIC_SUPABASE_ANON_KEY}
# Server configuration
NODE_ENV: production
HOST: 0.0.0.0
PORT: 3000
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
interval: 30s
timeout: 3s
start_period: 40s
retries: 3
networks:
- pantry
# Resource limits (adjust based on your needs)
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
reservations:
memory: 256M
cpus: '0.5'
networks:
pantry:
driver: bridge