Blue/Green vs. Symlink Releases for Magento Shops
AI generated
CI/CD
.yml
GitLab · CI/CD · Deployment Strategy · Magento
Blue/Green vs. Symlink Releases
for Magento Shops: an Honest Comparison

Blue/Green deployments sound like the perfect zero-downtime solution. For most Magento shops, though, the infrastructure overhead is out of proportion. Symlink releases achieve the same rollback speed at a fraction of the complexity, provided they are set up correctly.

14 min read Blue/Green · Symlink · current · releases/ · Rollback GitLab CI · Magento 2 · Zero Downtime

1. What Blue/Green Deployment Really Means

Blue/Green deployment means running two identical production environments, Blue and Green, in parallel. At any given moment exactly one environment is active and receiving traffic. A new release is deployed to the inactive environment, fully tested, and then traffic is switched from the old environment to the new one via a load balancer or DNS change. A rollback is simply another traffic switch back to the old environment, taking seconds, without any data loss.

That sounds elegant, and it is. But it comes at a price: doubled infrastructure. Two web servers, two PHP-FPM instances, two complete Magento installations, and a load balancer capable of performing the traffic switch. For a Magento shop running on a single server instance, that infrastructure simply does not exist. For a project with multiple web nodes and an upstream load balancer, it is achievable, but it comes with significant setup effort.

Then there is the question of shared resources: the database, Redis, and media files cannot be duplicated. In Blue/Green deployments for Magento, both environments point to the same MySQL instance, the same Redis, and the same NFS mount for pub/media/. That limits how truly isolated the approach really is: a non-backward-compatible database change in the Green release immediately affects the running Blue release. This fundamental Magento constraint is another reason why the benefit of Blue/Green is smaller for most Magento setups than it is for stateless web applications.

The symlink release model, known from Capistrano, Deployer, and similar tools, solves the same problem with far less infrastructure. The basic structure: a releases/ directory containing numbered or timestamped release folders, a current symlink pointing to the active release, and a shared/ directory for files that stay unchanged across all releases. The web server points to current/, never directly at a release directory.

A new release is deployed into a fresh directory under releases/, all Magento steps (shared links, SCD, cache:flush) are run against that new release directory, and only then is the current symlink switched atomically to the new release. Atomic means: ln -sfn is a single system call that cannot be interrupted. The instant the symlink switches, the web server points to the new release, with no downtime and no half-finished state.

3. Infrastructure Overhead: the Decisive Difference

A minimal Blue/Green deployment setup requires: two server instances (or two VMs/containers), a load balancer with health-check configuration and an API mechanism for switching traffic, a strategy for shared resources such as the database and media files (which cannot be duplicated), and a script that coordinates the switch. Operational effort doubles, because both environments must be kept up to date.

Symlink releases require: one server, the correct directory structure on that server, and permission to create symlinks. That is all. A single ln -sfn command performs the switch. For 95% of Magento shops running on a single server instance, this is therefore not really a trade-off: symlink releases are simply the only sensible option. Blue/Green becomes relevant once multiple web nodes are running in parallel behind a shared load balancer.

4. Rollback Speed in Direct Comparison

Both Blue/Green and symlink releases deliver extremely fast rollbacks, but in different ways. With Blue/Green, a rollback is a traffic switch: the load balancer sends traffic back to the old environment. That takes seconds and has no impact whatsoever on the application itself, since the old environment was active in parallel the entire time. That is the real advantage of Blue/Green: the old version was never truly shut down.

With symlink releases, a rollback is a symlink switch: ln -sfn /var/www/releases/20260507-120500 /var/www/current. This also takes seconds and requires no web server restart. The difference from the Blue/Green approach: new requests that arrived during the deploy process and already use the new release directory are abruptly thrown back onto the old release. For Magento this is uncritical for most request types, but it can interrupt an active checkout process. In practice, this window is extremely short.

deploy:production:
  stage: deploy
  environment:
    name: production
    url: https://shop.example.com
  script:
    # Transfer release archive to server
    - scp release-${CI_COMMIT_SHORT_SHA}.tar.gz "${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/"
    # Execute deployment sequence via SSH
    - ssh "${DEPLOY_USER}@${DEPLOY_HOST}" bash -s << 'DEPLOY'
        set -euo pipefail
        readonly RELEASE_ID="$(date +%Y%m%d-%H%M%S)"
        readonly APP_PATH="${DEPLOY_PATH}"
        readonly RELEASE_DIR="${APP_PATH}/releases/${RELEASE_ID}"

        # Create and populate release directory
        mkdir -p "${RELEASE_DIR}"
        tar -xzf "/tmp/release-${CI_COMMIT_SHORT_SHA}.tar.gz" -C "${RELEASE_DIR}"

        # Link shared directories (media, logs, env.php)
        ln -sfn "${APP_PATH}/shared/pub/media" "${RELEASE_DIR}/pub/media"
        ln -sfn "${APP_PATH}/shared/var/log" "${RELEASE_DIR}/var/log"
        cp "${APP_PATH}/shared/app/etc/env.php" "${RELEASE_DIR}/app/etc/env.php"

        # Run Magento release steps on new release directory
        cd "${RELEASE_DIR}"
        php bin/magento setup:static-content:deploy de_DE -f -j 4
        php bin/magento cache:flush

        # Atomic symlink switch: this is the actual "deploy" moment
        ln -sfn "${RELEASE_DIR}" "${APP_PATH}/current"

        # Keep last 5 releases, remove older ones
        ls -dt "${APP_PATH}/releases/"* | tail -n +6 | xargs rm -rf
      DEPLOY
  only:
    - tags

