Skip to content

Instantly share code, notes, and snippets.

@cs278
Last active July 25, 2022 18:19
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cs278/737ca00825c8c5077c4378592ce566be to your computer and use it in GitHub Desktop.
Save cs278/737ca00825c8c5077c4378592ce566be to your computer and use it in GitHub Desktop.
Compile Symfony cache on Platform.sh at build time

Compile Symfony cache at build time

This modification to your Symfony application allows the cache to be warmed at the time Platform.sh builds your application container. The usual advice is to warm the cache in the deploy hook, which can result in ~1 minute of downtime waiting for the cache. Given Symfony’s cache is compiled once and only needs updating if your application code changes, which is impossible on Platform.sh, this allows deployment downtime to be reduced to less than a second.

Assumptions

  • You are using Platform.sh Enterprise.
  • Symfony prod environment is used for all Platform.sh deployments regardless of the Platform environment.
  • You must modify the paths in the build hook to match the expected deployment paths (search for abcxyz1234567).
  • The built image maybe reused between PS & PE, currently this does not seem to be the case but this solution should correctly handle it if Platform.sh did begin to reuse images.

Symfony Kernel

src/Kernel.php

public function getCacheDir(): string
{
    if (false === $cacheDir = getenv('APP_CACHE_DIR')) {
        $cacheDir = $this->getProjectDir().'/var/cache';
    }

    return $cacheDir.'/'.$this->environment;
}

Symfony Configuration

config/packages/prod/framework.yaml

framework:
    cache:
        # Important:
        #
        # Do not configure the system cache, this is compiled by Symfony once when
        # the cache is built in the build hook. It contains things like Doctrine
        # annotations information, basically items that will only change if the
        # code changes.
        app: cache.adapter.redis

Build hook

warm_cache() {
    root="$1"; shift
    export APP_ENV="$1"; shift
    export APP_CACHE_DIR=$(echo "/app/$root/cache/${root:-default}" | sed 's,//,/,g')
    mkdir -p "$APP_CACHE_DIR"

    APP_DEBUG="0" bin/console cache:warmup -vvv
    APP_DEBUG="1" bin/console cache:warmup -vvv
}

cache_branch() {
    branch="$1"; shift
    env="$1"; shift

    mv "$APP_TMP_DIR" "$branch"
    cd "$branch"

    warm_cache "$branch" "$env"

    mv "cache/$branch" "../cache/$branch"
    rmdir "cache"
    cd ..
    mv "$branch" "$APP_TMP_DIR"
}

cache() {
    env="$1"; shift

    # This has to do crazy things to prepare the Symfony cache for the enterprise
    # environments with the correct paths ahead of time.

    # Move everything into /app/.app
    mkdir "$APP_TMP_DIR"
    find -maxdepth 1 -mindepth 1 ! -name "$APP_TMP_DIR" -exec mv -t "$APP_TMP_DIR" {} +

    mkdir "cache" "$APP_TMP_DIR/cache"

    # Compile the cache for each enterprise environment with the correct directory
    # structure.
    cache_branch "abcxyz1234567_stg" "$env"
    cache_branch "abcxyz1234567" "$env"

    # Move everything back out.
    find "$APP_TMP_DIR" -maxdepth 1 -mindepth 1 -exec mv -t . {} +

    # Prepare cache for PS environments.
    warm_cache "" "$env"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment