Deploying Web Applications with Confidence
From local development to production with automated pipelines and zero-downtime strategies
Deployment Should Not Be Scary
If deploying to production makes you nervous, something is wrong with your process. A well-designed deployment pipeline should be routine, automated, and reversible. The goal is to make deployments so boring that you can do them any time, multiple times a day, without drama.
The path from "it works on my machine" to "it works in production" should be paved with automation, testing, and guardrails that catch problems before they reach users.
Environment Configuration
Never hardcode configuration values. Use environment variables for everything that changes between environments: database credentials, API keys, feature flags, and service URLs. The same application code should run in development, staging, and production with only environment differences.
# .env (never commit this file)
APP_ENV=production
APP_DEBUG=false
DB_HOST=127.0.0.1
DB_DATABASE=myapp
DB_USERNAME=myapp_user
DB_PASSWORD=secure-password-here
MAIL_MAILER=smtp
MAIL_HOST=smtp.provider.com
Use a .env.example file (committed to the repo) that documents every environment variable without sensitive values. This serves as documentation for what the application needs to run.
CI/CD Pipeline
A continuous integration and deployment pipeline automates the journey from code commit to production. A typical pipeline includes:
- Code quality checks — Linting, type checking, and code style enforcement
- Automated tests — Unit, integration, and end-to-end tests
- Build — Compile assets, generate optimized bundles
- Deploy to staging — Automatically deploy to a staging environment that mirrors production
- Deploy to production — After approval or automatically if all checks pass
Every commit triggers the pipeline. If any step fails, the deployment stops. This ensures that broken code never reaches production, regardless of how urgent the change seems.
Deployment Strategies
For most web applications, a simple strategy works well: pull the latest code, install dependencies, run migrations, build assets, clear caches, and verify the application responds correctly. Automate this into a single command.
For applications with zero-downtime requirements:
- Rolling deployments — Update servers one at a time while others continue serving traffic
- Blue-green deployments — Run two identical environments, deploy to the inactive one, then switch traffic
- Canary deployments — Route a small percentage of traffic to the new version, monitor for issues, then gradually increase
Database Migrations in Production
Database migrations require extra care in production. Run migrations before deploying new code when adding columns or tables, and after deploying when removing columns. Never rename or drop columns in a single deployment — add the new column first, deploy code that writes to both, migrate data, deploy code that reads from the new column, then drop the old one.
Always back up your database before running migrations. Test migrations against a copy of production data in staging to catch issues with data volume, constraints, and edge cases that don't exist in your development database.
Rollback Strategy
Every deployment should have a rollback plan. Keep previous versions available so you can revert quickly. For code, this is as simple as deploying a previous Git commit. For databases, this is more complex — maintain backward-compatible migrations and have database backup restoration procedures documented and tested.
When a deployment goes wrong, roll back first, investigate second. The priority is restoring service, not debugging the issue. A clean rollback gives you the breathing room to investigate without the pressure of an ongoing outage.
Post-Deployment Monitoring
Deployment doesn't end when the code is live. Monitor your application for errors, performance degradation, and unusual behavior in the minutes and hours after deployment. Set up alerts for error rate spikes, response time increases, and health check failures. The sooner you detect a problem, the faster you can respond — whether that means a quick fix or a rollback.
Share this post: