# Database Setup & Troubleshooting ## Initial Setup **✅ Migrations now run automatically!** When you start the API, it will automatically run any pending database migrations. ### Quick Setup ```bash # 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: ```bash 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 ```bash 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 ```bash 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 ```bash 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 1. **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 2. **audio_clips** - Audio recordings for posts - id, post_id, bucket, object_key, mime - transcript, duration_ms, created_at 3. **settings** - Application settings - id, key, value, updated_at ## Migrations ### Location - Migration files: `apps/api/drizzle/` - Config: `apps/api/drizzle.config.ts` ### Commands ```bash # 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`: ```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: ```bash docker-compose down -v docker-compose up -d --build ``` ## Backup & Restore ### Backup ```bash # 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 ```bash # Restore from backup docker exec -i voxblog-mysql mysql -u voxblog -pvoxblogAppPass123! voxblog < backup.sql ``` ## Reset Database **WARNING: This deletes all data!** ```bash # 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 ```bash # 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