मेरे production deploys में 15 मिनट लगते हैं। मैं उन्हें देखता नहीं। साँस नहीं रोकता। चाय बनाता हूँ, और जब तक चाय तैयार होती है, नया version live हो चुका होता है।
हमेशा ऐसा नहीं था।
दो साल पहले, deploy एक पूजा-पाठ जैसा ritual था। एक घंटा block करो। Team को बताओ। Script manually चलाओ। Logs देखो। भगवान से प्रार्थना करो। जो टूटा उसे ठीक करो। फिर से चलाओ। और ज़ोर से प्रार्थना करो। पूरे process में 2-3 घंटे लगते थे और सबकी हालत खराब हो जाती थी। हम Friday को deploy करते थे क्योंकि हमें अपने आप से नफरत थी।
अगर ये सुनकर लगा "अरे, ये तो हमारी कहानी है" — तो तुम deploys systems पर नहीं, adrenaline पर चला रहे हो। March 2026 में ऐसा करने की कोई वजह नहीं है। यहाँ बताता हूँ कि मैंने 3 घंटे के anxiety festival को 15 boring minutes में कैसे बदला। ⚙️
Problem: किसी के दिमाग में ग्यारह steps
Deploy — यानी अपने code को अपने computer से उस server पर पहुँचाना जहाँ users actually उसे देखते हैं — इसमें एक साथ 11 अलग-अलग काम होते थे। Code pull करो। Dependencies install करो (external libraries जो तुम्हारी app को चाहिए)। Migrations चलाओ (database structure को नए code के हिसाब से update करो)। Assets build करो। Service restart करो। Cache clear करो। Reverse proxy update करो। Health endpoint check करो।
ये सब एक wiki page पर लिखा था जो 40% outdated था। नए team members डरे हुए रहते थे। Senior लोग बस थके हुए थे।
Fix कोई fancy tool नहीं था। Discipline था।
Step 1: एक script, एक command
मैंने एक bash script लिखी — एक छोटा program जो commands को एक के बाद एक चलाता है, जैसे कोई recipe जिसे computer line by line follow करता है। नाम रखा deploy.sh। ये सारे 11 काम sequence में करती है। कोई भी step fail हो, तो पूरा process रुक जाता है और बताता है कौन सा step टूटा और क्यों।
#!/bin/bash
set -euo pipefail
APP=$1
DEPLOY_LOG="/var/log/deploys/${APP}-$(date +%Y%m%d-%H%M%S).log"
echo "Deploying ${APP}..." | tee "$DEPLOY_LOG"
# हर step: नाम, command, rollback
deploy_step "Pull code" "git -C /srv/${APP} pull origin main"
deploy_step "Install deps" "cd /srv/${APP} && pip install -r requirements.txt"
deploy_step "Run migrations" "cd /srv/${APP} && python manage.py migrate"
deploy_step "Build assets" "cd /srv/${APP} && npm run build"
deploy_step "Restart service" "systemctl restart ${APP}"
deploy_step "Health check" "curl -sf http://localhost:8080/health"
echo "Deploy complete: ${APP}" | tee -a "$DEPLOY_LOG"
deploy_step function हर command को logging, timing, और error handling के साथ wrap करता है। अगर health check fail हो, तो automatically पिछला version restart हो जाता है — rollback, मतलब "undo करो और जो काम कर रहा था उस पर वापस जाओ।"
Setup time: 45 मिनट। उन 45 मिनटों ने तब से सैकड़ों घंटे बचाए हैं। मूल idea Twelve-Factor App methodology से आता है — एक codebase, एक build, एक deploy command।
Step 2: CI/CD — वो robot जो तुम्हारे लिए deploy करता है
CI/CD का मतलब है Continuous Integration / Continuous Deployment। सीधी भाषा में: एक system जो automatically तुम्हारे code को test करता है जब तुम changes push करते हो (ये CI part है), और अगर tests pass हो जाएँ, तो automatically server पर deploy कर देता है (ये CD part है)। तुम code push करो, robot बाकी सँभाल लेता है।
छोटी team के लिए, Jenkins (एक heavyweight automation server), ArgoCD (Kubernetes deployment tool), या Kubernetes cluster (container orchestration system — अगर ये शब्द समझ नहीं आए, अच्छा है, तुम्हें इसकी ज़रूरत नहीं) की ज़रूरत नहीं। बस GitHub Actions और SSH access वाला एक server चाहिए। GitHub Actions 2019 में launch हुआ और अब GitHub पर काम करने वाली teams के लिए default CI/CD choice बन चुका है — stable, well-documented, और छोटे workloads के लिए free।
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pip install -r requirements.txt
- run: pytest --tb=short
deploy:
needs: test
runs-on: ubuntu-latest
if: success()
steps:
- name: Deploy to production
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: deploy
key: ${{ secrets.SSH_KEY }}
script: bash /srv/myapp/deploy.sh myapp
बस यही है पूरी pipeline — automated steps का sequence जिसमें code तुम्हारे laptop से production तक पहुँचता है। main पर push करो (code की primary branch)। Tests GitHub के servers पर चलते हैं। Pass हों, तो GitHub SSH (secure remote connection protocol) से तुम्हारे server पर connect होकर deploy.sh चलाता है।
No containers। No orchestrators। No 200-line YAML files। GitHub Actions का free tier महीने में 2,000 minutes देता है — दिन में 2-3 बार deploy करने वाली छोटी team के लिए काफी से ज़्यादा।
Step 3: Health check जो सच में health check करे
ज़्यादातर health checks बस एक /health URL होता है जो {"status": "ok"} return करता है। इससे पता चलता है कि web server चल रहा है। इससे ये पता नहीं चलता कि app actually काम कर रही है या नहीं। ये ऐसा है जैसे किसी से पूछो "ज़िंदा हो?" जबकि पूछना चाहिए "देख सकते हो, सुन सकते हो, हाथ-पैर हिला सकते हो?"
मेरे health checks तीन चीज़ें verify करते हैं:
@app.get("/health")
async def health():
checks = {
"database": await check_db_connection(),
"cache": await check_redis_ping(),
"disk": check_disk_space_above(20), # percent
}
all_ok = all(checks.values())
return JSONResponse(
status_code=200 if all_ok else 503,
content={"status": "healthy" if all_ok else "degraded", "checks": checks}
)
Database down? Health check fail। Redis (in-memory cache — एक fast temporary storage layer) unreachable? Fail। Disk 95% भरी? Fail। Deploy script restart के बाद इस endpoint को call करती है। अगर 503 आए (HTTP status code — "service unavailable"), तो deploy automatically roll back हो जाता है।
इस एक endpoint ने deploy के बाद की ज़्यादा problems पकड़ी हैं जितनी हमारी सारी manual testing ने मिलाकर नहीं पकड़ीं। ⚙️
Step 4: Notifications, dashboards नहीं
मैं monitoring dashboards के सामने बैठकर नहीं देखता। Deploy script बस दो messages भेजती है:
- Deploy शुरू — "Deploying myapp at 14:32. Triggered by commit abc123."
- Deploy खत्म — "myapp deployed in 14m 22s" या "myapp deploy FAILED at step: health check. Rolled back."
ये Telegram channel पर आते हैं। Failure notification दिखे, तो investigate करो। Success दिखे, तो चाय की चुस्की लो।
No Grafana (popular dashboard tool)। No PagerDuty (alerting service जो रात 3 बजे जगाती है)। छोटी team जो 2-3 services चला रही है, उसके लिए Telegram message सही level की complexity है। Complexity problem के size से match होनी चाहिए, ambition के size से नहीं। 🫶
Step 5: Monday सुबह deploy करो
हमने Friday को deploy करना बंद कर दिया। अब Monday और Wednesday सुबह deploy करते हैं।
क्यों? क्योंकि अगर Monday को कुछ टूटे, तो पाँच दिन हैं fresh दिमाग से ठीक करने के लिए। Friday deploy मतलब weekend debugging। Weekend debugging मतलब burnout। Burnout मतलब गलतियाँ। गलतियाँ मतलब और weekend debugging।
ये negative feedback loop है — एक cycle जिसमें हर बुरा result अगले बुरे result की वजह बनता है। ये deployment strategy नहीं है।
Boring deploy schedule: Monday और Wednesday सुबह। 3 PM के बाद कुछ नहीं। Friday को कुछ नहीं। Lunch में कुछ नहीं। अगर Monday की window के लिए ready नहीं है, तो wait करो। Wait करना सस्ता है। Burnout महँगा है।
क्या छोड़ रहे हो
ईमानदारी का वक्त। इस setup में tradeoffs हैं।
Zero-downtime deploys नहीं। जब systemctl restart चलता है, तो 2-5 second का gap आता है जब app unavailable होती है। Millions of requests handle करने वाली service के लिए ये matter करता है। ज़्यादातर छोटी teams के लिए, किसी को पता भी नहीं चलता। अगर इससे आगे बढ़ना हो, तो blue-green deployments देखो (app की दो copies चलाओ और traffic उनके बीच switch करो) — लेकिन शुरुआत वहाँ से मत करो।
Single server, single point of failure। Server मरा, तो सब मरा। Redundancy में पैसा लगता है। $10K monthly revenue से कम वाले ज़्यादातर projects के लिए, daily backups वाला एक अच्छे से maintained server सही जवाब है। Scale की problems अच्छी problems हैं।
No containerization। Docker (एक tool जो तुम्हारी app को उसकी सारी dependencies के साथ एक isolated unit में package करता है) complex environments के लिए बढ़िया है। एक server पर Python app, database, और Redis के लिए ये overhead है। बाद में add कर लेना।
Google की DORA metrics research बताती है कि elite teams on-demand deploy करती हैं, lead time एक घंटे से कम। लेकिन ये भी बताती है कि वहाँ तुम incrementally पहुँचते हो — सारे tools एक साथ adopt करके नहीं।
Result
पहले: 3 घंटे के deploys, हफ्ते में 1-2 बार, 3 लोगों की team blocked। बाद में: 15 मिनट के deploys, हफ्ते में 2-3 बार, कोई देख नहीं रहा।
Monthly time saved: team का करीब 24 घंटे collective time। CI/CD setup की annual cost: $0 (GitHub Actions free tier + एक bash script)। Setup time: एक weekend।
Boring बनाओ
अच्छे ops का goal deploys को exciting बनाना नहीं है। Goal ये है कि deploys इतने boring हो जाएँ कि तुम भूल जाओ कि हुए भी थे।
जब बिना adrenaline के deploy करते हो, तो ज़्यादा बार deploy करते हो। जब ज़्यादा बार deploy करते हो, तो हर deploy छोटा होता है। जब हर deploy छोटा होता है, तो कम चीज़ें टूटती हैं। जब कम चीज़ें टूटती हैं, तो नींद अच्छी आती है।
बस यही philosophy है। एक script। एक pipeline। एक health check। एक notification channel। हफ्ते में एक शांत सुबह।
Boring बनाओ। छोटा बनाओ। Automatic बनाओ। जाओ चाय बनाओ। 🫶





