Introduction to Continuous Delivery: Moving Beyond Just CI
Learn the essentials of Continuous Delivery (CD). We bridge the gap between building code and staging environments, advancing your deployment pipeline.

Previously in this course, we mastered Building Images in CI and Artifact Management. We've spent thirty-one lessons perfecting our ability to build, test, and package our application. Now, it’s time to move from "it works on the build server" to "it is ready for the real world."
Continuous Delivery (CD) is the practice of ensuring that your code is always in a deployable state. While Continuous Integration (CI) validates that your code changes don't break the application, CD ensures those changes can be pushed to a staging environment—and eventually production—at any moment, with minimal manual intervention.
Understanding the CD Difference
In the industry, we often conflate CI and CD, but the distinction is critical for a DevOps engineer.
- Continuous Integration (CI): Focuses on the "is it broken?" phase. It’s about merging, building, and running tests. If it passes, you have a valid artifact.
- Continuous Delivery (CD): Focuses on the "is it ready for users?" phase. It involves packaging that artifact and configuring it so it can be deployed to a staging environment—a near-clone of your production setup—to verify how the app behaves outside of a isolated build environment.
Think of it as a relay race: CI carries the baton through the build and test stages. CD takes that baton and runs the final leg, setting up the infrastructure and configuration required to actually run the application.
Preparing Your App for Deployment
To move toward CD, your application needs to be "deployment-ready." This means removing hard-coded assumptions about where your app lives. You should be able to drop your container image onto any server, inject some environment variables, and have it run.
We do this by using environment-agnostic configuration. Instead of hard-coding database URLs or API keys, your application should look for these values in the environment.
Worked Example: Making an App Configurable
Imagine a simple Python script that connects to a database. Avoid this:
PYTHON# BAD: Hard-coded configuration db_url = "localhost:5432"
Instead, use standard environment variable patterns:
PYTHONimport os # GOOD: Using environment variables db_url = os.getenv("DATABASE_URL", "default-staging-url:5432")
When we set up our CD pipeline, we will inject the production URL during the deployment step, while the staging URL will be the default. This decoupling is the foundation of CD.
Hands-on Exercise: Audit Your Configuration
- Review your current project code. Look for any hard-coded strings that represent environment-specific settings (URLs, port numbers, file paths).
- Create a simple
config.py(or equivalent) in your project that usesos.getenvfor these values. - Commit these changes to your repository. This ensures that when we reach the actual deployment lessons, your application is already prepared to accept configuration from your CD pipeline.
Common Pitfalls
- Mixing Environment Concerns: Trying to force production secrets into your CI build. Secrets should be injected at the deployment phase, not when the image is built.
- The "It Worked on My Machine" Trap: Failing to use a staging environment that mirrors production. If you test on Linux but deploy to Windows, or use different database versions, you haven't actually achieved Continuous Delivery—you've only achieved "Continuous Deployment to Nowhere."
- Manual Hand-offs: Relying on a human to manually "prepare" a build after CI finishes. If it’s not automated, it’s not CD.
FAQ
Is Continuous Delivery the same as Continuous Deployment? No. Continuous Delivery is the ability to deploy at any time. Continuous Deployment is the automation of that release, where every change that passes the pipeline is automatically pushed to production.
What is a staging environment? Staging is an environment that mimics production as closely as possible. It is where you perform final integration testing before users ever see the code.
Do I need a complex server to start CD? Not at all. For now, focus on making your code configurable. We will use GitHub Environments to manage our staging targets in the upcoming lessons.
Recap
We’ve defined CD as the bridge between code validation and environment readiness. By decoupling your configuration from your code, you ensure your application is portable and ready for automated deployment. You are now prepared to define your staging targets and write the scripts that will automate the final delivery of your software.
Up next: Staging Environments — we will define where your code actually goes when it leaves the CI pipeline.
Work with me

CI/CD Pipeline & Docker Containerization
Ship with confidence: automated CI/CD pipelines and Docker setups so every push is tested and deployed — no more manual, error-prone releases.

VPS Server Setup, Deployment & Hardening
Get your app live on a fast, secure server — properly configured, hardened, and deployment-ready. No more wrestling with the command line.


