Continuous Delivery
The canonical text on building reliable, rapid, low-risk software releases through automation and discipline.
Code is the easy part. Shipping is the discipline.
A running collection of writing, courses, and tutorials on shipping software: version control, CI/CD, infrastructure-as-code, deployment, container builds, local dev, database migrations, and feature flags. Less about pipelines than about practice. What to automate, what to verify, and how to ship more often without paying for it later.
This index covers how your code gets to production. For what to build with, see System Architecture. For where it runs, see Infrastructure & Hosting. For keeping it healthy once running, see Production Operations.
Cross-cutting writings on shipping software well.
The canonical text on building reliable, rapid, low-risk software releases through automation and discipline.
Data-driven follow-up to Continuous Delivery; the research foundation behind the DORA metrics.
Comprehensive practitioner's guide to applying DevOps principles across the value stream.
The narrative DevOps text. A novel that introduced a generation of engineers to flow, feedback, and learning.
Canonical reference on trunk-based development: short-lived branches, fast review, continuous integration.
The CNCF-backed spec defining what GitOps is and what it isn't. Four principles, vendor-neutral.
Lightweight convention for commit messages that machines can parse and humans can scan.
MAJOR.MINOR.PATCH and the contract a version number actually conveys. The default for shared libraries.
Fowler's canonical 2006 essay defining CI: integrate often, automate the build, keep main releasable.
The case that deploy fear is technical debt; small, frequent, author-owned changes beat blanket freezes.
Quarterly opinionated assessment of tools, techniques, platforms, and languages by Thoughtworks practitioners.
Annual research linking delivery practices to org performance. The empirical backbone of modern delivery.
Git is the protocol. The host is what matters in practice. GitHub for default, GitLab for self-host-friendly, Codeberg and Forgejo for the ideological alternatives. The choice mostly determines your CI/CD options and how much of your workflow lives in the same UI as your code.
The free official Git book. The definitive learn-Git-from-scratch and Git-reference resource.
Documentation root for GitHub features: repos, Actions, packages, security, and Codespaces.
Reference for GitLab repos, CI/CD, registries, security, and self-managed installs.
Walks new users through account setup, repos, and Codeberg's community-driven Forgejo-based platform.
Create a repo, connect your local environment, and push your first commit.
Official user-facing docs for repositories, pull requests, issues, and collaboration on a Forgejo instance.
Run your first CI workflow with Forgejo Actions.
Installation, usage, and administration of the self-hosted Git forge.
Pull the Gitea image, configure volumes, and complete the install wizard.
Atlassian's onboarding for repos, push/pull, issues, and wikis in Bitbucket Cloud.
Bitbucket's built-in CI/CD with a first pipeline configured via bitbucket-pipelines.yml.
CI runs on every push; CD ships what passed. The line between them blurs in modern platforms. GitHub Actions wins by default because most teams are already on GitHub. CircleCI and Buildkite remain strong standalone offerings. Dagger and Earthly are the new wave that runs the same pipeline locally and remotely, important if you've ever debugged a YAML file by force-pushing.
Create your first workflow, trigger it on push, and explore the marketplace of pre-built actions.
Add a .gitlab-ci.yml, define your first job, and run it on shared or self-hosted runners.
Connect a repo, commit a config.yml, and watch your first CircleCI build run.
Hands-on tutorial creating a basic Buildkite pipeline from an example.
Official guided tour: install Jenkins and create your first Pipeline.
Comprehensive reference for installing, configuring, and operating Jenkins in production.
Stand up a Drone server and run your first .drone.yml pipeline.
Write pipelines in Go, Python, or TypeScript and run them anywhere with a container runtime.
Earthfile syntax, caching, and the local-equals-remote build model.
Covers CI fundamentals, TeamCity concepts, and installing the server on Windows, Linux, or macOS.
Point TeamCity at a repo URL and let auto-detection scaffold your first build configuration.
IaC lets you describe infrastructure as text and commit it. Terraform is the lingua franca; OpenTofu is its OSS fork after the license change. Pulumi gives you real programming languages. CDK is AWS's TypeScript/Python wrapper around CloudFormation. Crossplane brings IaC patterns into Kubernetes itself. Pick by how much programmability you want, and how much surface area your team can review.
Hands-on tutorials covering AWS, Azure, GCP, Kubernetes, and Terraform Cloud workflows.
Install OpenTofu and run your first plan/apply against any supported provider.
Pick a language and cloud, stand up your first stack, and deploy it via the Pulumi CLI.
Install the CDK CLI, bootstrap an environment, and deploy your first stack.
End-to-end walkthrough scaffolding, synthing, and deploying a real CDK application.
Install Crossplane, manage cloud resources, and build compositions from one entry point.
Install Ansible, build an inventory, and write your first 'Hello World' playbook.
GitOps means Git is the source of truth for what runs in production. ArgoCD and Flux are the Kubernetes-native canonical implementations. Helm is the package format underneath. For non-K8s deployments, the toolchain is more fragmented: Spinnaker for the heavyweight Netflix legacy, Tekton for the pipelines-as-code framework. The orchestration runtime itself is in Infrastructure & Hosting; this section is about how code gets there.
Install ArgoCD, register a Git repo as a source of truth, and deploy your first application.
Bootstrap Flux into a cluster, point it at a Git repo, and reconcile your first deployment.
Install Helm, search the chart repository, and release your first chart into a cluster.
Orientation for new Spinnaker users covering applications, pipelines, and deployment strategies.
Hands-on codelab introducing Spinnaker by deploying a simple service end to end.
Build two Tasks, chain them into a Pipeline, and run them with a PipelineRun on minikube.
Author and run your first standalone Tekton Task before moving up to full Pipelines.
Run skaffold dev against a sample Node app on minikube to see the build/deploy inner loop.
Use skaffold init to scaffold a skaffold.yaml for an existing application.
Building a container image is no longer just docker build. BuildKit gives you parallelism and better caching. Buildpacks (Cloud Native, Heroku) and Nixpacks auto-detect your stack. Ko builds Go binaries straight into images, no Dockerfile required. The right pick depends on whether you want Dockerfiles, declarative configs, or zero config at all. The container runtime itself is in Infrastructure & Hosting.
Project README covering frontends, caching, and modern Dockerfile features.
Build OCI images from source with the pack CLI; no Dockerfile required.
Official source-to-OCI-image builder docs. Note: the project is in maintenance mode; Railway directs new projects to Railpack.
Install ko, authenticate to a registry, and build a Go app into a container without a Dockerfile.
Quickstart, configuration, and goals for containerizing Java apps without Docker.
Gradle plugin for building OCI images from Java projects directly from your build.
Install Bazel and follow language-specific tutorials (C++, Java, Go, etc.) to set up your first workspace.
Conceptual overview of how Bazel approaches builds, dependencies, and reproducibility.
Local dev is half the developer experience. Dev Containers run a containerized dev environment in any editor that speaks the spec. mise and asdf manage runtime versions. direnv handles per-directory env vars. Nix flakes give you fully reproducible environments at the cost of a steep learning curve. Devbox wraps Nix in friendlier abstractions. Tilt is the option for Kubernetes-aware local dev. Docker Compose is in Infrastructure & Hosting; most teams use it locally too.
The devcontainer.json spec that VS Code, JetBrains, GitHub Codespaces, and others implement.
Install mise and start managing runtime versions, env vars, and tasks per project.
Install asdf, configure your shell, and add plugins for the language runtimes you need.
Project landing page with the canonical .envrc walkthrough and shell hook setup.
Install direnv and wire it into bash, zsh, fish, or your shell of choice.
Official learning hub pointing to nix.dev tutorials and the Nix reference manual.
Initialize a devbox.json, add Nix-powered packages, and enter an isolated dev shell in minutes.
Build a Kubernetes dev loop with live updates, smart rebuilds, and a status UI.
Schema changes are deploys with no rollback. Migration tools force you to encode every change as a forward-only script. Atlas is the modern declarative entrant. Goose and golang-migrate are the language-agnostic mainstays. Alembic, Flyway, and Liquibase are the long-running standards in Python and JVM ecosystems. The database itself is a System Architecture decision; this section is about safely changing its shape over time.
Declarative schema migrations: plan diffs, validate with linting, and ship via CI.
Canonical README for the Go migration tool: CLI usage, SQL and Go migration formats, embed examples.
Drivers, library usage, and recommended migration workflows.
Create up/down migration files, run them with the CLI, and embed migrations into a Go program.
Database-specific walkthrough for running golang-migrate against Postgres.
Set up Alembic with SQLAlchemy, generate your first revision, and apply it to a database.
Install Flyway and version-control your database schema with SQL-first migrations.
Install Liquibase and run your first changelog using the bundled H2 sandbox database.
Authoritative reference covering changelogs, contexts, rollbacks, and CI/CD integration patterns.
Set up Prisma Migrate, create a baseline migration, and generate SQL from your Prisma schema.
From-scratch tutorial wiring Prisma Migrate to a TypeScript + Postgres project.
Install sqlx-cli and use sqlx migrate add/run to manage SQLx migrations in Rust projects.
API reference for embedding migrations into a Rust binary via the sqlx::migrate! macro.
Feature flags decouple deploy from release. You can ship code today and turn it on for 1% of users tomorrow. LaunchDarkly is the heavyweight commercial player. Statsig and PostHog combine flags with analytics. Unleash, Flagsmith, and GrowthBook are the OSS contenders. OpenFeature is the emerging standard for vendor-neutral SDKs. The decision is mostly whether you need experimentation (A/B testing) or just safe rollouts.
Create a project, add an SDK, and ship your first flag-gated release.
Install a Statsig SDK in your language of choice and start checking feature gates in a few lines.
Concept guide explaining feature gates, targeting, rollouts, and overrides in Statsig.
Use PostHog's flags plus analytics plus experimentation in one stack.
"Get up and running with Unleash in less than 5 minutes" with links to SDKs and tutorials.
Create a flag, define strategies, and refine with constraints, segments, and variants.
Four-step tutorial: create a project and flag, import the JS SDK, fetch flags, and toggle behavior.
End-to-end walkthrough for feature flagging and experimentation with GrowthBook Cloud or self-host.
Wire a GrowthBook SDK into your app to start evaluating feature flags.
Add a flag in the ConfigCat dashboard and evaluate it from any of 20+ supported SDKs.
The CNCF-incubating spec for vendor-neutral feature-flag SDKs.
Engineers consistently publishing on continuous delivery, DevOps practice, and deployment.
Short answers grounded in the work of practitioners shipping real software.
On-push: lint, test, build. On-merge-to-main: deploy to staging automatically. On-tag (or manual approval): deploy to production. Three pipelines, three triggers; that's the whole shape. Almost any platform (GitHub Actions, GitLab CI, CircleCI) can do this in well under a hundred lines of YAML. Resist the urge to add review apps, canaries, or environments-per-branch until the basic flow is reliable and fast for everyone on the team.
Roughly when reproducing your infrastructure stops being a one-day task. If a new environment takes you a week of clicking in cloud consoles, IaC has already paid for itself. The other trigger is auditability: when you need to know who changed what in prod, plain SCM history beats a CloudTrail digest. Start with the resources that change most often (DNS, load balancers, IAM) and grow outward. You don't need to import everything on day one.
If your team is fluent in TypeScript, Python, or Go and you want loops, conditionals, and real testing, Pulumi is the natural fit. If you want the largest ecosystem of modules, the most provider coverage, and the easiest hiring story, Terraform (or OpenTofu) is still the default. The license change pushed many OSS teams to OpenTofu; check whether your CI provider's Terraform Cloud integration matters before picking.
kubectl apply scales to small teams and short feedback loops. GitOps starts paying off when you have more than one cluster, more than a handful of services per cluster, or audit requirements that demand a clear answer to "what's running and who put it there?". The four OpenGitOps principles (declarative, versioned, pulled, continuously reconciled) describe what you gain. If you don't need the gains yet, the operational cost is real.
Source: OpenGitOps Principles
Three rules: migrations are forward-only; every migration is backward-compatible with the previous app version; and migrations run before the app version that depends on them is deployed. That means expand/contract: add the new column or table first, ship the app that reads both old and new, backfill, then drop the old shape in a later release. Atlas, Alembic, Flyway, and Liquibase all support this pattern; the discipline comes from your team, not the tool.
Roughly when you start wanting to deploy more often than you want to release. Flags decouple the two: ship the code today, turn it on for 1% of users next week, ramp to 100% when the metrics hold. If your release cadence is monthly, you probably don't need a flag service yet. If it's daily and you have real users, the small operational cost pays for itself the first time you can roll back a bad release without rolling back a deploy.
The DORA research is unambiguous: high-performing teams deploy more often AND have lower change-failure rates. The way they get there is small batch sizes, fast feedback, and automation of the boring parts. The path is not to deploy more by relaxing review; it's to make each deploy smaller and the rollback cheaper. Charity Majors's framing is the right one: deploys shouldn't be scary because each one carries less risk, not because you've removed risk by waiting.
Source: DORA Research
Original writing coming.
Smarter Dev essays, walkthroughs, and short courses on shipping software will land here as they're written.
Join the Discord to be notifiedLast updated