5. Magento Specifics: Cache, Sessions, Database

Magento has a few specifics that need to be taken into account when choosing a deployment strategy. The Magento cache lives in Redis or on the filesystem and is managed by the application independently of the release directory. After a symlink switch, all requests immediately point to the new release, but the Redis cache still holds data in the old release's format. That is one reason why cache:flush should run before the symlink switch, not after.

Sessions are a more complex case. Magento stores sessions in Redis or in database tables. Active user sessions survive a symlink switch without issue, as long as the new release has not broken the session structure. With Blue/Green deployments the situation is similar: when the traffic switch happens, in-flight requests from the Blue environment still have active sessions. The shared Redis backend ensures those sessions remain valid in the Green environment too, provided the data format has not changed.

The database is the third critical point. Both deployment strategies share a single MySQL instance. Database migrations via setup:upgrade are not truly isolated in either symlink releases or Blue/Green: they take effect immediately for all environments. The difference: with symlink releases, that is explicitly part of the deploy sequence. With Blue/Green there is an illusion of isolation that does not actually hold for shared database resources.

Implementing a complete symlink release process in GitLab CI takes three things: the correct directory structure on the server, a deploy script that performs the symlink switch, and a rollback job in the pipeline. The server structure is set up once: mkdir -p /var/www/magento/{releases,shared/{pub/media,var/{log,session},app/etc}}. The shared/ directory holds all files that need to persist across releases.

The critical step is the order of operations: unpack the artifact, set up shared links, run Magento-specific steps (SCD, setup:upgrade if needed), cache:flush, and only then switch the symlink. After the symlink switch, new requests are served by the new release, but the web server does not need to be restarted. PHP-FPM and Nginx/Apache re-resolve the symlink on every request, so the switch takes effect immediately.

7. When Blue/Green Makes Sense for Magento

Blue/Green becomes worthwhile for Magento shops when several conditions are met at once: there is more than one web node, a load balancer that can be switched programmatically, and a team that can operate the doubled infrastructure. Beyond that, Blue/Green is attractive for shops with extremely high traffic, where even a brief window of requests hitting a half-deployed release is unacceptable.

Another use case for Blue/Green: database migrations that are not backward-compatible. With symlink releases, the new release must remain compatible with the old database schema until the symlink switches (the expand/contract pattern). With Blue/Green, the migration can be run and tested in the inactive environment before traffic switches over. This advantage, however, only holds if the database is not shared, which in Magento setups running a single shared MySQL instance is not the case anyway.

7b. Web Server Configuration for Symlink Releases

A frequently overlooked aspect of symlink releases is the Nginx configuration. The root path in the Nginx server block must point to /var/www/magento/current/pub, that is, to the symlink, not to a fixed release directory. Nginx follows the symlink on every request, so a symlink switch takes effect immediately without an Nginx reload. The same applies to PHP-FPM: the fastcgi_param SCRIPT_FILENAME parameter contains the path resolved through the symlink, which PHP-FPM handles correctly.

One important detail for Nginx with realpath resolution: some Nginx configurations enable root_path caching, which causes Nginx to resolve the symlink only once and then keep using the old path. For symlink releases, it must be ensured that Nginx re-resolves the symlink on every request, or a short Nginx reload after the symlink switch must be made an explicit part of the deploy sequence. Most standard Nginx configurations follow symlinks dynamically, but especially with hardened configurations this point should be tested explicitly.

A simple test after the first symlink switch: set the current symlink path in the Nginx configuration as a static root directive, then switch to a new release path. If Nginx keeps serving the old version afterward, symlink caching is active and an explicit nginx -s reload must be added to the deploy sequence. This test takes two minutes and prevents a hard-to-diagnose problem in production.

The same principle applies to Apache web servers: AllowOverride All and Options +FollowSymLinks must be set so Apache follows symlinks inside the Magento directory. Without this setting, Apache returns 403 errors for requests resolved through a symlink path. Both web server settings should be checked and documented once during server setup, so that new servers do not run into symlink configuration issues.

8. Shared Directories in Both Models

The shared concept is necessary in both deployment models. With symlink releases it is a physical shared/ directory on the server, referenced from each release directory via symlinks. The files exist once but are used by every release directory. With Blue/Green, the shared concept is solved at the infrastructure level: both environments share the same persistent volumes for pub/media/, and both connect to the same database and Redis instance.

