Keeping indexers, cache and database under control
A generic blue green deployment simply swaps two container versions. For Magento that is not enough, because indexers, cache, sessions and database migrations complicate the color switch. This article shows how blue green deployments for Magento in containers are built so the traffic switch actually happens without downtime and without inconsistent data.
Table of Contents
- 1. Why generic blue green is not enough for Magento
- 2. Two parallel stacks: blue and green in the container setup
- 3. Preparing static content and DI compile per color
- 4. Indexer strategy: reindex on the inactive color
- 5. Making database migrations backward compatible
- 6. Cache and session warmup before the switch
- 7. Health checks and readiness gates for the color switch
- 8. Traffic switch at the reverse proxy
- 9. Blue green vs. rolling deployment for Magento compared
- 10. Summary
- 11. FAQ
1. Why generic blue green is not enough for Magento
A classic blue green deployment assumes two identical environments run in parallel and the load balancer redirects traffic from the old to the new version with a single switch. For a stateless API that works without major complications. With Magento, however, several states come into play that must be kept in sync during the color switch: search indices, cache entries, sessions, carts, and the database schema itself.
Anyone who implements a blue green deployment for Magento naively and simply runs two container versions against the same database risks the new version working with stale indices, or the old version breaking due to an already migrated database schema. The result is broken product pages, wrong prices in the search index, or aborted checkouts, precisely during the critical switch window.
This article describes how a Magento blue green deployment with containers accounts for the specifics of indexers, cache and database, so the switch between colors actually runs without interruption instead of only being downtime free on paper.
2. Two parallel stacks: blue and green in the container setup
The basic structure of a blue green deployment for Magento consists of two fully functional container stacks that differ only in their code version but use the same database and the same Redis cluster. This shared data layer is the decisive difference from generic blue green setups: Magento cannot simply maintain two separate databases without duplicating or losing orders, customers and carts.
Every stack, whether blue or green, gets its own PHP-FPM container, its own Nginx container and its own volumes for static content and generated code. The shared services, database, Redis and OpenSearch, persist across both colors and are never duplicated. This split ensures that a blue green deployment for Magento only switches the application code while the data state stays consistent.
# docker-compose.blue-green.yml — shared data layer, two app stacks
services:
magento-blue:
image: registry.mironsoft.de/magento-shop:${BLUE_TAG}
environment:
DEPLOY_COLOR: blue
DB_HOST: mysql
REDIS_HOST: redis
OPENSEARCH_HOST: opensearch
volumes:
- static_blue:/var/www/html/pub/static
- generated_blue:/var/www/html/generated
networks: [backend]
magento-green:
image: registry.mironsoft.de/magento-shop:${GREEN_TAG}
environment:
DEPLOY_COLOR: green
DB_HOST: mysql
REDIS_HOST: redis
OPENSEARCH_HOST: opensearch
volumes:
- static_green:/var/www/html/pub/static
- generated_green:/var/www/html/generated
networks: [backend]
mysql:
image: mysql:8.0
networks: [backend]
redis:
image: redis:7-alpine
networks: [backend]
opensearch:
image: opensearchproject/opensearch:2
networks: [backend]
volumes:
static_blue:
static_green:
generated_blue:
generated_green:
networks:
backend:
3. Preparing static content and DI compile per color
Before a color goes live in a blue green deployment, setup:di:compile and setup:static-content:deploy must have run to completion on that color. Ideally this already happens during the container build, not only after the container starts, so the first request on the new color does not run into a slow on the fly compile. This preparation is more involved for Magento than for most other applications, because generated code and compiled static files depend directly on the respective codebase.
Important for a clean blue green deployment with Magento: static content and generated code must never be shared between blue and green, even if the database is shared. A shared static content volume would cause the old color to suddenly serve new, incompatible JavaScript bundles before the actual switch has even happened.
#!/usr/bin/env bash
# prepare-green.sh — build and warm up the inactive color before the switch
set -euo pipefail
COLOR="green"
IMAGE_TAG="${1:?Usage: prepare-green.sh <image-tag>}"
echo "[INFO] Building ${COLOR} stack with tag ${IMAGE_TAG}"
docker compose -f docker-compose.blue-green.yml build "magento-${COLOR}"
echo "[INFO] Running DI compile and static content deploy inside ${COLOR}"
docker compose -f docker-compose.blue-green.yml run --rm "magento-${COLOR}" \
bin/magento setup:di:compile
docker compose -f docker-compose.blue-green.yml run --rm "magento-${COLOR}" \
bin/magento setup:static-content:deploy -f de_DE en_US
echo "[OK] ${COLOR} stack ready for reindex and health checks"
4. Indexer strategy: reindex on the inactive color
Magento indexers run either in Update on Save or Update by Schedule mode. For a blue green deployment, Update by Schedule is almost always the right choice, because the reindex then runs through the cron of the currently active color while the inactive color is being prepared. The critical point: the full reindex must be complete on the new color before it receives traffic, otherwise it serves stale prices, stock levels or search results on the first request.
Since the indexer and search index in OpenSearch are shared between blue and green, a running reindex during a blue green deployment for Magento can theoretically affect both colors at once. That is why the reindex should only start once the new code is fully deployed but not yet live, and the indexer status must be checked explicitly for ready before the switch, not merely for a job count of zero.
#!/usr/bin/env bash
# reindex-and-verify.sh — reindex on the inactive color, verify before switch
set -euo pipefail
COLOR="green"
echo "[INFO] Reindexing all indexers on ${COLOR}"
docker compose -f docker-compose.blue-green.yml exec "magento-${COLOR}" \
bin/magento indexer:reindex
STATUS=$(docker compose -f docker-compose.blue-green.yml exec -T "magento-${COLOR}" \
bin/magento indexer:status | grep -c "Ready" || true)
TOTAL_INDEXERS=$(docker compose -f docker-compose.blue-green.yml exec -T "magento-${COLOR}" \
bin/magento indexer:status | grep -c "Indexer:" || true)
if [[ "$STATUS" -ne "$TOTAL_INDEXERS" ]]; then
echo "[ERROR] Not all indexers are ready on ${COLOR}: ${STATUS}/${TOTAL_INDEXERS}" >&2
exit 1
fi
echo "[OK] All ${TOTAL_INDEXERS} indexers ready on ${COLOR}"
5. Making database migrations backward compatible
Since blue and green use the same database, every schema change in a Magento blue green deployment must be designed so that both the old and the new code work with the same database structure during the transition phase. Dropping a column that the old code still reads would immediately crash the old color with a database error, even though it is technically still active.
The proven practice for schema changes in a blue green deployment for Magento is a two stage approach spanning two releases: in the first release only a new column is added, never removing or renaming an existing one. Only in the release after next, once it is certain no old color still depends on the old structure, is the obsolete column removed. This additive migration strategy is the core difference between a blue green deployment that only works on paper and one that actually stays outage free in production.
6. Cache and session warmup before the switch
A cold started Magento container answers the first requests noticeably slower, because config cache, layout cache and block HTML cache first need to be filled. For a blue green deployment that means: before the new color receives traffic, a warmup script should call the most important category and product pages as well as the homepage, so the full page cache in Varnish or the built in Magento cache is already filled.
Sessions remain untouched by the color switch in a correctly configured blue green deployment for Magento, as long as Redis is configured as central, shared session storage between both colors. A customer with an active cart notices nothing of the application color change in the ideal case, because their session ID remains valid and is simply served by the new PHP-FPM container instead of the old one.
7. Health checks and readiness gates for the color switch
The traffic switch in a blue green deployment must only happen once an automated health check reports the new color as fully ready. A simple HTTP 200 check on the homepage is not enough for that, because Magento can still deliver a status 200 page with incompletely compiled code or a half finished reindex. A meaningful health check endpoint instead specifically checks database connectivity, Redis reachability, OpenSearch status and indexer state.
Only once this multi stage health check is green does the inactive color count as ready for the switch. This readiness gate is the difference between a blue green deployment for Magento that runs automated and safe, and one where someone decides manually and under time pressure whether the switch is already safe.
#!/usr/bin/env bash
# health-gate.sh — readiness gate before switching traffic
set -euo pipefail
COLOR="green"
BASE_URL="http://magento-${COLOR}:8080"
check_endpoint() {
local path="$1"
local expected="$2"
local response
response=$(curl -s -o /dev/null -w "%{http_code}" "${BASE_URL}${path}")
[[ "$response" == "$expected" ]] || { echo "[FAIL] ${path} returned ${response}"; return 1; }
}
echo "[INFO] Running readiness checks for ${COLOR}"
check_endpoint "/health/db" "200"
check_endpoint "/health/redis" "200"
check_endpoint "/health/opensearch" "200"
check_endpoint "/health/indexer" "200"
echo "[OK] ${COLOR} passed all readiness checks, safe to switch traffic"
8. Traffic switch at the reverse proxy
The actual traffic switch in a blue green deployment for Magento happens at the reverse proxy, not inside Magento itself. With Traefik this happens by rewriting a Docker label that defines which service is responsible for the production domain, followed by a reload of the proxy configuration. With Nginx the upstream definition is swapped instead and an nginx -s reload is executed, which does not interrupt running connections.
After the switch, the old color stays reachable as a rollback target for a defined period, often 15 to 30 minutes, but without production traffic. Only once monitoring and error rates of the new color are stable is the old color shut down or reused as the new inactive color for the next blue green deployment.
9. Blue green vs. rolling deployment for Magento compared
Besides blue green, other deployment strategies exist for Magento that fit differently depending on team size and infrastructure. The following table contrasts the key differences.
| Criterion | Blue-Green | Rolling Deployment | Recommendation for Magento |
|---|---|---|---|
| Rollback speed | Instant via switch back | Gradual, slower | Blue-green for critical shops |
| Resource demand | Double during the switch | Only slightly higher | Rolling for tight budgets |
| Indexer complexity | Reindex needed before switch | Reindex during rollout | Both need Update by Schedule |
| Schema migrations | Additive, two stage | Additive, two stage | Same rules for both |
| Testability before going live | Full prod environment testable | Only canary share testable | Blue-green for high risk |
For Magento shops with high revenue per hour, the advantage of an instant rollback in a blue green deployment outweighs the higher resource demand during the switch window. For smaller shops with a tight infrastructure budget, a rolling deployment with the same indexer and migration rules is often the more pragmatic choice.
Mironsoft
Zero downtime deployments for Magento shops
Magento deployments without downtime and without headaches?
We build blue green pipelines for Magento that correctly orchestrate indexers, static content and database migrations, with automated health checks and a safe rollback path.
Deployment audit
Reviewing existing deployment pipelines for downtime risks
Blue-green setup
Setting up container stacks, health gates and traffic switch production ready
Migration strategy
Establishing backward compatible schema changes for safe rollbacks
10. Summary
A working blue green deployment for Magento differs significantly from a generic blue green setup for stateless applications. Indexers must have run to completion on the inactive color before traffic switches, static content and generated code must never be shared, and database migrations must stay additive and backward compatible across at least two releases, because both colors use the same database.
A multi stage health check that verifies database, Redis, OpenSearch and indexer status is the readiness gate that decides when the color switch is actually safe. With this combination of a shared data layer, additive migrations and automated readiness checks, a blue green deployment for Magento becomes a reliable, repeatable routine instead of a risky special event.
Magento Blue Green Deployments — Key Takeaways
Data layer
Database and Redis are shared between blue and green, never duplicated.
Indexers
Full reindex on the inactive color, status explicitly checked for ready.
Migrations
Only additive schema changes, obsolete columns removed two releases later.
Traffic switch
Only after a green health check via reverse proxy labels, old color stays the rollback target.