Files
computer-playbook/roles/web-app-shopware/README.md
T
kevinveenbirkenbachandClaude Opus 5.5 dd955a71a6 style(markdown): pin list markers to dash and convert every list
The 16.0.0 entry pkgmgr wrote on top of CHANGELOG.md uses "-" bullets
while every older entry uses "*". MD004's default "consistent" style takes
the marker of the first list in a file, so lint-markdown reported 400
MD004 findings in CHANGELOG.md and the pre-push gate refused the release
push.

MD004 is now pinned to "dash", the marker pkgmgr and the changelog skill
write, and make autoformat (markdownlint-cli2 --fix) converted the lists
of the 72 files that still used "*". Only list markers changed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-18 23:04:02 +02:00

7.8 KiB

Shopware

Description

Empower your e-commerce vision with Shopware 6, a modern, flexible, and open-source commerce platform built on Symfony and Vue.js. Designed for growth and innovation, it enables seamless integration, outstanding customer experiences, and complete control over your digital business. Build, scale, and sell with confidence.

Overview

This role deploys Shopware 6 using Docker. It automates installation, migration, and configuration of your storefront, integrating with a central MariaDB database. Optional components like Redis and OpenSearch enhance performance and search capabilities, while OIDC integrates the administration backend with Keycloak. Directory accounts sign in the same way: Shopware has no admin-LDAP extension this role can install, so LDAP identities arrive through Keycloak's user federation rather than through a plugin of their own.

With automated setup, update handling, variable management, and plugin-based authentication, this role simplifies the deployment and maintenance of your Shopware instance.

Cosmos

The diagram places Shopware in the Infinito.Nexus cosmos: the components it deploys (capabilities), the central services it consumes (dependencies), and its outward reach (federation and bridged external networks).

flowchart LR
    subgraph deps [Dependencies]
        dep_svc_bkp_volume_2_local["svc-bkp-volume-2-local 💻"]
        dep_svc_db_mariadb["svc-db-mariadb 🐳🐝"]
        dep_svc_db_openldap["svc-db-openldap 🐳🐝"]
        dep_svc_db_redis["svc-db-redis 🐳🐝"]
        dep_svc_net_tor["svc-net-tor 🐳🐝"]
        dep_web_app_dashboard["web-app-dashboard 🐳🐝"]
        dep_web_app_keycloak["web-app-keycloak 🐳🐝"]
        dep_web_app_matomo["web-app-matomo 🐳🐝"]
        dep_web_app_prometheus["web-app-prometheus 🐳🐝"]
        dep_web_app_seaweedfs["web-app-seaweedfs 🐳🐝"]
        dep_web_app_stalwart["web-app-stalwart 🐳🐝"]
        dep_web_svc_css["web-svc-css 💻"]
        dep_web_svc_logout["web-svc-logout 🐳🐝"]
    end
    subgraph role [web-app-shopware 🐳🐝]
        svc_logout["logout"]
        svc_sso["sso"]
        svc_ldap["ldap"]
        svc_dashboard["dashboard"]
        svc_matomo["matomo"]
        svc_email["email"]
        svc_mariadb["mariadb"]
        svc_init["init"]
        svc_shopware["shopware"]
        svc_php["php"]
        svc_web["web"]
        svc_worker["worker"]
        svc_scheduler["scheduler"]
        svc_redis["redis"]
        svc_opensearch["opensearch"]
        svc_seaweedfs["seaweedfs"]
        svc_css["css"]
        svc_prometheus["prometheus"]
        svc_tor["tor"]
        svc_container_backup["container_backup"]
    end
    dep_svc_bkp_volume_2_local -. "0..1" .-> svc_container_backup
    dep_svc_db_mariadb -. "0..1" .-> svc_mariadb
    dep_svc_db_openldap -. "0..1" .-> svc_ldap
    dep_svc_db_redis -. "0..1" .-> svc_redis
    dep_svc_net_tor -. "0..1" .-> svc_tor
    dep_web_app_dashboard -. "0..1" .-> svc_dashboard
    dep_web_app_keycloak -. "0..1" .-> svc_sso
    dep_web_app_matomo -. "0..1" .-> svc_matomo
    dep_web_app_prometheus -. "0..1" .-> svc_prometheus
    dep_web_app_seaweedfs -. "0..1" .-> svc_seaweedfs
    dep_web_app_stalwart -. "0..1" .-> svc_email
    dep_web_svc_css -. "0..1" .-> svc_css
    dep_web_svc_logout -. "0..1" .-> svc_logout

