Codewerk.
Get a quote
Home/Blog/From FTP to CI/CD: deployments that do not scare you

From FTP to CI/CD: deployments that do not scare you

If deploying is scary, you deploy rarely, so each deploy is huge, so it is scarier. Here is how to break that loop.

Photo: free stock photography (Unsplash licence) — see imprint

The fear loop

Manual FTP deploys are risky, so teams batch changes for weeks. A big batch is harder to test and harder to roll back, which makes the next deploy riskier still. Small, frequent, automated deploys are not a luxury — they are the way out.

Same image everywhere

Build a Docker image once, run that exact image on staging and production. 'It worked on staging' stops being a mystery when staging and production are byte-identical apart from configuration.

The pipeline that is enough

On push: install, lint, run tests, build assets, build image. On merge to main: deploy to staging automatically. On a tag: deploy to production with one click and a database migration step. You do not need more than this to be safe.

Rollback is a feature you must test

A rollback plan you have never executed is a wish. Practise it on staging: deploy, break something, roll back, verify. Do it once and go-live night stops being a night.

Key takeaways
  • Deploy small and often to make deploying boring.
  • Ship the identical image to staging and production.
  • An untested rollback is not a rollback.

Frequently asked questions

Because the risk comes from the size of the batch, not the frequency. Deploying rarely means weeks of changes go out together, which is harder to test and harder to roll back, so the next one is scarier still. Small and frequent breaks that loop. The aim is not speed for its own sake — it is making a deploy boring.

On push: install, lint, run the tests, build assets, build the image. On merge to main: deploy to staging automatically. On a tag: one click to production, with a database migration step. That is enough to be safe for one shop. If someone offers you more stages than that, ask which specific failure each extra one prevents.

Because they are not the same machine. A different PHP patch level, a missing extension, a config nobody wrote down. Build one Docker image and run that exact image in both places, with only configuration differing. Then the mystery does not get debugged — it stops existing. That is the point of the image, not the container fashion.

A rollback you have never executed is a wish. Practise it on staging: deploy, break something deliberately, roll back, verify the shop still sells. Decide in advance what happens to a database migration you cannot undo — that is the part which quietly turns a rollback into an outage. Do it once and go-live stops being a night.

We do this for a living — Shopware, Node.js, React, ERP integration and automation for B2B.

Talk to an engineer

// Keep reading

Related articles