Skip to content

Deploys - Overview

There are two ways to deploy to the serverless platform, using either git for continuous deployment (our recommended approach), or file deploys. We also provide SFTP access, but this is primarily used for viewing, editing or transferring a small number of files.

Git Deploy Strategies

For git deploys, you can choose between two deployment strategies that determine how your code is deployed and stored:

StrategyBest ForRollbackStorageMethod
VersionedProduction apps needing instant rollbackInstant (previous versions retained)Higher (full copy per deploy)Atomic
LiveLarge codebases, frequent deploysRequires redeployLower (single directory with incremental updates)Incremental

Versioned Strategy (Default)

Versioned deploys are atomic. Each deployment creates a new, complete copy of your application in a versioned directory, think of it like a git checkout. A live symlink points to the active version, enabling instant rollback to any previous deployment. Files not tracked by git will not persist between deploys, unless they are in our persistent storage.

Live Strategy

Uses a single persistent deploy directory with incremental syncing. Each build output is compared to the previous one and only changed files are updated. Files not changed, added, or deleted in the build output will not be touched between deploys — including files modified directly on the live site via SFTP or a CMS. The live symlink structure is maintained, allowing zero-downtime switching between strategies. See How Live Deploys Work for a detailed breakdown.

Atomic Deploys

Atomic deploys mean your whole application is deployed each time, and the existing release stays separate. This ensures zero downtime, simple rollback, and consistent state. Atomic deploys apply to file deploys and git deploys using the versioned strategy.

If you are used to deploying files with SFTP, SSH or similar this is a bit different, with two key concepts to keep in mind:

  • Your application files are downloaded and replaced entirely each deployment, giving you a clean slate.
  • Any files written to your application directory during runtime (think uploads, cache, logs, built artifacts) will not be present on the next deployment, unless placed in persistent storage of some kind.

Persistent Storage

For some parts of your application you may need persistent storage. Some common uses cases are for storing generated images, caches, logs, or user submitted content.

That’s where the shared directory /mnt/data/website/shared comes in – it’s a directory that exists outside your application’s deployment directory and survives across all deploys. You can write whatever files you like here, and they will be available to all deploys now and in the future. You can also structure it’s contents however you like. Here’s a simplified example of how we use it for our own website:

We have three things we want to persist between deploys. User submitted form entries, our generated responsive images and some logging. In our build script we have the following:

.webslice/build.sh
#!/bin/bash
# create shared directories if they don't exist
mkdir -p /mnt/data/website/shared/forms
mkdir -p /mnt/data/website/shared/img-cache
mkdir -p /mnt/data/website/shared/logs
# remove existing public image directory
rm -rf public/img-cache
# create symlink to persistent storage so image paths work
ln -sf /mnt/data/website/shared/img-cache public/img-cache
echo "✓ Symlinks created successfully"

This gives us the three folders we want to persist, and we have made only the image directory accessible in our public/ directory to ensure existing image paths work and are available to the browser. The other two directories are private, so there’s no symlink required. Instead in our site.php we tell the system that’s where to write logs and form entries to:

config/site.php
return [
'image_manipulation' => [
'cache' => true,
'cache_path' => storage_path('/mnt/data/website/img-cache'),
],
'disks' => [
'forms' => [
'driver' => 'local',
'root' => storage_path('/mnt/data/website/forms'),
],
'logs' => [
'driver' => 'local',
'root' => storage_path('/mnt/shared/logs'),
],
],
];

With that done we end up with the folder structure below in persistent storage:

  • Directorymnt/website/shared/
    • Directoryforms/
    • Directoryimg-cache/ » public/img-cache
    • Directorylogs/

These folders and any files they container will accessible by all future deploys, and our image directory can be served to the browser, ensuring we’re not having to generate new images each deploy.