Published · Updated
Deployment should be boring
At ConnectTo, where I started working with Laravel commercially as a junior, a deployment meant running git pull on the production server. Merge conflicts were sometimes resolved right there, so production could differ from both the repository and every developer’s local copy.
- CI/CD
- deployment
- Git
- Docker
- GitHub Actions
- GitLab CI
What was wrong with git pull on production
A release depended on someone remembering the order of commands and the current state of the server. The commit being deployed didn’t tell you any of that.
Resolving a conflict on production also changed the working tree in the middle of a release. The server could end up running a merge result that nobody had reviewed or reproduced anywhere else.
I had production access and helped with deployments in a team of three developers. That’s where my preference for CI/CD comes from.
Release steps in version control
In later projects I used GitHub Actions and GitLab CI for repeatable build and deployment steps, with Docker where it suited the target environment. In GitHub Actions the pipeline usually went: build the image, push it to a registry, deploy that image. The commands and their order live in version-controlled configuration, not in someone’s terminal history.
- Build the artefact that will actually be deployed.
- Keep release commands in version-controlled pipeline configuration.
- Run automated checks before changing production.
- Make redeploying and rolling back independent of anyone’s terminal history.
What changed
Normal releases stopped needing merge resolution on the server. The pipeline configuration shows which steps will run, and its output shows where a failed release stopped. That’s what I mean by boring: a deployment shouldn’t depend on knowledge that only one person has.