Deployment Quick Start Guide
Welcome! 👋
This guide will help you learn the Sampo deployment system in ~30 minutes. You'll deploy your first change to production safely and confidently.
Prerequisites Checklist
Before starting, make sure you have:
- [ ] SSH access to VPS (
ssh root@23.235.204.208works) - [ ] Docker Desktop installed and running
- [ ] Git repository cloned and up to date
- [ ]
.env.blueline-alphafile in project root - [ ] pnpm installed (
pnpm -vworks)
Don't have these? Ask DevOps team for access.
Your First Deployment (Tutorial)
We'll make a small, safe change and deploy it to production. This is the safest way to learn!
Step 1: Make a Small Change (2 minutes) ⚠️ REQUIRED
You MUST make this change - the verification step checks for it!
Open the health controller:
# Open the health controller
code apps/api/src/health/health.controller.ts
Find the @Get() method (around line 38) and add YOUR comment with YOUR actual
name:
@Public()
@Get()
// ... other decorators ...
getHealth() {
// DEPLOYMENT TEST: Mark Jedrzejczyk - 2026-02-08
// ⬆️ REPLACE with YOUR name and TODAY'S date!
return this.healthService.getBasicHealth();
}
Example (use YOUR name and date):
// DEPLOYMENT TEST: Jane Smith - 2026-02-08
// DEPLOYMENT TEST: John Doe - 2026-02-08
// DEPLOYMENT TEST: Your Name Here - 2026-02-08
⚠️ CRITICAL: Replace <Your Name> and <Today's Date> with actual values,
not the placeholders!
Why this change?
- It's safe (just a comment, no behavior change)
- It's traceable (you can verify YOUR change deployed by finding YOUR name on VPS)
- It's reversible (easy to rollback if needed)
Save the file after making this change!
Step 2: Validate Locally (3 minutes)
Before deploying, always validate:
# 1. Validate environment
./scripts/validate-deployment-env.sh
# Expected: "✅ All environment variables validated successfully"
If validation fails:
- Check
.env.blueline-alphaexists - Verify all required variables are set
- Ask team if unsure about any values
# 2. Type check
pnpm type-check
# Expected: "No errors found"
If type errors:
- These are from your change (fix them)
- OR from main branch (pull latest and fix)
# 3. Verify YOUR change is in the file
grep -i "DEPLOYMENT TEST.*$(whoami)" apps/api/src/modules/health/health.controller.ts
# Expected: Shows YOUR comment line
# Example: // DEPLOYMENT TEST: Mark Jedrzejczyk - 2026-02-08
If grep finds NOTHING:
- ⚠️ STOP! You skipped Step 1
- Go back and add YOUR comment to the TypeScript file
- Don't proceed until you see your name in the grep output
Step 3: Dry-Run (Preview) (2 minutes)
Let's see what would happen without actually deploying:
./scripts/docker-audit/build-cross-platform.sh --all --amd64 \
--api-url https://alpha.theblueline.com/api \
--push root@23.235.204.208 \
--dry-run
What to look for in output:
- ✅ Version tag (e.g.,
20260208-143022-a4c6788) - ✅ Two images: API and Web
- ✅ Estimated transfer size (~1.15GB)
- ✅ Deployment steps listed
This is safe - nothing is deployed, just a preview.
Step 4: Deploy for Real (10-15 minutes)
Now let's actually deploy:
./scripts/docker-audit/build-cross-platform.sh --all --amd64 \
--api-url https://alpha.theblueline.com/api \
--push root@23.235.204.208 \
--smoke-tests
What's happening (watch the output):
-
Environment Validation (~5 seconds)
- Checks 8 required variables
-
Type Check (~10 seconds)
- Validates TypeScript
-
Build API Image (~2-4 minutes)
- Watch for cache hits (faster builds)
- Look for "CACHED" vs "RUN" lines
-
Build Web Image (~4-7 minutes)
- Next.js build is slowest part
-
Container Smoke Tests (~30 seconds)
- Verifies containers can start
-
Transfer Images (~2-3 minutes)
- Uploads to VPS over SSH
- Loads images into Docker
-
Deployment Smoke Tests (~30 seconds)
- Runs 6 automated checks
Total time: 10-15 minutes (depends on cache)
⚠️ CRITICAL: Images are transferred but containers NOT restarted automatically
Step 4b: Restart Containers (1 minute)
The build script transfers images but doesn't restart containers. You must do this manually:
ssh root@23.235.204.208 << 'REMOTE'
cd /opt/sampo-alpha
# Stop old containers
docker compose -f docker-compose.base.yml \
-f docker-compose.blueline-alpha.override.yml down
# Start new containers with fresh images
docker compose -f docker-compose.base.yml \
-f docker-compose.blueline-alpha.override.yml up -d
# Wait for healthy status
sleep 15
# Verify containers started
docker ps --filter "name=blueline-alpha"
REMOTE
Expected output:
- All 3 containers:
Up X seconds (healthy) - NOT "Up X hours" (that means old containers still running!)
Step 5: Verify Deployment Version (1 minute)
Method 1: Visual Check (Fastest)
Navigate to Admin Dashboard:
https://alpha.theblueline.com/admin/dashboard
Look for the build version badge in the top-right corner:
🔖 2131d0c • 2026-02-08
Hover over it to see full details:
- Deployed date and time (UTC)
- Git commit SHA
- Full version string
If the commit SHA matches your build ✅ → Deployment succeeded!
Method 2: API Check (Programmatic)
curl -s https://alpha.theblueline.com/health | jq -r '.buildVersion'
Expected output:
20260208-175451-2131d0c
This is your deployment version - it changes with every build!
Format: YYYYMMDD-HHMMSS-GITSHA
20260208= February 8, 2026 (today)175451= 5:54:51 PM (when you built)2131d0c= Git commit (first 7 characters)
How to use it:
✅ Verify deployment worked:
# Save version from build output
BUILD_VERSION="20260208-175451-2131d0c"
# Check if it's running
RUNNING_VERSION=$(curl -s https://alpha.theblueline.com/health | jq -r '.buildVersion')
if [ "$RUNNING_VERSION" = "$BUILD_VERSION" ]; then
echo "✅ Correct version deployed!"
else
echo "❌ Wrong version! Running: $RUNNING_VERSION, Expected: $BUILD_VERSION"
fi
If version is wrong:
- ❌ Containers weren't restarted (go back to Step 4b)
- ❌ Old images cached (docker ps should show "Up X minutes", not hours)
Step 6: Verify Your Code Change (Optional)
If you added a comment in Step 1, verify it's in the compiled code:
ssh root@23.235.204.208 "docker exec blueline-alpha-api cat /app/dist/modules/health/health.controller.js | grep -i 'DEPLOYMENT TEST'"
Note: Build version check (Step 5) is faster and more reliable!
🎉 Congratulations! You just deployed to production!
Common Deployment Scenarios
Now that you've done one deployment, here are common scenarios:
Scenario 1: Deploy Code-Only Change
When: You changed TypeScript/JavaScript files only (no package.json, no schema)
Steps:
./scripts/validate-deployment-env.sh(validate environment)pnpm type-check(ensure no type errors)git status(ensure clean, committed changes)- Deploy command (above)
- Verify with smoke tests
Time: ~10 minutes (good cache)
Scenario 2: Deploy with New Dependencies
When: You updated package.json (added/removed packages)
Steps:
- Same as Scenario 1, but...
- Build will be slower (~15-20 minutes)
- Cache will miss on
pnpm installlayer - This is expected - don't worry!
Tip: Run ./scripts/analyze-build-cache.sh after to see cache impact
Scenario 3: Deploy Database Schema Change
When: You modified prisma/schema.prisma
Steps:
-
Before deploy: Create migration locally
pnpm db:migrate:dev --name descriptive_name -
Commit migration to git (critical!)
-
Deploy normally (migrations run automatically on container startup)
-
Verify migrations applied:
ssh root@23.235.204.208 'docker logs blueline-alpha-api --tail 50 | grep -i migration' -
If seeds needed:
ssh root@23.235.204.208 'docker exec blueline-alpha-api pnpm db:seed:prod'
Critical: Migrations run automatically. Seeds only if you changed seed files.
Scenario 4: Something Went Wrong (Rollback)
When: Deployment succeeded but app is broken
Steps:
-
Don't panic! We can rollback in <5 minutes
-
List available versions:
./scripts/rollback-deployment.sh root@23.235.204.208 -
Select previous version (or type "previous"):
./scripts/rollback-deployment.sh root@23.235.204.208 previous -
Verify rollback worked:
curl https://alpha.theblueline.com/health -
Investigate what went wrong (check logs, test locally)
Database safe: Rollback does NOT revert database changes (data is preserved)
Hands-On Exercises
Exercise 1: Read-Only Exploration
Goal: Get familiar with the system without deploying
# 1. View current deployment version
ssh root@23.235.204.208 'docker images | grep blueline-alpha'
# 2. Check container status
ssh root@23.235.204.208 'docker ps --filter "name=blueline-alpha"'
# 3. View recent logs
ssh root@23.235.204.208 'docker logs blueline-alpha-api --tail 20'
# 4. Test health endpoint
curl https://alpha.theblueline.com/health | jq
# 5. Check build cache history
./scripts/analyze-build-cache.sh
Exercise 2: Dry-Run Practice
Goal: Practice using dry-run mode before real deployments
# 1. Make a trivial change (add a comment somewhere)
# 2. Run dry-run
./scripts/docker-audit/build-cross-platform.sh --all --amd64 \
--api-url https://alpha.theblueline.com/api \
--push root@23.235.204.208 \
--dry-run
# 3. Read the output carefully
# - What version tag would be created?
# - What's the estimated transfer size?
# - What deployment steps would run?
# 4. Revert your change (git checkout or undo)
Exercise 3: Cache Performance Analysis
Goal: Understand how cache affects build time
# 1. Build locally (should be fast with cache)
./scripts/docker-audit/build-cross-platform.sh --api --local
# 2. Check cache performance
./scripts/analyze-build-cache.sh --detailed
# 3. Make a code-only change (add comment to any file)
# 4. Build again
./scripts/docker-audit/build-cross-platform.sh --api --local
# 5. Compare cache performance (should be similar or better)
./scripts/analyze-build-cache.sh --detailed
# Questions to answer:
# - What was the cache hit rate?
# - How much time was saved?
# - What layers were rebuilt?
Troubleshooting Your First Deployment
Problem: "Environment validation failed"
Symptom: ./scripts/validate-deployment-env.sh shows errors
Solution:
- Check which variables are missing (read error output)
- Copy
.env.blueline-alpha.exampleto.env.blueline-alpha(if it doesn't exist) - Ask team for production values (don't guess!)
- Re-run validation
Problem: "Type check failed"
Symptom: pnpm type-check shows TypeScript errors
Solution:
- Read error messages carefully
- Fix your code changes
- OR pull latest from main (if errors aren't from you)
- Re-run type-check
Problem: "Build fails during pnpm install"
Symptom: Docker build fails with npm/pnpm error
Solution:
- Check if
pnpm-lock.yamlis committed to git - Try:
pnpm installlocally (does it work?) - If local works but Docker fails: Rebuild without cache
docker builder prune -a ./scripts/docker-audit/build-cross-platform.sh --api --local
Problem: "Container smoke tests fail"
Symptom: Build succeeds but container won't start
Solution:
- Check logs:
docker logs <container-name> - Common causes:
- Missing environment variable
- Database connection failed
- Port already in use
- See Deployment Troubleshooting for detailed guide
Problem: "Transfer to VPS times out"
Symptom: SSH transfer hangs or fails
Solution:
- Check VPS is reachable:
ssh root@23.235.204.208 'echo ok' - Check VPS disk space:
ssh root@23.235.204.208 'df -h' - If disk full: Clean old images
ssh root@23.235.204.208 'docker system prune -a -f'
Best Practices (Learn These!)
1. Always Validate Before Deploy
DO:
./scripts/validate-deployment-env.sh # Check env vars
pnpm type-check # Check types
git status # Check working directory clean
DON'T:
- Skip validation (causes 20% of failures)
- Deploy with uncommitted changes
- Deploy without testing locally first
2. Use Dry-Run for Risky Changes
DO:
# Before deploying major changes:
./scripts/docker-audit/build-cross-platform.sh ... --dry-run
# Review output, then deploy for real
DON'T:
- Skip dry-run for database migrations
- Skip dry-run for dependency updates
- Skip dry-run if you're uncertain
3. Monitor Build Cache Performance
DO:
# After each deploy, check cache:
./scripts/analyze-build-cache.sh
# If cache <70%, investigate why
DON'T:
- Ignore slow builds (they indicate problems)
- Prune cache unless necessary
- Change Dockerfile without understanding cache impact
4. Keep Version History
DO:
- Let system tag images automatically
- Keep last 10 versions on VPS
- Use version tags for rollback
DON'T:
- Manually delete images (unless disk full)
- Use
:latesttag for rollback (not specific enough)
5. Document Your Deployments
DO: After each deployment, note:
- Date/time
- Version tag
- What changed
- Any issues encountered
DON'T:
- Deploy without team communication
- Deploy during peak hours (unless urgent)
- Deploy on Friday afternoons (risky!)
Deployment Checklist (Print This!)
Pre-Deployment
- [ ] Changes committed to git
- [ ] Working directory clean (
git status) - [ ] Environment validated (
./scripts/validate-deployment-env.sh) - [ ] Types checked (
pnpm type-check) - [ ] Tests passing (
pnpm test) - [ ] Dry-run reviewed (if risky change)
During Deployment
- [ ] Watch build output for errors
- [ ] Note version tag created
- [ ] Verify container smoke tests pass
- [ ] Verify deployment smoke tests pass
Post-Deployment
- [ ] Health check returns 200 (
curl https://alpha.theblueline.com/health) - [ ] Web loads (
curl https://alpha.theblueline.com) - [ ] Logs look normal (
docker logs blueline-alpha-api --tail 50) - [ ] Cache performance acceptable (
./scripts/analyze-build-cache.sh) - [ ] Document deployment (version, changes, issues)
If Problems
- [ ] Check logs first (
docker logs ...) - [ ] Try rollback if critical (
./scripts/rollback-deployment.sh) - [ ] Ask team for help (don't struggle alone)
- [ ] Document issue for future reference
Next Steps
Now that you've completed your first deployment:
-
Read the full guides:
- Deployment Overview - Complete system features
- Troubleshooting Guide - Detailed issue resolution
- Build Optimization - Performance tuning
-
Practice on staging:
- Ask team about staging environment
- Deploy test changes there first
- Get comfortable with the workflow
-
Learn the advanced features:
- Rollback to specific versions
- Cache analytics and optimization
- Database migration workflows
-
Join deployment reviews:
- Shadow experienced team members
- Ask questions during their deployments
- Learn from their techniques
Getting Help
Stuck? Here's how to get help:
-
Check documentation first:
- Search help center for your error message
- Read troubleshooting guide
- Check this quick start guide
-
Check logs:
- Build logs (in terminal)
- Container logs (
docker logs ...) - Application logs (in admin UI)
-
Ask the team:
- Post in #deployments channel
- Include: What you tried, error message, version tag
- Share logs if relevant
-
Emergency (production down):
- Rollback immediately (
./scripts/rollback-deployment.sh) - Then investigate root cause
- Document for post-mortem
- Rollback immediately (
Quick Reference
Most Common Commands
# Validate before deploy
./scripts/validate-deployment-env.sh
# Type check
pnpm type-check
# Dry-run (preview)
./scripts/docker-audit/build-cross-platform.sh --all --amd64 \
--api-url https://alpha.theblueline.com/api \
--push root@23.235.204.208 \
--dry-run
# Deploy for real
./scripts/docker-audit/build-cross-platform.sh --all --amd64 \
--api-url https://alpha.theblueline.com/api \
--push root@23.235.204.208 \
--smoke-tests
# Rollback
./scripts/rollback-deployment.sh root@23.235.204.208 previous
# Check cache
./scripts/analyze-build-cache.sh
# View logs
ssh root@23.235.204.208 'docker logs blueline-alpha-api --tail 50'
# Health check
curl https://alpha.theblueline.com/health
Key Files
- Environment:
.env.blueline-alpha - Build script:
scripts/docker-audit/build-cross-platform.sh - Validation:
scripts/validate-deployment-env.sh - Rollback:
scripts/rollback-deployment.sh - Cache analytics:
scripts/analyze-build-cache.sh
VPS Details
- Host: root@23.235.204.208
- Path: /opt/sampo-alpha
- API Port: 3003 (internal), 443 (public HTTPS)
- Web Port: 3006 (internal), 443 (public HTTPS)
- Database Port: 5436 (internal only)
Related Articles
Next Steps After This Tutorial
- 📘 Deployment Overview - Complete system features and capabilities
- 🔧 Troubleshooting Guide - What to do when things go wrong
- ⚡ Build Optimization - Speed up your deployments
Advanced Topics
- 📄 Deployment runbook:
docs/operations/deployment-runbook.md - 📊 Implementation history:
docs/operations/week2-week3-implementation-summary.md - 🔍 Quick reference:
docs/operations/docker-deployment-quick-reference.md
Feedback? Found this guide helpful or confusing? Let the DevOps team know how we can improve it!