388 lines
6.7 KiB
Markdown
388 lines
6.7 KiB
Markdown
# 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)
|