- Added new migrate.ts module to handle automatic database migrations using drizzle-orm - Modified server startup to run migrations before Express initialization - Added comprehensive documentation in AUTO_MIGRATION_SUMMARY.md explaining the implementation - Updated DATABASE_SETUP.md to reflect automatic migration process and troubleshooting steps - Added error handling to exit process if migrations fail during startup - Implemented clear
4.7 KiB
Database Setup & Troubleshooting
Initial Setup
✅ Migrations now run automatically! When you start the API, it will automatically run any pending database migrations.
Quick Setup
# 1. Start containers
docker-compose up -d --build
# 2. Wait for MySQL to be healthy and migrations to complete (about 30 seconds)
docker-compose logs -f api
# You should see:
# 🔄 Running database migrations...
# ✅ Database migrations completed successfully
# API server running on port 3301
# 3. Verify tables were created (optional)
docker exec voxblog-mysql mysql -u voxblog -pvoxblogAppPass123! voxblog -e "SHOW TABLES;"
Manual Migration (if needed)
You can still run migrations manually if needed:
docker exec voxblog-api sh -c "cd /app/apps/api && pnpm drizzle:migrate"
Expected output:
Tables_in_voxblog
__drizzle_migrations
audio_clips
posts
settings
Common Issues
1. Access Denied Error
Error: Access denied for user 'voxblog'@'172.20.0.3' (using password: YES)
Cause: MySQL container was created with old/different passwords
Solution: Reset the database volume and restart
docker-compose down -v
docker-compose up -d --build
# Wait 30 seconds for MySQL to initialize
docker exec voxblog-api sh -c "cd /app/apps/api && pnpm drizzle:migrate"
2. Tables Don't Exist
Error: Table 'voxblog.posts' doesn't exist
Cause: Migrations failed to run automatically (check API logs)
Solution: Check API logs for migration errors
docker-compose logs api | grep -i migration
# If migrations failed, restart the API
docker-compose restart api
# Or run migrations manually
docker exec voxblog-api sh -c "cd /app/apps/api && pnpm drizzle:migrate"
3. MySQL Container Not Healthy
Error: API can't connect to database
Solution: Check MySQL logs and wait for it to be healthy
docker-compose logs mysql
docker-compose ps # Check if mysql is "healthy"
Database Schema
The application uses Drizzle ORM with MySQL. Schema is defined in:
apps/api/src/db/schema.ts
Tables
-
posts - Blog posts with metadata
- id, title, content_html, tags_text, feature_image
- canonical_url, prompt, status
- ghost_post_id, ghost_slug, ghost_published_at, ghost_url
- selected_image_keys, generated_draft, image_placeholders
- version, created_at, updated_at
-
audio_clips - Audio recordings for posts
- id, post_id, bucket, object_key, mime
- transcript, duration_ms, created_at
-
settings - Application settings
- id, key, value, updated_at
Migrations
Location
- Migration files:
apps/api/drizzle/ - Config:
apps/api/drizzle.config.ts
Commands
# Generate new migration (after schema changes)
docker exec voxblog-api sh -c "cd /app/apps/api && pnpm drizzle:generate"
# Run migrations
docker exec voxblog-api sh -c "cd /app/apps/api && pnpm drizzle:migrate"
Environment Variables
Database connection uses these variables from .env:
# MySQL Root
MYSQL_ROOT_PASSWORD=voxblogRootPass123!
# Application User
MYSQL_PASSWORD=voxblogAppPass123!
DB_HOST=mysql
DB_PORT=3306
DB_USER=voxblog
DB_PASSWORD=voxblogAppPass123!
DB_NAME=voxblog
Important: If you change these values, you must recreate the MySQL container:
docker-compose down -v
docker-compose up -d --build
Backup & Restore
Backup
# Backup all data
docker exec voxblog-mysql mysqldump -u voxblog -pvoxblogAppPass123! voxblog > backup.sql
# Backup specific table
docker exec voxblog-mysql mysqldump -u voxblog -pvoxblogAppPass123! voxblog posts > posts_backup.sql
Restore
# Restore from backup
docker exec -i voxblog-mysql mysql -u voxblog -pvoxblogAppPass123! voxblog < backup.sql
Reset Database
WARNING: This deletes all data!
# Complete reset
docker-compose down -v
docker-compose up -d --build
# Wait for MySQL to be healthy
sleep 30
# Run migrations
docker exec voxblog-api sh -c "cd /app/apps/api && pnpm drizzle:migrate"
Verify Database
# Check if containers are running
docker-compose ps
# Check MySQL is healthy
docker-compose ps mysql
# List tables
docker exec voxblog-mysql mysql -u voxblog -pvoxblogAppPass123! voxblog -e "SHOW TABLES;"
# Count posts
docker exec voxblog-mysql mysql -u voxblog -pvoxblogAppPass123! voxblog -e "SELECT COUNT(*) FROM posts;"
# Check migrations
docker exec voxblog-mysql mysql -u voxblog -pvoxblogAppPass123! voxblog -e "SELECT * FROM __drizzle_migrations;"
Troubleshooting Checklist
- MySQL container is running and healthy
- Environment variables are correct in
.env - Migrations have been run
- Tables exist in database
- API can connect to database (check logs)
Last Updated: 2025-10-26