5.4Deployment & CI/CD (GitHub Actions, cloud)
The essentials in 30 seconds
- Guardian CI: on every push, checkout → install → ruff + pytest — red blocks, green authorises.
- Ship versioned: Docker image to the registry or a platform connected to the repo — every release is traceable.
- Sober prod: secrets out of YAML, logs and /health, tested rollback — deploying means being able to come back.
Running mini-case — Nabil goes live from Algiers
Nabil's containerised analysis runs well — but only on the team's machines in Algiers. He puts it online: a connected Git repo, a GitHub Actions workflow running ruff and pytest on every push, a versioned image delivered to a platform connected to the repo, logs and a health endpoint in place. Final episode of cases 5.1-5.3 — Nabil closes the loop from pro code to a living app.
Final episode of cases 5.1-5.3 — Nabil closes design, async and Docker with going to production.
1. CI: testing on every push
The GitHub Actions workflow is the guardian: checkout → install Python → pip install -r requirements → ruff + pytest. Every push is proven in minutes: red blocks the merge, green authorises. CI is not an option to “add later” — it is in place from the very first test. Nabil deliberately triggers a failure to see the alert: the day it really breaks, he will know how to read the red.
The green README badge proves the standard: style + tests on every change, with no human intervention.
2. Shipping: image or platform
Two complementary paths. The Docker image pushed to the registry (see 5.3): traceable, reproducible, deployed wherever you want. Or the platform connected to the repo (Render, Railway, Fly and equivalents): every green push updates the site automatically — simple to start with. Secrets in repo secrets, never in YAML: prod is configured, not coded. Nabil compares offers when choosing (plans change) and targets the simple path first, control next.
Either way, every delivery is versioned (tags, SHA): you know exactly what is live.
3. The prod minimum: logs, health, rollback
Deploying = being able to come back. The minimum: structured logs (logging), a /health endpoint for monitoring, versions to roll back to. Without a tested rollback, every release is a jump with no parachute. Nabil tests the way back before the big night: on incident day, he restores instead of improvising — and gets the infrastructure choice and access validated by his IT department before exposing real data.
Without this trio, you do not deploy: you gamble.
🔎 Concrete example — Nabil's workflow
Style + tests on every push, green badge as proof.
name: ci
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: {python-version: "3.12"}
- run: pip install -r requirements.txt
- run: ruff check . && pytest -q
Reading: style + tests on every push — red blocks the merge.
Lesson: the green README badge proves the standard continuously.
Section vocabulary
- Deployment
- Making the app reachable online, off your machine.
Simple example: Nabil's analysis leaves localhost for a public address.
What it is not: a script running only on his PC.
Reflex: is my app reachable off my machine?
- CI
- Automatically testing every change, from the very first test.
Simple example: Every push of Nabil's runs ruff and pytest.
What it is not: tests run by hand when someone thinks of it.
Reflex: can a push pass with no proof?
- Pipeline
- An automatic suite of steps (tests, build, deployment) triggered on every push.
Simple example: Nabil's workflow: install, check, test.
What it is not: a manual copy-paste release.
Reflex: is my delivery reproducible?
- GitHub Actions
- Pipelines described as versioned YAML in .github/workflows.
Simple example: Nabil's ci.yml file, reread like code.
What it is not: a mystery server deploying who knows how.
Reflex: is my pipeline versioned and rereadable?
- Rollback
- Going back to the previous version, tested before it is needed.
Simple example: Nabil restores the previous version after an incident.
What it is not: fixing in panic directly in prod.
Reflex: did I test my way back?
In practice — Automating tests and deployment
- Version your project with Git and push it to a GitHub repo (git init, add, commit, push).
- Create a GitHub Actions workflow (.github/workflows/ci.yml) that installs dependencies and runs pytest on every push.
- Check in the “Actions” tab that the pipeline runs and turns green; trigger a test failure to see the alert.
- Deploy the app on a cloud platform (Render/Railway) connected to the repo: every push updates the site automatically.
Ready-to-say script — announcing the go-live
“Our analysis is ready to leave localhost: I set up CI from the first test — ruff and pytest on every push, red blocks. I ship versioned via the platform connected to the repo, secrets in repo secrets, logs and a health endpoint in place, rollback tested. Before exposing real data, I get the infrastructure and access validated by IT.”
Say to your manager to get the go-live and the IT circuit on sensitive data approved.
Copy-paste template — generic Python CI workflow
name: ci
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: {python-version: "3.12"}
- run: pip install -r requirements.txt
- run: ruff check . && pytest -q
Solo / tight budget
Nabil alone: the minimal workflow (ruff + pytest) is enough — the repo's free CI guards prod.
Small business / small team
Green badge + red blocking the merge: nobody ships without proof, even in a hurry.
SME in Algiers
Nabil gets host, access and backups validated by IT in Algiers before exposing real data.
Starting team
Pair up: one writes the workflow, the other checks secrets, /health and rollback; review before the first prod.
✓ Best practices
- CI from the first test: green authorises, red blocks.
- Secrets in repo secrets, never in plain text in YAML.
- Rollback tested before prod: deploying means being able to come back.
✗ Common pitfalls
- “We will add CI later” (regressions ship silently).
- Secrets in plain text in versioned YAML.
- Deploying with no way back and no monitoring (/health, logs).
Key takeaways
- Deployment makes the application reachable online (cloud/PaaS).
- CI/CD automates tests and releases on every code change.
- GitHub Actions describes pipelines in a versioned YAML file.
- Git/GitHub is the foundation: versioning, collaboration and pipeline trigger.
48h challenge — apply tomorrow
Add the workflow above to 1 repo: does it push green — and does red block after a triggered failure?
- I can explain CI vs CD in one sentence.
- My workflow tests on every push (proven green).
- I know where secrets go (out of YAML).
Frequently asked questions
What does CI/CD add over manual deployment?
It removes human error and wasted time: on every change, tests run automatically and, if they pass, the app goes live with no intervention. You ship more often, faster and more safely — a modern-team standard. And red blocking the merge beats any reminders.
Where to host a Python app cheaply?
Repo-connected platforms (Render, Railway, Fly and equivalents) offer entry tiers and automatic deployment from GitHub: ideal to start. For more control, the big clouds are more powerful but more complex — reserve them for needs that justify it. Compare offers when choosing (they change) and get IT validation before exposing sensitive data.
What does a CI/CD pipeline (e.g. GitHub Actions) do?