Alle Artikel
Shopware 65 min

Shopware 6 Docker Deployment mit CI/CD

Docker hat sich als Standard für moderne Shopware 6 Deployments etabliert. In diesem Guide zeige ich dir, wie du ein professionelles Shopware 6 Docker Deployment mit automatisierter CI/CD Pipeline aufsetzt – von der lokalen Entwicklung bis zur Production-Umgebung.

Warum Docker für Shopware 6?

Shopware 6 bringt komplexe Abhängigkeiten mit: PHP 8.1+, MySQL, Elasticsearch, Redis und Node.js für die Administration. Docker löst das klassische "Works on my machine"-Problem und macht dein Shopware 6 Docker Deployment reproduzierbar und skalierbar.

Die wichtigsten Vorteile:

  • Identische Umgebungen in Dev, Staging und Production
  • Einfaches Rollback durch Versionierung
  • Horizontale Skalierung einzelner Services
  • Schnellere Onboarding-Zeiten für neue Entwickler

Docker Compose Setup für Shopware 6

Beginnen wir mit einer Production-ready Docker Compose Konfiguration. Diese bildet die Basis für unser Shopware 6 Docker Deployment:

version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
    volumes:
      - ./custom:/var/www/html/custom
      - ./config:/var/www/html/config
      - files:/var/www/html/files
      - media:/var/www/html/public/media
      - theme:/var/www/html/public/theme
    environment:
      APP_ENV: prod
      APP_URL: ${APP_URL}
      DATABASE_URL: mysql://shopware:${DB_PASSWORD}@database:3306/shopware
      OPENSEARCH_URL: http://opensearch:9200
      REDIS_CACHE_HOST: redis
    depends_on:
      - database
      - opensearch
      - redis
    networks:
      - shopware

  database:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
      MYSQL_DATABASE: shopware
      MYSQL_USER: shopware
      MYSQL_PASSWORD: ${DB_PASSWORD}
    volumes:
      - db-data:/var/lib/mysql
    command: --default-authentication-plugin=mysql_native_password
    networks:
      - shopware

  opensearch:
    image: opensearchproject/opensearch:2.8.0
    environment:
      discovery.type: single-node
      DISABLE_SECURITY_PLUGIN: true
      OPENSEARCH_JAVA_OPTS: "-Xms512m -Xmx512m"
    volumes:
      - opensearch-data:/usr/share/opensearch/data
    networks:
      - shopware

  redis:
    image: redis:7-alpine
    networks:
      - shopware

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./public:/var/www/html/public:ro
      - theme:/var/www/html/public/theme:ro
      - media:/var/www/html/public/media:ro
    depends_on:
      - app
    networks:
      - shopware

volumes:
  db-data:
  opensearch-data:
  files:
  media:
  theme:

networks:
  shopware:

Multi-Stage Dockerfile für Shopware 6

Ein optimiertes Multi-Stage Dockerfile reduziert die Image-Größe und trennt Build- von Runtime-Dependencies:

# Build Stage
FROM node:18-alpine AS node-builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# PHP Build Stage
FROM php:8.2-fpm-alpine AS php-builder
RUN apk add --no-cache \
    icu-dev \
    freetype-dev \
    libjpeg-turbo-dev \
    libpng-dev \
    libzip-dev \
    oniguruma-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) \
        pdo_mysql \
        intl \
        gd \
        opcache \
        zip \
        bcmath

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts

# Production Stage
FROM php:8.2-fpm-alpine AS production
RUN apk add --no-cache \
    icu-libs \
    freetype \
    libjpeg-turbo \
    libpng \
    libzip \
    && docker-php-ext-enable opcache

COPY docker/php/opcache.ini /usr/local/etc/php/conf.d/opcache.ini
COPY docker/php/php.ini /usr/local/etc/php/conf.d/custom.ini

COPY --from=php-builder /usr/local/lib/php/extensions /usr/local/lib/php/extensions
COPY --from=php-builder /var/www/html/vendor /var/www/html/vendor
COPY --from=node-builder /app/node_modules /var/www/html/node_modules

COPY . /var/www/html
RUN chown -R www-data:www-data /var/www/html

USER www-data
EXPOSE 9000
CMD ["php-fpm"]

GitLab CI/CD Pipeline für Shopware 6 Docker Deployment

Automatisierung ist der Schlüssel zu zuverlässigen Deployments. Hier ist eine vollständige GitLab CI/CD Konfiguration:

stages:
  - build
  - test
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

build:
  stage: build
  image: docker:24
  services:
    - docker:24-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build --target production -t $IMAGE_TAG .
    - docker push $IMAGE_TAG
    - docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest
    - docker push $CI_REGISTRY_IMAGE:latest
  only:
    - main
    - develop

