Case study · internal work, delivery pipeline

Our delivery pipeline: every release numbered, and a rollback written in advance.

This is not a client assignment: it is the tooling that puts this site live, along with the projects we deliver from our code forge. Each version becomes a numbered Docker image, deployed without any admin key travelling through the pipeline. Going back to the previous one needs no rebuild, and the procedure is written down.

01/BackgroundWhy we built it

A manual release depends on the memory of whoever does it

There are two of us delivering. A release had to follow the same path every time, and we had to know at any moment which version was running. For each risk, what the pipeline does.

  1. 01Every manual release differs slightly from the one before.Always the same path: image build, publication to the registry, deployment requested by the forge.
  2. 02An image tagged “latest” does not tell you which code is running.Each image carries its version number and its commit identifier, written into the image itself; no moving tags.
  3. 03An emergency rollback means rebuilding a version we no longer have.Numbers follow one another with no gaps: the previous one always points to a published image, which only needs restarting.
  4. 04An accidental push to the main branch goes straight to production: it has happened to us.Direct pushes to the main branch are blocked in all our active repositories: everything goes through a merge request with a green pipeline, administrators included.
02/What we builtIn service today

From commit to go-live, with no manual step

A merge request is approved, the main branch delivers, and each step leaves a trace we can read back.

  • 01
    Self-hosted forge. Code, merge requests, pipeline and image registry on our own Forgejo forge.
  • 02
    Validate without delivering. A merge request builds the image to check that it passes, without publishing or deploying it.
  • 03
    Version number. The date, then the release's position in the day, reserved before the build so that no image overwrites another.
  • 04
    Multi-stage Docker image. Dependencies, build and runtime kept separate; the final image runs without privileges, with a health probe.
  • 05
    An image that knows where it comes from. The source commit and version number are written into its labels: the container itself tells you what is running.
  • 06
    Deployment through a controller. The forge asks a controller to release, with a dedicated key; the application's secrets stay on the server, never in the repository.
  • 07
    Written rollback. Put back the required number, restart, check through the container; a missing number makes the command fail without touching the live site.
  • 08
    Guardrails. Main branch protected in every active repository; every Monday, the images actually in service are scanned and the number of critical vulnerabilities arrives by e-mail.
03/One diagramTypeset diagram, not a screenshot

A diagram of the path, until we have a screenshot of our forge

No screenshot of the forge has been published yet. This diagram follows a release, from the code to the server.

Diagram of the delivery pipeline in four stages: a merge request with a green pipeline joins the main branch; the project is built into a numbered Docker image, with its health probe; every version is kept in our private registry; the image is deployed on our servers, with a rollback written in advanceDiagram of the delivery pipeline in four stages: a merge request with a green pipeline joins the main branch; the project is built into a numbered Docker image, with its health probe; every version is kept in our private registry; the image is deployed on our servers, with a rollback written in advance
Fig. 01Diagram of the path, typeset as text. It is not a screenshot of our forge.

Four stages, from code to go-live

An approved merge request, a numbered Docker image, kept in the private registry, then deployed by the controller; going back to the previous version is written in advance.

04/TechnologiesWhat we chose, and why

A short pipeline that we can read from end to end

Few tools, and every rule written in the repository, next to the code it delivers.

  • ForgeForgejo and its Forgejo Actions pipeline, with a private image registry on the same forge.
  • ImagesMulti-stage Docker, unprivileged runtime, health probe, commit and version labels.
  • DeploymentDocker Compose on the server, version number read from a single file; a missing value makes the command fail instead of serving a random image.
  • AccessDeployment controller reached with a key used only to trigger it; application secrets on the server, outside the repository.
  • ChecksMain branch protected in every active repository, green pipeline before merging, administrators included.
  • MonitoringWeekly scan of the images in service with Trivy, a report by e-mail and an audit report in PDF.

What next

Manual releases, and nobody knows which version is running?

Every piece of software we write ships with its delivery pipeline. Tell us about your project, and we will tell you what is feasible, with a timeline and a rough price.

Discuss your project

Reply within 24 working hours, from one of the two founders. Or by phone: +33 7 59 96 14 99.