Youâre staring at another $500/month managed DB bill. âI could self-host this,â you whisper⊠then imagine 2 AM alerts, corrupted backups, and security holes big enough to drive a truck through.
Relax. With Docker + a $5 VPS, you can run bulletproof PostgreSQL/MySQL databasesâwithout becoming a full-time sysadmin. Iâve done it for 50+ apps. Letâs build yours in 15 minutes flat.
Why Self-Host? (Spoiler: Itâs Not Just About Money)
Managed DBs are great⊠until you need:
-
Total control over configs (
shared_buffers
, anyone?). - Zero latency between app + DB (same VPS = đ„ speed).
- Costs below $10/month (yes, itâs possible).
Warning: Donât do this for Fortune 500 apps. Do it for:
- Side projects
- Internal tools
- Learning real database ops
Step 0: Pick Your VPS (The $5 Heroes)
- DigitalOcean: 1GB RAM, 25GB SSD, dead-simple UI â $6/month.
- Linode: 1GB RAM, NVMe storage, 1TB transfer â $5/month.
- Hetzner: 2GB RAM, 40GB SSD (Germany-only) â âŹ4.49/month.
Pro Move: Use Ubuntu 22.04 LTS. Battle-tested + Docker-friendly.
Step 1: Dockerize Your Database (5 Minutes)
For PostgreSQL:
# docker-compose.yml
services:
db:
image: postgres:15
container_name: postgres_db
volumes:
- pg_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: your_strong_password
ports:
- "5432:5432"
volumes:
pg_data:
For MySQL:
services:
db:
image: mysql:8.0
container_name: mysql_db
volumes:
- mysql_data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: your_strong_password
ports:
- "3306:3306"
volumes:
mysql_data:
Run it:
docker compose up -d
Boom. Your DB is alive.
Step 2: Lock Down Security (Non-Negotiable)
- SSH Hardening:
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
AllowUsers your_username
- Firewall Rules:
ufw allow 22/tcp
ufw allow 5432/tcp # or 3306 for MySQL
ufw enable
- DB User Best Practices:
-- NEVER use root!
CREATE USER app_user WITH PASSWORD 'strong!password';
GRANT SELECT, INSERT ON ALL TABLES TO app_user;
Step 3: Automated Backups (Sleep Soundly)
Backup Script (/scripts/backup_db.sh
):
#!/bin/bash
DATE=$(date +%Y-%m-%d)
docker exec postgres_db pg_dump -U postgres mydb > /backups/mydb_$DATE.sql
# For MySQL:
# docker exec mysql_db mysqldump -u root -p'pass' mydb > /backups/mydb_$DATE.sql
Cron Job (Daily at 2 AM):
crontab -e
0 2 * * * /bin/bash /scripts/backup_db.sh
Pro Tip: Sync backups to S3/Backblaze:
rclone sync /backups s3:bucket_name
Step 4: Monitoring (No More Guessing Games)
Install Prometheus + Grafana:
# docker-compose-monitoring.yml
services:
prometheus:
image: prom/prometheus
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
grafana:
image: grafana/grafana
ports:
- "3000:3000"
Grab a Dashboard:
When Self-Hosting Bites Back (Be Honest!)
- Disaster Strikes: VPS provider outage â DB down.
-
Security Fail: You missed a
pg_hba.conf
tweak â hacked. - Scale Walls: 100+ writes/sec? Good luck tuning solo.
Switch to Managed When:
- You value sleep > $200/month savings.
- Your app makes real revenue.
- Youâre bored of being a DBA.
Real-World Cost Breakdown
Item | Managed DB | Self-Hosted |
---|---|---|
Postgres | $50+/month | $5/month |
Backups | $20+/month | $0.023/GB (S3) |
Expertise | $0 (their ops) | Your weekends |
TL;DR:
- Docker Compose: Your databaseâs blueprint.
- $5 VPS: Your playground.
- Backups + Monitoring: Your insurance. Total control under $10/month? Priceless.
Your Move:
- Spin up a $5 VPS.
- Run the
docker-compose.yml
above. - Never pay for overkill again.
Tag that friend still paying for Heroku Postgres for their blog. They need freedom.
Self-hosting horror story? Share below! Weâve all been there. đ đŹ
Top comments (0)