Software Development

DevOps for Software Teams: From Manual Releases to a Pipeline

What DevOps changes in day-to-day delivery, the habits that keep releases slow, and the first pipeline steps for a team that still deploys by hand.

5 min readBy BizHues Engineering

Working on this?

Talk it through with an engineer.

A 30-minute requirements call, no charge.

Book a call

The feature was finished on Thursday. It reached production the following Tuesday, after someone in operations spent two days preparing a server, running steps from a Word document and chasing errors that only showed up on the live machine. Releases like that become rare, large and tense, and the team starts finding reasons to postpone them. DevOps is the set of practices that removes that handoff, so shipping a change becomes ordinary work the whole team owns.

What DevOps means on a normal day

Take the name away and you are left with a handful of habits.

Continuous integration means every change is built and tested automatically when it is pushed. Continuous delivery means a passing build moves to an environment through a repeatable process, with no steps run by hand. Infrastructure is described in files kept in version control, so a server can be rebuilt from them instead of from someone's memory. Monitoring is set up before launch, not after the first outage. And the developer who wrote the code sees how it behaves in production, instead of hearing about it from a support ticket a week later.

None of this needs a reorganisation or a new job title. It needs a pipeline, a set of tests that actually run, and an agreement about who looks at the alerts.

A typical delivery pipeline
  1. 01Committo version control
  2. 02Build and testautomatic on every change
  3. 03Packageas a container image
  4. 04Deployto staging, then production
  5. 05Monitorlogs, errors, alerts

What monitoring finds feeds the next change

Each step runs the same way for every change, so a release is routine instead of an event.

Why small releases break less

When delivery is automated, releases can be small. A small release is easier to test, easier to read and easier to roll back. When something goes wrong, the cause is close to the change.

Take a change that breaks settlement reconciliation for one payment gateway. Shipped in a release of ten changes, someone finds it within the hour by reading the diff. Shipped in a release of two hundred, it is found after the finance team has reconciled the day by hand and asked engineering, politely, what happened.

Slow releases have a quieter cost too. Every week a finished feature waits for a deploy window is a week of work nobody can use, and a week in which the branch drifts further from everything else.

One build, deployed everywhere

The most useful rule here is also the boring version: build once, and deploy that exact build to every environment. The image you tested in staging is the image that goes to production. Only configuration changes between them. If production gets a fresh build, you tested something else.

The second rule is about the bad evening. Keep the last good version as a deployable artefact with a one-command rollback, not as a tag someone might remember. When a release goes wrong at 9 p.m., nobody reads documentation.

A minimal pipeline for a containerised application has this shape. It is a sketch, not a template; the point is that one image is built and the same image is deployed.

stages: [test, build, deploy]
test:
  stage: test
  script: [make test]
build:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
deploy_staging:
  stage: deploy
  script: [./deploy.sh staging $CI_COMMIT_SHA]

Production gets the same deploy job with the same image tag, usually behind a manual approval button rather than an email thread.

How Profit Lever Models ships

Profit Lever Models is a driver-based financial modelling platform. The documented stack is a Next.js App Router front end, a Django REST API, PostgreSQL, Redis with Celery for background jobs and notifications, S3 for file storage, and Metabase or Superset for analytics. It is deployed in containers on AWS and released through GitLab CI/CD.

Profit Lever Models stack
  • Next.js App Routerfront end
  • Django REST APIbusiness logic and permissions
  • Celery workers with Redisbackground jobs
  • PostgreSQL and S3data and files
  • Containers on AWSreleased through GitLab CI/CD

Several components, each deployable as a container, which makes an automated pipeline worth having.

Profit Lever Models product overview
Profit Lever Models, a driver-based financial planning platform.

With a front end, an API, background workers and a database, a manual release has plenty of places to go wrong. Workers can end up on a different version from the API. A migration can run twice. A setting can change on one server and not the next. Running the build and the tests in CI and shipping containers means the artefact that was tested is the artefact that gets deployed, and the same image runs in staging and production. The project also uses caching and background jobs to keep large models responsive, and the pipeline supports small, incremental releases rather than a monthly big one.

How teams slide back to manual releases

The first way is buying the tools and keeping the old process. A pipeline exists, but a person still approves each stage by email, so the release waits for someone to come back from lunch. The second is a DevOps team that turns into the new operations wall. Developers throw changes over to it instead of to the old ops group, and the only thing that changed is the team name.

Pipelines that only build are common. Without tests, speed means shipping bugs faster. Environments that differ come next: staging on one database version, production on another, with different settings, so a passing release fails on the day. That kind of drift piles up like any other technical debt in a long-running project, and it is paid back at the worst possible time.

Secrets in shell scripts, or pasted into a chat channel, make access control and auditing hard. Monitoring added after the first outage means there is no baseline to compare against, which is a polite way of saying nobody knows what normal looks like.

And slow pipelines. If CI takes forty minutes, developers batch their changes to avoid waiting, releases get large again, and you are back where you started.

First steps if you have no pipeline

If you are starting from releases run by hand, do these in order. Each one is small enough to finish in a week or two.

  • Put everything in version control, including infrastructure settings.
  • Run the build and the existing tests on every change. Block merges that fail.
  • Package the application the same way for every environment.
  • Automate deployment to staging, then to production.
  • Keep the previous release deployable, and practise a rollback once.
  • Add logs, error reporting and one alert per critical flow, before it pages someone.
  • Give developers access to production dashboards and bring them into incident reviews.

Begin with the second item. A build that runs the tests on every change gives the team its first reliable signal, and every later step depends on it. If you want a second pair of eyes on an existing setup, our software development practice covers delivery pipelines along with the application itself.

From our work

Profit Lever Models

Financial Intelligence Platform

Read the project story
Share this article
Software Development

Talk to an engineer

Have a requirement worth building?

Book a 30-minute call with an engineer, at no charge. Tell us the problem and the systems involved, and you leave with questions answered and a suggested first step, not a sales deck.