Project Deployment and Launch — From Development to Production
Launching a product is like launching a rocket—the first 24 lessons cover design and manufacturing, and this lesson is about the countdown and launch. There's a long checklist before launch, and you can't ignite the engines until every item is checked off. Launching without a checklist is a gamble.
1. What You'll Learn
- Production Environment Checklist: Three-Dimensional Assessment of Security, Performance, and Monitoring
- Staged Rollout Strategies: Implementation Approaches for Blue-Green Deployment and Canary Deployment
- Database Migration Security: Alembic Best Practices for Zero-Downtime Migration
- Log Aggregation: Structured Logs + ELK / Loki Integration
- Alice: The Final Chapter—PriceTracker Officially Launches
2. Alice's True Story
(1) Pain Point: Frequent Incidents During Deployment
PriceTracker experienced issues during its first two deployments: the first time, they forgot to configure HTTPS; the second time, a table lock during a database migration caused a 10-minute service outage; and the third time, logs weren't aggregated, so after a problem arose, Charlie spent two hours sifting through logs on five servers. Alice needs a systematic deployment process to ensure that every deployment is safe and controllable.
(2) Solution for the Deployment Checklist
Deployment isn't just a matter of "pushing the code up and calling it a day"; it's a series of checklists: security hardening, performance validation, migration strategy, staged rollout, and monitoring verification—you can only move on to the next step after checking off each one.
(3) Revenue
Third deployment: All items on the checklist were checked off; HTTPS was configured; the migration was completed with zero downtime; a rolling release was initiated by first routing 10% of traffic for validation; and logs were automatically aggregated to Loki—the entire deployment process went off without a hitch, and Charlie's monitoring dashboard remained in the green the whole time.
3. Production Environment Checklist
(1) Launch Process
flowchart TD
A[Code Freeze] --> B[Security Audit]
B --> C[Load Test]
C --> D[Staging Deploy]
D --> E[Smoke Test]
E --> F[Canary Release 10%]
F --> G{Metrics OK?}
G -->|Yes| H[Full Rollout 100%]
G -->|No| I[Rollback]
I --> J[Investigate]
J --> A
H --> K[Monitor 1h]
K --> L[✓ Live]
(2) Three-Dimensional Checklist
| Dimension | Check Item | Status |
|---|---|---|
| Security | HTTPS Certificate Configuration | ☐ |
| CORS allows only production domains | ☐ | |
| Rate Limiting Enabled | ☐ | |
| JWT SECRET_KEY has been changed | ☐ | |
| No hard-coded keys | ☐ | |
| Security scan passed | ☐ | |
| Performance | Uvicorn Workers ≥ 4 | ☐ |
| Appropriate DB connection pool size | ☐ | |
| Redis Caching Enabled | ☐ | |
| GZip compression enabled | ☐ | |
| Load test passed (target QPS) | ☐ | |
| Monitoring | /health endpoint is normal | ☐ |
| Prometheus Metrics Collection | ☐ | |
| Grafana Dashboard Ready | ☐ | |
| Alert Rule Configuration | ☐ | |
| Log Aggregation Running | ☐ |
4. Staged Rollout Strategy
(1) Blue-Green Deployment
flowchart LR
LB[Load Balancer] -->|100% traffic| Blue[Blue v1]
subgraph Deploy
Green[Green v2]
end
LB -.->|Switch| Green
style Blue fill:#4caf50
style Green fill:#2196f3
| Step | Action | Rollback |
|---|---|---|
| 1 | Deploy the Green (v2) environment | - |
| 2 | Run smoke tests in Green | - |
| 3 | LB Switch to Green | Switch back to Blue |
| 4 | Monitor Green for 30 minutes | Switch back to Blue |
| 5 | Stability confirmed, Blue taken offline | - |
(1) ▶ Example: Nginx Blue-Green Configuration
# nginx/conf.d/pricetracker.conf
upstream pricetracker_blue {
server api-blue:8000;
}
upstream pricetracker_green {
server api-green:8000;
}
# Currently serving Blue
server {
listen 80;
server_name api.pricetracker.example.com;
location / {
proxy_pass http://pricetracker_blue;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
# Switch to Green by changing proxy_pass target
# Then: docker compose -f docker-compose.green.yml up -d
Output:
// Execution Successful
(2) Canary Release
| Strategy | Traffic Distribution | Observation Period | Rollback |
|---|---|---|---|
| 10% | 1 v2 + 9 v1 | 15 min | Switch back to v1 |
| 30% | 3 v2 + 7 v1 | 15 min | Switch back to v1 |
| 50% | 5 v2 + 5 v1 | 15 min | Switch back to v1 |
| 100% | All v2 | 30 min | Rollback image version |
5. Zero-Downtime Database Migration
(1) Principles of Secure Migration
| Principle | Description | Example |
|---|---|---|
| Add Only, Do Not Delete | Add a new column first; do not delete the old column | ALTER TABLE ADD COLUMN new_col |
| Dual-write compatibility | Both new and old code work | New code writes to two columns; old code reads only the old column |
| Delayed Cleanup | Delete old columns only after stability is confirmed | Delete old columns 7 days after deploying v2 |
| Incremental Migration | Change only one thing at a time | Don't add columns or change data types in a single migration |
(1) ▶ Example: Safe Column Addition Migration
# alembic/versions/xxx_add_wholesale_price.py
"""Add wholesale_price column to products
Safe migration: ADD COLUMN is non-blocking in PostgreSQL
"""
def upgrade():
op.add_column(
"products",
sa.Column("wholesale_price", sa.Float(), nullable=True),
)
# Set default for existing rows (separate statement for performance)
op.execute("UPDATE products SET wholesale_price = base_price * 0.6 WHERE wholesale_price IS NULL")
# Make non-nullable in next migration after code deployed
def downgrade():
op.drop_column("products", "wholesale_price")
Output:
# Function defined successfully
(2) Risky Migration vs. Safe Migration
| Migration Type | Security | Risk of Table Locking | Recommendations |
|---|---|---|---|
| ADD COLUMN | Security | None | Can be executed online |
| CREATE INDEX | Relatively safe | Possible | Use CREATE INDEX CONCURRENTLY |
| DROP COLUMN | Risk | Yes | Make sure the code no longer uses it first |
| ALTER COLUMN TYPE | Risk | High | Phased migration (add new column → migrate data → delete old column) |
| RENAME COLUMN | Danger | Medium | Rename after enabling dual-write compatibility |
6. Log Aggregation
(1) Structured Logs
(1) ▶ Example: Structured Log Configuration
# app/core/logging.py
import logging
import json
from datetime import datetime
class JSONFormatter(logging.Formatter):
def format(self, record):
log_entry = {
"timestamp": datetime.utcnow().isoformat(),
"level": record.levelname,
"message": record.getMessage(),
"module": record.module,
"function": record.funcName,
"line": record.lineno,
}
# Add request context if available
if hasattr(record, "request_id"):
log_entry["request_id"] = record.request_id
if hasattr(record, "user_id"):
log_entry["user_id"] = record.user_id
return json.dumps(log_entry)
# Configure logging
logger = logging.getLogger("pricetracker")
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)
Output:
# Function defined successfully
(2) Comparison of Log Aggregation Solutions
| Solution | Advantages | Disadvantages | Recommended Scenarios |
|---|---|---|---|
| ELK (Elasticsearch + Logstash + Kibana) | Comprehensive features, powerful search capabilities | High resource consumption | Large-scale projects |
| Loki+Grafana+Promtail | Lightweight, integrated with Grafana | Limited search capabilities | Small to medium-sized projects |
| CloudWatch Logs | Zero-Maintenance | AWS Lockdown | AWS Deployment |
(2) ▶ Example: Adding Loki to Docker Compose
# Add to docker-compose.yml
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
volumes:
- loki_data:/loki
promtail:
image: grafana/promtail:latest
volumes:
- /var/log:/var/log:ro
- ./docker/promtail.yml:/etc/promtail/config.yml
depends_on:
- loki
Output:
CONTAINER ID IMAGE STATUS PORTS
abc123 nginx:latest Up 2 hours 0.0.0.0:80->80/tcp
7. PriceTracker Officially Launches
(1) Project Completion Milestones
gantt
title PriceTracker Development Timeline
dateFormat YYYY-MM-DD
section Phase 1
FastAPI Intro :p1a, 2026-01-01, 1d
Installation & UV :p1b, after p1a, 1d
Path & Query Params :p1c, after p1b, 1d
Request Body & Pydantic :p1d, after p1c, 1d
Response Models :p1e, after p1d, 1d
Phase 1 Capstone :p1f, after p1e, 2d
section Phase 2
Middleware :p2a, after p1f, 1d
Dependency Injection :p2b, after p2a, 1d
Database SQLAlchemy :p2c, after p2b, 2d
CRUD Operations :p2d, after p2c, 1d
Authentication JWT :p2e, after p2d, 2d
Phase 2 Capstone :p2f, after p2e, 2d
section Phase 3
WebSocket :p3a, after p2f, 1d
Celery :p3b, after p3a, 2d
File Upload :p3c, after p3b, 1d
Testing :p3d, after p3c, 1d
Caching :p3e, after p3d, 1d
OpenAPI :p3f, after p3e, 1d
section Phase 4
Docker :p4a, after p3f, 1d
Performance :p4b, after p4a, 1d
Monitoring :p4c, after p4b, 1d
CI/CD :p4d, after p4c, 1d
section Phase 5
Project Design :p5a, after p4d, 1d
Project Development :p5b, after p5a, 2d
Project Deployment :p5c, after p5b, 1d
(2) Deployment Verification Checklist
| Verification Item | Verification Method | Passing Criteria |
|---|---|---|
| API Availability | curl /health |
{"status": "healthy"} |
| Front-end Integration | Bob Calls the API from the Front End | All Endpoints Are Working Properly |
| Authentication | JWT Login + Protected Endpoints | Login successful; returns 401 if not authenticated |
| Permission | Free/Pro/Enterprise Rate Limiting | Correctly limited according to the plan |
| WebSocket | Connection + Price Feeds | Receive Real-Time Updates |
| Cache | Cache Hit Rate for Popular Products | > 80% |
| Monitoring | Grafana Dashboard | Metrics Displayed Normally |
| Alert | P99 Simulation Spike | Alert Trigger Notification |
| Logs | Query Loki | Searchable Structured Logs |
| CI/CD | Deployment triggered by tag push | Automatic deployment successful |
❓ FAQ
weight parameter (server v2:8000 weight=1; server v1:8000 weight=9;), while K8s uses the canary Deployment to adjust the number of replicas.CREATE INDEX CONCURRENTLY (to create indexes without locking tables) and avoid executing DDL statements during peak hours. Migrate large tables in batches.📖 Summary
- Three Dimensions of the Deployment Checklist: Security (HTTPS/CORS/RateLimit), Performance (Workers/Connection Pool/Caching), Monitoring (Metrics/Alerts/Logs)
- Blue-Green Deployment: Switching between two environments with rollbacks in seconds; Canary Deployment: Gradual scaling—10% → 30% → 50% → 100%
- Zero-Downtime Migration Principles: Add Only, Never Delete; Dual-Write Compatibility; Deferred Cleanup; Incremental Migration
- Structured JSON logs + Loki/Grafana aggregation, with requests tracked by
request_id - PriceTracker Officially Launched: Bob's front-end integration was successful, Charlie's monitoring system is giving the green light, and millions of price data points are flowing steadily.
📝 Exercises
- Basic Exercise (Difficulty: ⭐): Create a PriceTracker deployment checklist (5 items each for security, performance, and monitoring) and use it to verify your deployment environment item by item. Hint: Refer to the checklist table in this article.
- Advanced Problem (Difficulty ⭐⭐): Implement structured JSON logging (including timestamp, level, message, and request_id); add a logging middleware to inject the request_id into each request; and configure Docker Compose and Loki to aggregate the logs. Hint: JSONFormatter +
logging.getLogger("pricetracker") - Challenge (Difficulty: ⭐⭐⭐): Complete deployment process—write a safe migration script (follow the "add-only, no-delete" principle), configure Nginx blue-green deployment, set up Grafana alert rules (P99 > 500 ms + error rate > 5%), and perform canary release verification (first route 10% of traffic to v2, then fully switch over). Hint:
CREATE INDEX CONCURRENTLY+ Nginx upstream switching



