How to Migrate a DeployHQ Project to Use Atomic Deployments

Tips & Tricks and Tutorials

How to Migrate a DeployHQ Project to Use Atomic Deployments

Standard deployments overwrite files directly on your server. This is fine for most sites, but it means there's a window during every deployment where some files are new and others are old. If a visitor hits your site during that window, they may see errors — and if the deployment fails partway through, you're left with a partially updated codebase.

Atomic deployments eliminate both problems. Each deployment goes into its own directory, and your live site switches to the new release only after everything is in place. If the deployment fails, your site keeps running from the previous release, completely unaffected.

If you have an existing DeployHQ project using standard deployments, migrating to atomic deployments requires creating a new server configuration and updating your web server settings.

Standard vs atomic deployments

Aspect Standard Atomic
File updates Overwrites in place Deploys to a new directory
Downtime risk Yes — during file transfer None — symlink switch is instant
Failed deployment Partially updated files Previous release stays live
Rollback Not possible without redeploying Instant — switch symlink back
Disk usage Single copy of files 3 copies (current + 2 previous)

How atomic deployments work

When you run an atomic deployment, DeployHQ creates this directory structure within your deployment path:

/var/www/your-app/
├── releases/
│   ├── 20260325120000/    # Previous release
│   └── 20260325140000/    # Current release
├── shared/                # Persistent files (uploads, config, logs)
│   ├── config/
│   └── storage/
├── cache/                 # Build cache (if configured)
└── current -> releases/20260325140000   # Symlink to active release

Your web server serves content from the current symlink. When a new deployment completes, DeployHQ switches current to point at the new release directory. This switch is an atomic filesystem operation — there's no in-between state.

sequenceDiagram
    participant D as DeployHQ
    participant S as Server
    participant W as Web Server

    Note over W: Serving from current → release-A
    D->>S: Create new release directory
    D->>S: Copy previous release files
    D->>S: Upload changed files
    D->>S: Symlink shared files
    D->>S: Switch current → release-B
    Note over W: Now serving from current → release-B

Migration steps

1. Identify files outside your repository

Before migrating, check what's on your server that isn't in your Git repository. Common examples:

  • Configuration files: .env, config/database.yml, wp-config.php
  • User uploads: uploads/, storage/app/public/
  • Log files: storage/logs/, log/
  • Cache directories: cache/, tmp/

These need to be moved into the shared directory after the atomic deployment structure is created.

2. Create a new server in DeployHQ

In your DeployHQ project, add a new server with the same connection details as your existing one (hostname, username, credentials). On the configuration screen, check the Perform zero-downtime deployments on this server option.

Important: The deployment path you specify must be empty. DeployHQ needs a clean directory to create the releases/, shared/, and current structure. If your current site lives at /var/www/your-app/, you have two options:

  1. Use a new parent directory (e.g., /var/www/your-app-atomic/) and update your web server configuration
  2. Back up and clear the existing directory, then use the same path

3. Run a full deployment

Deploy to the new server. DeployHQ creates the directory structure and uploads a complete copy of your codebase to the first release directory.

4. Move persistent files to shared

SSH into your server and move any files that need to persist across releases into the shared directory:

# Example: move uploads directory
mv /var/www/your-app-atomic/releases/20260325120000/storage/app/public \
   /var/www/your-app-atomic/shared/storage/app/public

# Example: move environment file
cp /var/www/old-site/.env /var/www/your-app-atomic/shared/.env

DeployHQ automatically symlinks everything in shared/ into each new release during deployment. The directory structure must match — a file at shared/config/database.yml gets symlinked to releases/TIMESTAMP/config/database.yml.

5. Update your web server configuration

Point your web server's document root to the current symlink:

Nginx:

server {
    root /var/www/your-app-atomic/current/public;
    server_name example.com;
    # ... rest of your configuration
}

Apache:

DocumentRoot /var/www/your-app-atomic/current/public
<Directory /var/www/your-app-atomic/current/public>
    Options FollowSymLinks
    AllowOverride All
</Directory>

Reload your web server configuration:

sudo systemctl reload nginx
# or
sudo systemctl reload apache2

6. Remove the old server from DeployHQ

Once you've confirmed the atomic deployment is working correctly, remove the old (standard) server from your DeployHQ project.

Troubleshooting common migration issues

Ensure the deployment user has write permissions to the entire deployment path. The user needs to create directories, copy files, and create symlinks.

Shared files not appearing in releases

Check that the shared directory structure matches where the application expects the files. If your app expects config/database.yml, the file must be at shared/config/database.yml.

Also verify that the shared files don't exist in your Git repository. If they do, DeployHQ can't create the symlink because the file is already there. Add these files to your .gitignore.

Application errors after switching

If your application throws errors after the switch, it may be related to:

  • Cached paths: Some frameworks cache absolute file paths. Clear the application cache as an SSH command after deployment
  • Missing shared files: Double-check that all necessary config and upload directories are in shared/
  • Process restarts: If your app runs a persistent process (like a Node.js server or PHP-FPM), you may need to restart it via an SSH command

Running out of disk space

DeployHQ keeps 3 releases (current + 2 previous). For large codebases, ensure your server has at least 3x the disk space of your application. DeployHQ automatically cleans up older releases.

Combining with build pipelines

If your project uses a build pipeline (for compiling assets, installing dependencies, etc.), it works seamlessly with atomic deployments. The build runs before files are transferred, and the compiled output goes into the new release directory.

Combining with SSH commands

For applications that need database migrations or process restarts, configure SSH commands to run after files are transferred. The commands run in the context of the new release directory, before the symlink is switched.


Ready to eliminate deployment downtime? Sign up for DeployHQ and set up atomic deployments in minutes.

If you have any questions about migrating to atomic deployments, contact us at support@deployhq.com or reach out on X (Twitter).