initial working version
This commit is contained in:
387
wishlist-app/DOCKER.md
Normal file
387
wishlist-app/DOCKER.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# Docker Deployment Guide
|
||||
|
||||
This application is fully containerized and ready for Docker deployment.
|
||||
|
||||
## Quick Start with Docker Compose
|
||||
|
||||
The easiest way to run the entire stack locally:
|
||||
|
||||
```bash
|
||||
# Start the application and database
|
||||
docker-compose up -d
|
||||
|
||||
# Check if containers are running
|
||||
docker-compose ps
|
||||
|
||||
# Run database migrations
|
||||
docker-compose exec app bun run db:push
|
||||
|
||||
# View application logs
|
||||
docker-compose logs -f app
|
||||
|
||||
# View database logs
|
||||
docker-compose logs -f db
|
||||
```
|
||||
|
||||
Visit `http://localhost:3000`
|
||||
|
||||
### Stopping
|
||||
|
||||
```bash
|
||||
# Stop containers
|
||||
docker-compose down
|
||||
|
||||
# Stop and remove volumes (⚠️ deletes data)
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
## Building the Docker Image
|
||||
|
||||
### Local Build
|
||||
|
||||
```bash
|
||||
# Build the image
|
||||
docker build -t wishlist-app .
|
||||
|
||||
# Run the container (requires database)
|
||||
docker run -d \
|
||||
-p 3000:3000 \
|
||||
-e DATABASE_URL="postgresql://user:pass@host:5432/db" \
|
||||
--name wishlist-app \
|
||||
wishlist-app
|
||||
```
|
||||
|
||||
### Multi-stage Build Details
|
||||
|
||||
The Dockerfile uses a multi-stage build for optimization:
|
||||
|
||||
1. **base**: Base Bun image
|
||||
2. **deps**: Install dependencies with frozen lockfile
|
||||
3. **builder**: Build the SvelteKit application
|
||||
4. **runner**: Production image with minimal size
|
||||
|
||||
Final image includes:
|
||||
- Built application (`/app/build`)
|
||||
- Production dependencies
|
||||
- Drizzle schema for migrations
|
||||
- Port 3000 exposed
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Required environment variables:
|
||||
|
||||
```env
|
||||
DATABASE_URL=postgresql://username:password@host:port/database
|
||||
NODE_ENV=production
|
||||
PORT=3000
|
||||
```
|
||||
|
||||
### For docker-compose
|
||||
|
||||
Edit `docker-compose.yml` to change database credentials.
|
||||
|
||||
### For Coolify
|
||||
|
||||
Set in the Coolify dashboard under **Environment Variables**.
|
||||
|
||||
## Database Migrations
|
||||
|
||||
### Initial Setup
|
||||
|
||||
After first deployment:
|
||||
|
||||
```bash
|
||||
# Using docker-compose
|
||||
docker-compose exec app bun run db:push
|
||||
|
||||
# Using standalone container
|
||||
docker exec -it wishlist-app bun run db:push
|
||||
```
|
||||
|
||||
### Applying Schema Changes
|
||||
|
||||
After modifying `src/lib/server/schema.ts`:
|
||||
|
||||
```bash
|
||||
# Generate migration
|
||||
bun run db:generate
|
||||
|
||||
# Apply to running container
|
||||
docker-compose exec app bun run db:push
|
||||
```
|
||||
|
||||
## Port Configuration
|
||||
|
||||
Default port: `3000`
|
||||
|
||||
To change:
|
||||
|
||||
1. **docker-compose.yml**:
|
||||
```yaml
|
||||
ports:
|
||||
- "8080:3000" # External:Internal
|
||||
```
|
||||
|
||||
2. **Dockerfile** (if needed):
|
||||
```dockerfile
|
||||
ENV PORT=3000
|
||||
EXPOSE 3000
|
||||
```
|
||||
|
||||
## Volumes and Data Persistence
|
||||
|
||||
### PostgreSQL Data
|
||||
|
||||
Data is persisted in a Docker volume:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
postgres_data:
|
||||
```
|
||||
|
||||
To backup:
|
||||
```bash
|
||||
docker-compose exec db pg_dump -U wishlistuser wishlist > backup.sql
|
||||
```
|
||||
|
||||
To restore:
|
||||
```bash
|
||||
docker-compose exec -T db psql -U wishlistuser wishlist < backup.sql
|
||||
```
|
||||
|
||||
## Health Checks
|
||||
|
||||
### Application Health
|
||||
|
||||
The app responds on `http://localhost:3000/`
|
||||
|
||||
### Database Health
|
||||
|
||||
PostgreSQL health check is configured in docker-compose.yml:
|
||||
```yaml
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U wishlistuser -d wishlist"]
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
```
|
||||
|
||||
## Production Considerations
|
||||
|
||||
### Security
|
||||
|
||||
1. **Change default credentials** in docker-compose.yml
|
||||
2. **Use secrets** for sensitive data:
|
||||
```yaml
|
||||
secrets:
|
||||
db_password:
|
||||
file: ./secrets/db_password.txt
|
||||
```
|
||||
|
||||
3. **Don't expose PostgreSQL port** in production:
|
||||
```yaml
|
||||
# Remove or comment out:
|
||||
# ports:
|
||||
# - "5432:5432"
|
||||
```
|
||||
|
||||
### Performance
|
||||
|
||||
1. **Resource Limits**:
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '0.5'
|
||||
memory: 512M
|
||||
```
|
||||
|
||||
2. **Use PostgreSQL connection pooling** for high traffic
|
||||
|
||||
### Networking
|
||||
|
||||
For production with reverse proxy (Nginx, Traefik):
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
networks:
|
||||
- traefik_network
|
||||
- internal
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.wishlist.rule=Host(`wishlist.example.com`)"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container won't start
|
||||
|
||||
```bash
|
||||
# Check logs
|
||||
docker-compose logs app
|
||||
|
||||
# Common issues:
|
||||
# - DATABASE_URL incorrect
|
||||
# - Database not ready
|
||||
# - Port already in use
|
||||
```
|
||||
|
||||
### Database connection failed
|
||||
|
||||
```bash
|
||||
# Test database connectivity
|
||||
docker-compose exec app sh
|
||||
bun run db:push
|
||||
|
||||
# Check database is running
|
||||
docker-compose ps db
|
||||
|
||||
# Restart database
|
||||
docker-compose restart db
|
||||
```
|
||||
|
||||
### Build fails
|
||||
|
||||
```bash
|
||||
# Clear build cache
|
||||
docker-compose build --no-cache
|
||||
|
||||
# Check Docker resources
|
||||
docker system df
|
||||
docker system prune # Clean up if needed
|
||||
```
|
||||
|
||||
### Permission errors
|
||||
|
||||
```bash
|
||||
# Fix file permissions
|
||||
sudo chown -R $USER:$USER .
|
||||
|
||||
# Rebuild
|
||||
docker-compose up --build -d
|
||||
```
|
||||
|
||||
## Development with Docker
|
||||
|
||||
### Live Development
|
||||
|
||||
For development with hot reload, mount source:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
command: bun run dev
|
||||
volumes:
|
||||
- ./src:/app/src
|
||||
- ./static:/app/static
|
||||
environment:
|
||||
NODE_ENV: development
|
||||
```
|
||||
|
||||
### Access Database
|
||||
|
||||
```bash
|
||||
# Using psql
|
||||
docker-compose exec db psql -U wishlistuser wishlist
|
||||
|
||||
# Using Drizzle Studio
|
||||
docker-compose exec app bun run db:studio
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions Example
|
||||
|
||||
```yaml
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Build image
|
||||
run: docker build -t wishlist-app .
|
||||
- name: Push to registry
|
||||
run: |
|
||||
docker tag wishlist-app registry.example.com/wishlist-app
|
||||
docker push registry.example.com/wishlist-app
|
||||
```
|
||||
|
||||
## Coolify Deployment
|
||||
|
||||
For Coolify deployment, see [COOLIFY_DEPLOYMENT.md](./COOLIFY_DEPLOYMENT.md)
|
||||
|
||||
Coolify will:
|
||||
1. Pull from your Git repository
|
||||
2. Build using this Dockerfile
|
||||
3. Deploy with configured environment variables
|
||||
4. Set up networking and SSL automatically
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Container Stats
|
||||
|
||||
```bash
|
||||
# Real-time stats
|
||||
docker stats wishlist-app wishlist-db
|
||||
|
||||
# Resource usage
|
||||
docker-compose top
|
||||
```
|
||||
|
||||
### Logs
|
||||
|
||||
```bash
|
||||
# Follow logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Last 100 lines
|
||||
docker-compose logs --tail=100
|
||||
|
||||
# Specific service
|
||||
docker-compose logs -f app
|
||||
```
|
||||
|
||||
## Cleanup
|
||||
|
||||
```bash
|
||||
# Stop and remove containers
|
||||
docker-compose down
|
||||
|
||||
# Remove images
|
||||
docker rmi wishlist-app
|
||||
|
||||
# Remove all unused data
|
||||
docker system prune -a
|
||||
|
||||
# Remove specific volume
|
||||
docker volume rm wishlist-app_postgres_data
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. ✅ Use `.dockerignore` to reduce build context
|
||||
2. ✅ Multi-stage builds for smaller images
|
||||
3. ✅ Non-root user in production
|
||||
4. ✅ Health checks configured
|
||||
5. ✅ Secrets management for credentials
|
||||
6. ✅ Resource limits defined
|
||||
7. ✅ Regular backups of database
|
||||
8. ✅ Monitoring and logging
|
||||
9. ✅ Security scanning of images
|
||||
10. ✅ Version tags for images
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Docker Documentation](https://docs.docker.com/)
|
||||
- [Docker Compose Documentation](https://docs.docker.com/compose/)
|
||||
- [Coolify Documentation](https://coolify.io/docs)
|
||||
- [SvelteKit Deployment](https://kit.svelte.dev/docs/adapters)
|
||||
Reference in New Issue
Block a user