voxblog/DATABASE_SETUP.md
Ender 36de987b5e
All checks were successful
Deploy to Production / deploy (push) Successful in 1m45s
feat: implement automatic database migrations on server startup
- 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
2025-10-26 23:21:40 +01:00

209 lines
4.7 KiB
Markdown

# 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