2025-06-12

⚛️ Atomic deploys

To minimize a deployment's downtime, we use atomic deployments for a couple of clients.


Concept

This concept uses a directory structure like:

~
├── deploy-cache
├── releases
│   ├── 7fd8ff39e3935dc865b2e498681b162127313550
│   ├── 93162127313555dc865b2e498681b7fd8ff39e30
│   ├── …
│	  └── 5dc865b2e498681b7fd8ff39e393162127313550
└── shared
    ├── cache
    ├── content
    └── storage

And two symlinks to tell the web server which release is the current one, where current always points to the latest release and htdocs points to the htdocs folder of the current release**.**

~
├── current -> releases/7fd8ff39e3935dc865b2e498681b162127313550
├── htdocs -> current/htdocs

When deploying files to the server, all those gets rsynced into /deploy-cache and then copied to a new folder in /releases. When done, the current symlink is changed to the new release folder and the site is updated.

Setup

How it works (from Buddy’s guide)

The whole process is handled entirely by two actions — SFTP and SSH — and involves creating a couple of directories on the server:

  • /current - the directory to which your web server points. It containing a symbolic link to the current website version in the /releases directory.
  • /releases - contains the history of uploaded releases. For each version a directory with the name of the release tag is created. This allows for a quick rollback of changes.
  • /deploy-cache - used for storing new files during the deployment. Once the upload has finished, its contents are copied to a new directory in the /releases directory.

In short, when the deployment is triggered, Buddy will first deploy the files to the cache directory on the server, copy the files to a newly created release directory, and switch the symlink of the web server to the new version.

Database backup with mysqldump

If all tables are in the form of InnoDB we can use the --single-transaction flag to keep the database available while taking a DB dump. Without that the tables will be locked while using mysqldump and the site will respond with a 503 status.

Example from Oderland

mysqldump --single-transaction --skip-lock-tables -u username_craft -p password_craft > prod_craft.sql