The shared problem in both models: app/etc/env.php is environment-specific and must be copied or linked into every release directory. With symlink releases it is copied from the shared/ directory. With Blue/Green it can live as a file on a shared volume or be generated dynamically via a secrets management solution. The file must never end up in the repository or in the build artifact, and that applies equally to both deployment strategies.

9. Comparison: Blue/Green vs. Symlink for Magento

Criterion Blue/Green Symlink Release Recommendation
Infrastructure overhead High (double the servers) Minimal (1 server) Symlink for <99% of shops
Rollback time Seconds (traffic switch) Seconds (symlink switch) Both equally fast
Setup complexity High (LB, 2 environments) Low (directories, symlinks) Symlink is much simpler
Downtime during deploy None Minimal (milliseconds) Practically equivalent
DB migration handling Separable Requires expand/contract Blue/Green for complex DBs
Suitable for Magento Multi-node setups only All setups Symlink is universally applicable

The table confirms the core point: for the vast majority of Magento shops, the symlink release model is the right choice. It achieves the same rollback speed as Blue/Green while requiring a fraction of the infrastructure overhead. Blue/Green should only be chosen when the infrastructure already includes multiple web nodes and a programmable load balancer.

10. Summary

Choosing between Blue/Green and symlink releases is, for most Magento shops, not really a trade-off: symlink releases offer zero-downtime-capable deployments with second-fast rollback at minimal infrastructure cost. Blue/Green adds considerable complexity without delivering real value for single-server setups. Rollback times are practically identical; the difference lies in the infrastructure, not the outcome.

Teams that implement symlink releases consistently, with a correct releases/shared/current structure, atomic symlink switches, and a tested rollback script, end up with a deployment process that is more reliable than many Blue/Green setups that have never been rehearsed for a real failure. The best deployment strategy is the one the team understands, practices regularly, and can execute in seconds when it matters. Both approaches demand the same thing: preparation, documentation, and regular practice of the rollback path, not just when a production failure forces it.

A concrete tip for teams that have not yet settled on a deployment model: start with symlink releases, build the structure cleanly once, and then run three deployments consistently following the same pattern. After those three deployments, the model is understood, practiced, and trustworthy. Blue/Green can be added later as an extension if the infrastructure requires it, but the foundation that symlink releases establish remains valid either way.

The maturity of a deployment process does not show in the first successful deployment, but in the first fast rollback under pressure. Teams that test their rollback path monthly, for example through scheduled rollback drills on staging, build the confidence that makes the difference between panic and routine when a real failure hits. That drill costs five minutes and saves hours in an actual incident.

Blue/Green vs. Symlink Releases: the Essentials at a Glance

Symlink for single servers

releases/, a current symlink, and shared/ are the complete model. ln -sfn is atomic, so there is no downtime window.

Blue/Green for multi-node

Only worthwhile with an existing load balancer and multiple web nodes. Setup effort is significant.

Rollback in seconds

Both models offer second-fast rollback. For symlink: ln -sfn releases/PREV current. No web server restart needed.

Shared directories are critical

pub/media/, var/log/, and env.php must be shared correctly in both models, otherwise rollback only works at the filesystem level.

11. FAQ: Blue/Green vs. Symlink Releases for Magento

1Blue/Green with one server?
Not sensible, it requires two parallel environments. On a single server, symlink release is the right choice with the same rollback speed.
2Is ln -sfn really atomic?
Yes. A single rename() syscall at the kernel level, no intermediate state, no downtime window.
3How many releases to keep?
5 to 10 releases. More allows a longer rollback window but uses more disk space. Oldest is removed automatically.
4Restart PHP-FPM after a symlink switch?
Usually not needed. The opcache should be cleared though: php -r 'opcache_reset();' via CLI after the switch.
5In-flight requests during the symlink switch?
In-flight requests finish processing normally. New requests go to the new release right away. Window: milliseconds.
6Rollback process for symlink releases?
ln -sfn to the previous release directory, then cache:flush. The database schema must be compatible, migrations are not reversible.
7DB migrations with symlink releases?
Expand/contract pattern: backward-compatible changes first, then the code switch, then remove the old DB code.
8Do I need Kubernetes for Blue/Green?
No, it also works with VMs and Nginx/HAProxy. Kubernetes makes it easier but is not a requirement.
9Rollback job in GitLab CI?
A manual job with when: manual in the rollback stage. SSH connection, ln -sfn to the previous release. Always prepared, never improvised.
10Most common mistake with symlink releases?
Switching the symlink too early, before SCD and cache:flush. Correct: finish all Magento steps in the new directory first, only then ln -sfn.

Blue/Green and symlink switching are not mutually exclusive. In mature environments, teams combine both approaches: a symlink switch as an atomic operation inside one of the two Blue/Green slots delivers maximum flexibility at minimal deployment risk.

Teams that start with a simple symlink model still have the option to migrate to Blue/Green later. The investment in a clean release structure pays off in both deployment models.