- Changed admin frontend port from 3000 to 3300 across all configuration files - Changed API backend port from 3001 to 3301 across all configuration files - Updated health check endpoints to use new ports in CI/CD workflow - Modified documentation and deployment guides to reflect new port numbers - Updated Caddy and Nginx reverse proxy configurations to use new ports
7.3 KiB
Local Docker Testing Guide
Prerequisites
1. Install Docker Desktop (Mac)
Download and install from: https://www.docker.com/products/docker-desktop
Or use Homebrew:
brew install --cask docker
Start Docker Desktop from Applications.
2. Verify Installation
docker --version
docker-compose --version
Quick Start
1. Create Local .env File
# Copy example
cp .env.example .env
# Edit with your values
nano .env
Minimal .env for local testing:
# Database
MYSQL_ROOT_PASSWORD=localrootpass123
MYSQL_PASSWORD=localvoxblogpass123
# Application
ADMIN_PASSWORD=admin123
OPENAI_API_KEY=sk-your-actual-openai-key-here
GHOST_ADMIN_API_KEY=leave-empty-if-not-using
# S3 Storage (use your actual credentials)
S3_BUCKET=your-bucket-name
S3_REGION=us-east-1
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
S3_ENDPOINT=https://s3.amazonaws.com
# Frontend (for local testing)
VITE_API_URL=http://localhost:3301
2. Build and Start
# Build and start all containers
docker-compose up --build
# Or run in background (detached mode)
docker-compose up --build -d
This will:
- Build the API Docker image
- Build the Admin Docker image
- Start MySQL database
- Start all services
First build takes 5-10 minutes (downloading dependencies, building images)
3. Wait for Services to Start
Watch the logs until you see:
voxblog-mysql | ready for connections
voxblog-api | Server listening on port 3301
voxblog-admin | Configuration complete
4. Access Your Application
- Frontend: http://localhost:3300
- API: http://localhost:3301
- API Health: http://localhost:3301/api/health
5. Test the Application
- Open http://localhost:3300 in your browser
- Login with your ADMIN_PASSWORD
- Create a post
- Upload images
- Generate content with AI
Useful Commands
View Logs
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f api
docker-compose logs -f admin
docker-compose logs -f mysql
# Last 50 lines
docker-compose logs --tail=50 api
Check Status
# See running containers
docker-compose ps
# See all Docker containers
docker ps
Stop Services
# Stop all containers
docker-compose down
# Stop and remove volumes (deletes database!)
docker-compose down -v
Restart Services
# Restart all
docker-compose restart
# Restart specific service
docker-compose restart api
docker-compose restart admin
Rebuild After Code Changes
# Rebuild and restart
docker-compose up --build
# Rebuild specific service
docker-compose up --build api
docker-compose up --build admin
Access Container Shell
# API container
docker-compose exec api sh
# MySQL container
docker-compose exec mysql mysql -u voxblog -p
# Enter MYSQL_PASSWORD when prompted
Clean Up Everything
# Stop and remove containers
docker-compose down
# Remove all unused images
docker image prune -a
# Remove all unused volumes
docker volume prune
# Nuclear option - clean everything
docker system prune -a --volumes
Troubleshooting
Port Already in Use
If you get "port is already allocated" error:
# Check what's using the port
sudo lsof -i :3300
sudo lsof -i :3301
# Kill the process
kill -9 <PID>
# Or change ports in docker-compose.yml
ports:
- "3302:80" # Use 3302 instead of 3300
Build Fails
# Clean build cache
docker-compose build --no-cache
# Remove old images
docker image prune -a
# Try again
docker-compose up --build
Database Connection Error
# Check if MySQL is healthy
docker-compose ps
# View MySQL logs
docker-compose logs mysql
# Restart MySQL
docker-compose restart mysql
# Wait 30 seconds for MySQL to be ready
Out of Disk Space
# Check Docker disk usage
docker system df
# Clean up
docker system prune -a
docker volume prune
Container Keeps Restarting
# View logs to see error
docker-compose logs api
# Common issues:
# - Missing environment variables in .env
# - Database not ready (wait longer)
# - Port conflict
Can't Access Frontend
- Check if container is running:
docker-compose ps - Check logs:
docker-compose logs admin - Try accessing:
curl http://localhost:3300 - Check if port 3300 is free:
lsof -i :3300
API Returns 502 Error
- Check if API is running:
docker-compose ps - Check API logs:
docker-compose logs api - Test API directly:
curl http://localhost:3301/api/health - Check environment variables:
docker-compose exec api env
Development Workflow
Making Code Changes
Backend (API) changes:
# Edit code in apps/api/
# Rebuild and restart
docker-compose up --build api
Frontend (Admin) changes:
# Edit code in apps/admin/
# Rebuild and restart
docker-compose up --build admin
Database Changes
# Run migrations
docker-compose exec api pnpm run drizzle:migrate
# Generate new migration
docker-compose exec api pnpm run drizzle:generate
View Database
# Access MySQL
docker-compose exec mysql mysql -u voxblog -p
# Show databases
SHOW DATABASES;
USE voxblog;
SHOW TABLES;
# Query data
SELECT * FROM posts;
Testing Checklist
- Docker Desktop running
.envfile created with all valuesdocker-compose up --buildsuccessful- All 3 containers running (mysql, api, admin)
- Can access http://localhost:3300
- Can login with ADMIN_PASSWORD
- Can create a post
- Can upload images
- Can generate AI content
- Can save and publish
Performance Tips
Speed Up Builds
# Use BuildKit for faster builds
export DOCKER_BUILDKIT=1
export COMPOSE_DOCKER_CLI_BUILD=1
docker-compose up --build
Reduce Image Size
Already optimized with:
- Multi-stage builds
- Alpine Linux base images
- Production dependencies only
Persistent Data
Database data is stored in Docker volume mysql_data:
# List volumes
docker volume ls
# Inspect volume
docker volume inspect voxblog_mysql_data
# Backup volume
docker run --rm -v voxblog_mysql_data:/data -v $(pwd):/backup alpine tar czf /backup/mysql-backup.tar.gz /data
Next Steps
Once local testing is successful:
- ✅ Commit your changes
- ✅ Push to Gitea
- ✅ Deploy to VPS using deploy.sh
- ✅ Set up Caddy reverse proxy
- ✅ Configure CI/CD
Common Issues & Solutions
Issue: "Cannot connect to Docker daemon"
Solution: Start Docker Desktop
Issue: "Port 3000 is already allocated"
Solution: Stop other services or change port in docker-compose.yml
Issue: "Build takes too long"
Solution: First build is slow (5-10 min). Subsequent builds are faster.
Issue: "MySQL not ready"
Solution: Wait 30 seconds after starting. MySQL needs time to initialize.
Issue: "API returns 500 error"
Solution: Check .env file has all required variables, especially OPENAI_API_KEY
Issue: "Images not uploading"
Solution: Check S3 credentials in .env file
Quick Reference
# Start
docker-compose up -d
# Stop
docker-compose down
# Logs
docker-compose logs -f
# Rebuild
docker-compose up --build
# Clean up
docker-compose down -v
docker system prune -a
Ready to test! Start Docker Desktop, then run docker-compose up --build 🚀