# Rails Deploy Checklist — VPS Production

## Pre-deploy
- [ ] `RAILS_ENV=production` set
- [ ] `SECRET_KEY_BASE` generated (`rails secret`)
- [ ] `DATABASE_URL` configured
- [ ] `config/database.yml` uses `url: ENV["DATABASE_URL"]` for production
- [ ] `config/environments/production.rb`: `force_ssl = true`
- [ ] `config/environments/production.rb`: `config.active_storage.service = :local` (or :s3)
- [ ] `.env` file NOT in git, `.gitignore` includes `/.env*`

## Server setup
- [ ] Ruby installed (rbenv or system)
- [ ] PostgreSQL installed and running
- [ ] DB user created with `CREATEDB` privilege
- [ ] nginx installed with SSL (certbot)
- [ ] UFW: allow 22, 80, 443 only

## Deploy
- [ ] `git clone` / `git pull`
- [ ] `bundle install --deployment --without development test`
- [ ] `rails db:migrate`
- [ ] `rails db:seed` (first deploy only)
- [ ] `rails assets:precompile` (Propshaft/Sprockets)
- [ ] `rails tailwindcss:build` (if using tailwindcss-rails)
- [ ] systemd service for Puma created and enabled
- [ ] nginx proxy_pass to Puma configured
- [ ] `systemctl restart portfolio && systemctl reload nginx`

## Post-deploy verification
- [ ] `curl -sI https://yourdomain.com` returns 200
- [ ] CSS/JS loading (check browser DevTools Network tab)
- [ ] Database seeded correctly
- [ ] SSL certificate valid (check expiry)
- [ ] robots.txt accessible
- [ ] sitemap.xml accessible

## Monitoring
- [ ] `journalctl -u portfolio -f` for live logs
- [ ] Certbot auto-renew timer active (`systemctl status certbot.timer`)
- [ ] Disk space check (`df -h`)
- [ ] Memory check (`free -h`)

---
By Vadim Bobkov — bobkov.cc
