docker-compose up -dThat's it! The application will be available at http://localhost:8080
- ✅ Complete Task Manager application
- ✅ SQLite database with automatic schema initialization
- ✅ Persistent data storage (survives restarts)
- ✅ Health monitoring
- ✅ Production-optimized build
- Application listens on port 8080
- Binds to 0.0.0.0 (accessible from all interfaces)
- Configurable via
PORTenvironment variable
- URL:
http://localhost:8080/health - Response:
{"status":"healthy"} - Used by Docker healthchecks and orchestration systems
- Type: SQLite (embedded, no separate DB service needed)
- Location:
/app/data/tasks.db(in Docker volume) - Connection: Parses
DATABASE_URLenvironment variable - Schema: Auto-initializes on first run
- Persistence: All data persists across restarts via Docker volume
- First registered user becomes admin automatically
- Admin users can access Settings page
- Admin status checked when users table is empty
- All system configuration stored in database
- Managed via Settings Page UI (admin only)
- Default settings auto-initialized:
app_name: Application namemax_tasks_per_user: Task limitssession_timeout: JWT token expirationallow_registration: Control new signups
┌─────────────────────────────────────┐
│ Docker Container (8080) │
│ ┌───────────────────────────────┐ │
│ │ Node.js + Express Server │ │
│ │ (Backend API + Frontend) │ │
│ └───────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────┐ │
│ │ SQLite Database │ │
│ │ /app/data/tasks.db │ │
│ │ (Mounted to Docker Volume) │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
│
▼
┌──────────────┐
│ Docker Volume│
│ (Persistent) │
└──────────────┘
Configured in docker-compose.yml:
- NODE_ENV=production
- PORT=8080
- DATABASE_URL=sqlite:///app/data/tasks.db
- JWT_SECRET=change-this-to-a-secure-random-string-in-productionJWT_SECRET in production!
docker-compose psdocker-compose logs -fdocker-compose restartdocker-compose downdocker-compose down -vdocker-compose up -d --buildcurl http://localhost:8080/health
# Expected: {"status":"healthy"}curl -X POST http://localhost:8080/api/auth/register \
-H "Content-Type: application/json" \
-d '{"username":"admin","email":"admin@example.com","password":"secure123"}'curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"secure123"}'TOKEN="your-token-from-login"
curl -X POST http://localhost:8080/api/tasks \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $TOKEN" \
-d '{"title":"Test Task","description":"Testing","priority":"high"}'curl http://localhost:8080/api/settings \
-H "Authorization: Bearer $TOKEN"Data persists across container restarts. Test it:
# 1. Create some data (register, add tasks)
# 2. Restart container
docker-compose restart
# 3. Verify data is still there
curl -X POST http://localhost:8080/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"secure123"}'- Change
JWT_SECRETto a strong random value - Enable HTTPS (use reverse proxy like Nginx)
- Implement rate limiting
- Regular security updates
# Backup database
docker cp task-manager-app:/app/data/tasks.db ./backup-$(date +%Y%m%d).db
# Restore database
docker cp ./backup.db task-manager-app:/app/data/tasks.db
docker-compose restart- Health check runs every 30 seconds
- Monitor logs for errors:
docker-compose logs -f - Set up external monitoring (e.g., Prometheus, Datadog)
- For horizontal scaling, use external database (PostgreSQL/MySQL)
- Update
DATABASE_URLto point to external DB - Deploy behind load balancer
docker-compose logs# Change port in docker-compose.yml
ports:
- "8081:8080" # Use 8081 instead# Check if app is responding
docker exec task-manager-app wget -O- http://localhost:8080/health
# Check logs
docker-compose logs -f# Verify volume exists
docker volume ls | grep task-data
# Inspect volume
docker volume inspect testapp2_task-data# App runs as 'node' user (non-root)
# Volume permissions are automatically set
docker-compose down
docker volume rm testapp2_task-data
docker-compose up -dGitHub Actions workflow included at .github/workflows/deploy-to-gke.yaml for automated deployment to Google Kubernetes Engine.
GCP_PROJECT_IDGCP_SA_KEYGKE_CLUSTER_NAMEGKE_ZONE
- Build time: ~30-60 seconds (cached: ~5 seconds)
- Start time: ~3-5 seconds
- Cold start to ready: Under 2 minutes total
- Memory usage: ~150-200 MB
- Image size: ~200 MB
For issues or questions:
- Check logs:
docker-compose logs - Verify health:
curl http://localhost:8080/health - Review this guide
- Check GitHub issues
.
├── Dockerfile # Multi-stage build
├── docker-compose.yml # Orchestration config
├── .dockerignore # Build optimization
├── backend/ # API server
│ ├── server.js # Main server (PORT=8080)
│ ├── database.js # SQLite with DATABASE_URL support
│ ├── routes/
│ │ ├── auth.js # Login/register (first user = admin)
│ │ ├── tasks.js # Task CRUD
│ │ └── settings.js # DB-backed settings
│ └── middleware/
│ ├── auth.js # JWT verification
│ └── admin.js # Admin access control
└── frontend/ # React SPA
└── src/
└── components/
├── Login.jsx
├── TaskManager.jsx
└── Settings.jsx # Admin settings UI