test:
  stage: test
  image: $IMAGE_TAG
  services:
    - mysql:8.0
    - name: opensearchproject/opensearch:2.8.0
      alias: opensearch
  variables:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_DATABASE: shopware_test
    DATABASE_URL: mysql://root:root@mysql:3306/shopware_test
    APP_ENV: test
  script:
    - composer install --dev
    - bin/console database:create --if-not-exists
    - bin/console database:migrate --all
    - php vendor/bin/phpunit
  only:
    - main
    - develop

deploy_production:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - ssh-keyscan $PRODUCTION_HOST >> ~/.ssh/known_hosts
  script:
    - |
      ssh $PRODUCTION_USER@$PRODUCTION_HOST << 'EOF'
        cd /var/www/shopware
        docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
        docker-compose pull app
        docker-compose up -d app
        docker-compose exec -T app bin/console system:update:finish
        docker-compose exec -T app bin/console cache:clear
        docker-compose exec -T app bin/console theme:compile
      EOF
  only:
    - main
  when: manual

Zero-Downtime Deployment Strategy

Für Production-Umgebungen ist Zero-Downtime essentiell. Hier eine bewährte Strategie für dein Shopware 6 Docker Deployment:

#!/bin/bash
# deploy.sh - Zero-Downtime Deployment Script

set -e

IMAGE_TAG=$1
COMPOSE_FILE="docker-compose.prod.yml"

echo "Starting deployment of $IMAGE_TAG..."

# Pull new image
docker-compose -f $COMPOSE_FILE pull app

# Create new container without starting
docker-compose -f $COMPOSE_FILE create --force-recreate app

# Run migrations in new container
docker-compose -f $COMPOSE_FILE run --rm app bin/console database:migrate --all

# Start new container
docker-compose -f $COMPOSE_FILE up -d --no-deps app

# Health check
echo "Waiting for application to be ready..."
for i in {1..30}; do
    if docker-compose -f $COMPOSE_FILE exec -T app bin/console system:info > /dev/null 2>&1; then
        echo "Application is ready!"
        break
    fi
    sleep 2
done

# Compile theme and clear cache
docker-compose -f $COMPOSE_FILE exec -T app bin/console theme:compile
docker-compose -f $COMPOSE_FILE exec -T app bin/console cache:clear

# Remove old containers
docker-compose -f $COMPOSE_FILE down --remove-orphans

echo "Deployment completed successfully!"

Performance-Optimierung für Production

Für ein performantes Shopware 6 Docker Deployment sind diese Optimierungen wichtig:

PHP OpCache Konfiguration (docker/php/opcache.ini):

opcache.enable=1
opcache.memory_consumption=256
opcache.interned_strings_buffer=16
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0
opcache.fast_shutdown=1

Nginx Konfiguration mit Caching:

server {
    listen 80;
    server_name _;
    root /var/www/html/public;

    location ~ ^/(theme|media|bundles|sitemap) {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_buffer_size 32k;
        fastcgi_buffers 8 16k;
    }
}

Monitoring und Logging

Für Production-Deployments empfehle ich diese Monitoring-Tools zu integrieren:

// docker-compose.monitoring.yml
services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus-data:/prometheus

  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_PASSWORD}
    volumes:
      - grafana-data:/var/lib/grafana

Troubleshooting häufiger Probleme

Problem: Container startet nicht nach Deployment

# Logs checken
docker-compose logs -f app

# In Container einsteigen
docker-compose exec app sh

Problem: Permission-Fehler

# File Permissions reparieren
docker-compose exec app chown -R www-data:www-data var/ public/

Problem: Theme-Assets fehlen

# Theme neu kompilieren
docker-compose exec app bin/console theme:compile --active-only

Fazit

Ein professionelles Shopware 6 Docker Deployment mit CI/CD erfordert initiale Investition, zahlt sich aber durch Stabilität und Geschwindigkeit aus. Die gezeigte Setup kombiniert Docker Best Practices mit Shopware-spezifischen Anforderungen und ist produktionsreif.

Wichtigste Takeaways:

  • Multi-Stage Builds für kleinere Images
  • Docker Volumes für persistente Daten
  • Health Checks für Zero-Downtime Deployments
  • Automatisierte Tests vor dem Deployment
  • Monitoring von Anfang an einplanen

Du arbeitest an einem Shopware 6 Docker Deployment Projekt? Ich helfe dir gerne bei der Umsetzung einer robusten CI/CD Pipeline und Production-Infrastruktur.

Shopware 6 Docker DeploymentShopware 6FreelancerWebentwicklungDüsseldorf