Solid 1:1 edges are fixed relationships; dashed 0..1 edges are conditional (enabled only in matching deployments); red 0..0 edges are turned off in this role. Node markers show the role's deploy modes (💻 host, 🐳 compose, 🐝 swarm); ❌ marks a service that is explicitly turned off, and ⚙️ an Ansible role dependency declared in meta/main.yml.

Features

  • Modern and Scalable: A robust Symfony-based framework optimized for commerce innovation.
  • Automated Setup & Maintenance: Installs, migrates, and configures Shopware automatically.
  • Extensible Architecture: Optional Redis, OpenSearch, and plugin-based IAM integrations.
  • Centralized Database Access: Connects seamlessly to the shared MariaDB service.
  • Integrated Configuration: Environment and Docker Compose variables managed automatically.

Quick Setup

Development

Clone, set up the workstation, and deploy Shopware onto the local stack:

git clone https://github.com/infinito-nexus/core.git
cd core
make onboard
make compose-deploy mode=reinstall apps=web-app-shopware full_cycle=false

Production

Run the published image to provision the inventory and deploy Shopware to a managed server (the mounted volume persists the inventory):

APP=web-app-shopware
HOST=<your-server>
DOMAIN=<your-domain>
TLS_MODE=self_signed
SSH_PUBLIC_KEY="<your-ssh-public-key>"

docker run --rm -it \
  -v "$PWD/inventories:/etc/infinito.nexus/inventories" \
  -e APP="$APP" -e HOST="$HOST" -e DOMAIN="$DOMAIN" -e TLS_MODE="$TLS_MODE" -e SSH_PUBLIC_KEY="$SSH_PUBLIC_KEY" \
  ghcr.io/infinito-nexus/core/debian bash -c '
    INVENTORY=/etc/infinito.nexus/inventories/production
    infinito administration inventory provision "$INVENTORY" \
      --inventory-file "$INVENTORY/devices.yml" \
      --host "$HOST" \
      --include "$APP" \
      --vars "{\"TLS_MODE\": \"$TLS_MODE\", \"DOMAIN_PRIMARY\": \"$DOMAIN\", \"users\": {\"administrator\": {\"authorized_keys\": [\"$SSH_PUBLIC_KEY\"]}}}" &&
    infinito administration deploy dedicated "$INVENTORY/devices.yml" \
      --password-file "$INVENTORY/.password" \
      --diff -vv'

Further Resources

Persona contract opt-outs

tasks/01_admin.yml provisions only the administrator in Shopware's user table. meta/services.yml pins services.sso.flavor: oidc, so no oauth2-proxy fronts the role and the storefront carries no authenticated surface at all; the Keycloak login provider that tasks/setup/oidc.yml configures covers the administration backend alone. biber therefore has no account in any matrix variant and templates/playwright.env.j2 renders PERSONA_BIBER_BLOCKED=true unconditionally.

PERSONA_ADMINISTRATOR_BLOCKED=true is declared because the shared helper cannot reach Shopware's logout, not because the journey is untestable. The only logout control lives in .sw-admin-menu__user-actions, which the administration stylesheet keeps at display: none until its toggle is clicked, and that toggle is a bare div carrying no role, no aria-haspopup and no dropdown class — nothing in the helper's trigger set matches it. Its second fallback, following a same-origin settings link, misses as well because the administration is hash-routed and every settings target is #/sw/settings/....

The journey itself is not dropped. files/playwright/test-admin-native.js drives it through Shopware's own selectors: an authenticated backend assertion, then logout through the user-actions toggle and back to the login form. SSO_SERVICE_ENABLED selects how it signs in — through the a.heptacom-admin-open-auth--button provider link that AdminOpenAuth appends into .sw-login__content when SSO is on, through the native password form when it is off. The guest persona and the role-local reachability, TLS and HSTS assertions run unconditionally.

Credits

Implemented by Kevin Veen-Birkenbach. Part of the Infinito.Nexus Project and maintained by Kevin Veen-Birkenbach. Licensed under the Infinito.Nexus Community License (Non-Commercial).