惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

N
Netflix TechBlog - Medium
罗磊的独立博客
云风的 BLOG
云风的 BLOG
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
小众软件
小众软件
Blog — PlanetScale
Blog — PlanetScale
T
The Blog of Author Tim Ferriss
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
月光博客
月光博客
博客园 - Franky
F
Fortinet All Blogs
D
Docker
博客园 - 司徒正美
腾讯CDC
Recent Announcements
Recent Announcements
The Cloudflare Blog
B
Blog RSS Feed
GbyAI
GbyAI
T
Tailwind CSS Blog
雷峰网
雷峰网
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
博客园 - 三生石上(FineUI控件)
阮一峰的网络日志
阮一峰的网络日志

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
🚀 jenkins pipeline for django — common mistakes and how t...
Python-T Poi · 2026-05-02 · via DEV Community

“Automation doesn’t eliminate work — it eliminates stupid work.”

I remember the time I broke a production deploy because I forgot to run migrate. Not collectstatic — that would’ve been bad enough. No. I let new models hit the DB while the old code was still live. Stack trace had something like django.core.exceptions.FieldError: Unknown field 'updated_at'. 2 AM. Cold chai. A hotel chain losing bookings by the minute. Yeah, I learned this the hard way.

Look — we’ve all been there. At that point, I was doing Friday night deploys like some kind of cursed ritual. git push, ssh in, source venv, python manage.py test — fingers crossed. Then collectstatic, then restart gunicorn, then pray nginx doesn’t throw 502s.

Spoiler: it usually did.

And then I set up my first jenkins pipeline for django. Not glamorous. Not fancy. But it worked. Like, actually worked. No more all-nighters. No more “did I forget something?” panic.

Now? Deploys are quieter than my Sunday mornings with filter coffee. Routine. Predictable. Boring — in the best way.

Let’s talk about how you can get there too.


jenkins pipeline for django

🚀 Prerequisites — What You Need

Here’s the thing — Jenkins won’t fix a messy project. If your Django settings are hardcoded, if you’re committing secrets.py, if your requirements.txt is out of date… stop. Fix that first.

Trust me, I’ve seen pipelines fail because someone used pip freeze > reqs.txt in 2019 and never touched it again.

So — before Jenkins, get your ducks in a row:

  • A Django app on GitHub or another Git provider
  • An EC2 instance running Ubuntu (or Amazon Linux)
  • Jenkins installed and running on that instance
  • Basic CI/CD understanding — stages, agents, scripts
  • Python , pip , and virtualenv set up on the Jenkins server

And — this one’s critical — your Django settings must be environment-aware. I use django-environ now. Used to use python-decouple. Same idea.

# settings.py
from decouple import config

SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)

Enter fullscreen mode Exit fullscreen mode

Why? Because Jenkins is going to inject those values at runtime. If your app crashes when DEBUG=False, better find out in CI than when the CEO is demoing it.

Not gonna lie — I once spent three hours debugging why tests passed locally but failed on Jenkins. Turns out, DEBUG=True was hiding a missing STATIC_ROOT. Duh.


🔧 Jenkins Setup — Getting the Pieces Together

Alright. Ubuntu box. SSH access. Let’s install Jenkins.

Quick note: Jenkins needs Java. I know. (Java. In 2024. sigh) But it is what it is.

sudo apt update
sudo apt install openjdk-11-jdk -y
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
sudo apt update
sudo apt install jenkins -y
sudo systemctl enable jenkins
sudo systemctl start jenkins

Enter fullscreen mode Exit fullscreen mode

Now go to http://your-ec2-public-ip:8080. Initial setup. Admin password from /var/lib/jenkins/secrets/initialAdminPassword. You know the drill.

But — don’t skip the plugins. You’ll want:

  • Pipeline
  • Git
  • Blue Ocean (optional, but nicer UI)
  • Amazon ECR (if using Docker later)

Oh, and this one burned me once — the jenkins user needs write access to /tmp. And to .ssh. And to the internet. Sounds obvious, right?

So I once spent two hours debugging why pip install was failing. Turns out Jenkins couldn’t write to /tmp. (Yes. Really.) Permission denied. On /tmp. I still laugh about it. (Now.)

🔐 SSH & Git Access

Jenkins needs to clone your repo. Best way? SSH keys.

Add the Jenkins user’s public key to your GitHub repo as a deploy key.

Test it:

sudo su - jenkins
ssh -T git@github.com

Enter fullscreen mode Exit fullscreen mode

If this fails — and believe me, it will if you miss one step — the entire pipeline dies. Quietly. Like a ninja. Or a passive-aggressive coworker.

And when Jenkins can’t pull code? You’re stuck. Team’s waiting. Standup’s tomorrow.

Yeah. Don’t be that guy.

🐍 Python Environment

Every build should start fresh. Always.

Use a virtual environment. Every time.

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Enter fullscreen mode Exit fullscreen mode

Shared server. Shared Python path. One rogue pip install -user — and boom. Dependency hell. Silent test failures. Mysterious import errors.

I saw a junior dev spend a day debugging a ModuleNotFoundError once — turned out another team’s pipeline installed an old version of requests globally. Nightmare.

So: isolate. Always.


pipelines — The Heart of Automation

This is where the rubber meets the road.

You’ll define your jenkins pipeline for django in a file called Jenkinsfile — right in your project root.

Groovy syntax. Not Python. Not my favorite. But it works.

Here’s a battle-tested starter:

// Jenkinsfile
pipeline {
    agent any

    environment {
        SECRET_KEY = credentials('django-secret-key')
        DEBUG = 'False'
        DB_HOST = 'prod-db.example.com'
    }

    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/yourname/your-django-app.git'
            }
        }

        stage('Setup') {
            steps {
                sh '''
                python3 -m venv venv
                source venv/bin/activate
                pip install -r requirements.txt
                '''
            }
        }

        stage('Test') {
            steps {
                sh '''
                source venv/bin/activate
                python manage.py test --settings=myapp.settings.test
                '''
            }
            post {
                always {
                    junit '**/test-reports/*.xml'
                }
            }
        }

        stage('Deploy to AWS') {
            steps {
                sh '''
                source venv/bin/activate
                python manage.py collectstatic --noinput --settings=myapp.settings.prod
                sudo systemctl restart gunicorn
                '''
            }
        }
    }

    post {
        success {
            echo "🚀 Deployed to production!"
        }
        failure {
            echo "❌ Pipeline failed. Check logs."
        }
    }
}

Enter fullscreen mode Exit fullscreen mode

Quick breakdown:

  • environment block uses Jenkins Credentials — no hardcoded secrets. Ever.
  • Test stage runs Django tests and reports back via JUnit. You can see test history in Blue Ocean. Super useful.
  • Deploy runs collectstatic and restarts Gunicorn. (Assuming you’re not using Docker.)

And yes — this assumes you’re running Gunicorn behind Nginx. It’s old-school. It’s reliable. It’s what I still use for 80% of my projects.

A junior I was mentoring asked me last week: “Why not just use GitHub Actions?” Fair question.

My answer? If you’re deep in AWS, with private VPCs, internal DBs, on-prem-ish needs — Jenkins runs on your infra. It can SSH into boxes. It can talk to internal services. GitHub Actions? Not always.

So flexibility matters.

Also — we’ve used jenkins pipeline for django like, five times now. Because it’s not just a phrase. It’s a pattern. A workflow. A peace-of-mind machine.


☁️ AWS Integration — Closing the Loop

Where are you deploying?

Let’s be real — this pipeline is useless if it doesn’t push code somewhere.

Your options:

  • EC2 with Gunicorn + Nginx (simple, full control)
  • Elastic Beanstalk (managed, easy scaling)
  • ECS/Fargate (Docker-based, modern)

For most teams I’ve worked with — especially early-stage — I'd recommend EC2. Cheaper. Easier to debug. You see the server. You can SSH. You can tail -f logs/gunicorn.log. Feels real.

But if you’re on Elastic Beanstalk, no shame. Just update your deploy step:

aws elasticbeanstalk create-deployment --application-name my-django-app --environment-name myapp-prod --version-label $BUILD_NUMBER

Enter fullscreen mode Exit fullscreen mode

Oh — and Jenkins needs AWS credentials.

Best way? Assign an IAM role to the EC2 instance. Least privilege. beanstalk:CreateDeployment, s3:PutObject — that’s it.

Worst way? Hardcoded keys in the Jenkinsfile. Please don’t. (I’ve seen it. In production. facepalm)

Pro tip: Run migrate — but after the new code is in place.

I once ran it before syncing code. Django tried to apply a migration that referenced a field not yet in the code. Database locked. Application down.

Chaos.

Lesson: ordering matters. Script it. Test it.

🔄 Automate on Every Push

Now — the fun part.

Go to Jenkins dashboard. Create a new Pipeline job. Point it to your GitHub repo.

Then — enable webhooks.

So every git push triggers the pipeline. No manual clicks. No “who forgot to run CI?” emails.

Test it:

git commit --allow-empty -m "Trigger Jenkins"
git push origin main

Enter fullscreen mode Exit fullscreen mode

If it runs — golden.

If not?

Check:

  • Webhook delivery in GitHub Settings (look for 200s)
  • Firewall rules (is port 8080 open?)
  • SSH/Git permissions (again — always the culprit)

And when it finally works?

Magic.

Not real magic. Just engineering. But it feels like magic.

Your code. Your pipeline. Your server. All in sync.

Like a well-tuned chord.


🟩 Final Thoughts

Setting up a jenkins pipeline for django isn’t about tools.

It’s about trust.

Trust that your tests catch bugs.

Trust that your deploys don’t break everything.

Trust that a junior dev won’t accidentally nuke production.

I used to be proud of how fast I could SSH into a server and fix things.

Now? I’m proud when I don’t have to.

That’s the win.

Because now, I’m not a firefighter. I’m a builder.

And honestly — the first time your pipeline blocks a bad deploy because a test failed? You’ll grin like an idiot.

You’ve leveled up.

Not because of Jenkins.

But because you stopped doing stupid work.

And that — that’s automation worth having.


❓ Frequently Asked Questions

How do I secure secrets in a Jenkins pipeline?

Use Jenkins’ built-in Credentials Store. Never, ever hardcode API keys. Inject them via the environment block using credentials('id'). They’ll be masked in logs — and you won’t leak them in a terminal screenshot. (Like I did once. Don’t ask.)

Can I use Docker with a Jenkins pipeline for Django?

Absolutely. Build your image in the pipeline, push to ECR, then deploy. Replace collectstatic with docker build and docker push. Same flow. New tools. Works great — especially on Fargate.

Why use Jenkins instead of GitHub Actions or GitLab CI?

Jenkins runs on your infrastructure. Need to access a private VPC? Internal database? Jenkins can. GitHub Actions? Sometimes not. Also — full control over workers, caching, permissions. It’s clunkier, sure. But it’s yours.