Running Shopware CE with PaaS

This page explains how to use platform.sh with Shopware's CE.

PaaS (platform as a service) is an alternative for shop owners who want to avoid the hassle of setting up their server with either a traditional or cloud hosting provider. platform.sh is an easy-to-use yet powerful PaaS service.

PaaS is available as an option for users of Shopware 6' paid plans. But PaaS, using providers like platform.sh, is also possible for Shopware CE users. I will try to lay out the main steps for putting your server on platform.sh.

The entire setup is similar to setting up a (paid plan) Shopware instance with Shopware's PaaS service. If in doubt, please refer to the appropriate documentation.

Setup the platform.sh Environment

This is obviously the first step to do - follow the docs on platform.sh. In particular, you need to create a new project that

Prepare your Local Environment to Connect to platform.sh

Install the platform cli tool in your local environment, as described here.

ddev users my want to install just inside the web container, see here.

Also, your gitlab or github repository must be connected to your platform.sh project.

Configure Your Project

Basically, you will need three new files in your project:

  • .platform/routes.yaml

  • .platform/services.yaml

  • .platform.app.yaml

# .platform/routes.yaml
"https://{default}/":
    type: upstream
    id: shopware
    upstream: "shopware:http"
    cache:
        enabled: true
        cookies: ['/^ss?ess/']
# .platform/services.yaml
db:
    type: oracle-mysql:8.0
    disk: 1024

fileshare:
    type: network-storage:2.0
    disk: 2048
# .platform.app.yaml
name: shopware

type: php:8.2
build:
    flavor: composer

dependencies:
    php:
        composer/composer: '^2'

variables:
    env:
        APP_ENV: prod
        DATABASE_URL: "mysql://user:@database.internal:3306/main"
        SHOPWARE_SKIP_BUNDLE_DUMP: 1
        SHOPWARE_SKIP_ASSET_COPY: 1
        SHOPWARE_SKIP_THEME_COMPILE: 1
        PUPPETEER_SKIP_CHROMIUM_DOWNLOAD: 1
        SHOPWARE_ADMIN_BUILD_ONLY_EXTENSIONS: 1
    php:
        upload_max_filesize: 32M
        post_max_size: 32M
        memory_limit: 512M
        'assert.active': 0
        'opcache.enable_file_override': 1
        'opcache.interned_strings_buffer': 20
        'opcache.validate_timestamps': 0
        'zend.detect_unicode': 0
        realpath_cache_ttl: 3600
        'opcache.memory_consumption': 128M
        'opcache.max_accelerated_files': 20000

runtime:
    extensions:
        - ctype
        - dom
        - iconv
        - mbstring
        - fileinfo
        - intl
        - redis
        - sodium

hooks:
    build: |
        set -e
        
        echo "B U I L D - start"
               
        touch install.lock
        
        export CI=true
        bin/ci bundle:dump -n
        bin/ci feature:dump -n
        bin/build-js.sh
        bin/ci administration:delete-files-after-build -n
        
        echo "B U I L D - end"

    deploy: |
        set -e
        
        echo "D E P L O Y start"
        
        if [ "$PLATFORM_ENVIRONMENT_TYPE" != production ]; then
            export FRONTEND_URL=`echo $PLATFORM_ROUTES | base64 --decode | jq -r 'to_entries[] | select(.value.id=="shopware") | .key'`
            export FRONTEND_DOMAIN=`php -r 'echo parse_url($_SERVER["FRONTEND_URL"], PHP_URL_HOST);'`
            export APP_URL="$FRONTEND_DOMAIN"
            bin/console sales-channel:update:domain "$FRONTEND_DOMAIN"
        fi
        
        bin/console database:migrate --all -n
        
        bin/console plugin:refresh --skipPluginList -n
        bin/console plugin:update:all -n
        
        bin/console theme:compile --keep-assets --active-only -n
        
        bin/console assets:install -n
        bin/console administration:delete-extension-local-public-files -n
        
        echo "D E P L O Y end"

relationships:
    database: "db:mysql"

disk: 1024

source:
    root: shopware

mounts:
    "/files":
        source: service
        service: fileshare
        source_path: "files"
    "/public/media":
        source: service
        service: fileshare
        source_path: "public/media"
    "/public/theme":
        source: service
        service: fileshare
        source_path: "public/theme"
    "/public/thumbnail":
        source: service
        service: fileshare
        source_path: "public/thumbnail"
    "/config/secrets":
        source: service
        service: fileshare
        source_path: "config/secrets"
    "/var":
        source: service
        service: fileshare
        source_path: "var"
    "/var/cache":
        source: local
        source_path: "var/cache"
    "/installer":
        source: local
        source_path: "installer"
    "/.global":
        source: local
        source_path: "global"
    "/.cache":
        source: local
        source_path: ".cache"

web:
    locations:
        "/":
            root: "public"
            passthru: "/index.php"
            expires: 24h
            rules:
                \.(css|js|gif|jpe?g|png|ttf|eot|woff2?|otf|cast|mp4|json|yaml|ico|svg?|cast|mp4|json|yaml|svg?|ttf)$:
                    expires: 4w

workers:
    queue:
        disk: 128
        commands:
            start: |
                bin/console cache:clear
                bin/console messenger:consume async failed --memory-limit=$(cat /run/config.json | jq .info.limits.memory)M --time-limit=295

crons:
    scheduler:
        spec: '*/5 * * * *'
        cmd: 'php bin/console scheduled-task:run --no-wait'

Generate JWT Secrets

Whilst JWT secrets are usually stored in the folder config/jwt within your project, this approach does not work with platform.sh. Instead, the secrets need to be stored as project variables.

Run the following command locally:

platform ssh --app=shopware "bin/console system:generate-jwt-secret --use-env" |\
grep -E "^JWT_(PUBLIC|PRIVATE)_KEY=" |\
while read line ; do \
platform variable:create --sensitive 1 --level project --name env:$(echo $line | cut -d "=" -f 1) --value $(echo $line | cut -d "=" -f 2-); \
done

Then add a config file config/packages/prod/z-shopware.yaml to your project folder.

# config/packages/prod/z-shopware.yaml
shopware:
    api:
        jwt_key:
            private_key_path: '%env(base64:JWT_PRIVATE_KEY)%'
            public_key_path: '%env(base64:JWT_PUBLIC_KEY)%'

Deploy Your Project

Deploying now just means pushing the appropriate branch of your project to your repo. (This is the branch you have associated with a project environment on the platform.sh side.) platform.sh will then automatically run the deployment script as defined in your .platform.app.yaml file.

Upload your Media Files and Database to platform.sh

Use the platform cli to upload your media files:

platform mount:upload --mount public/media --source shared/public/media
platform mount:upload --mount public/thumbnail --source shared/public/thumbnail

And upload your database using the following command:

platform sql <your-database>.sql

Last updated