Shopware 6 Production and Staging Environment (2/2)
Complete Setup and Automated Deployment Guide
Table of Contents
This guide is divided into two parts:
- Part 1: Server Environment Setup (Production & Staging) - Basic Infrastructure
- Part 2: Development Environment and Automated Deployment - CI/CD Pipeline
Part 2: Development Environment and Automated Deployment
In Part 1, we built the Shopware6 production and staging environment on the server. Part 2 covers everything from local development environment setup to implementing automated deployment. The following steps show how to build an efficient development environment and implement automated deployment with GitHub Actions.
1. Prepare Local Development Environment
Why a Good Development Environment Matters
A well-configured development environment should give you:
- Production Parity: Same PHP and Node.js versions as your servers
- Quick Setup: Get up and running with minimal effort using Dockware
- Debugging Power: Step-through debugging and profiling with Xdebug
- Fast Feedback: Instant file change detection and reloading
Let’s get your local Shopware6 development environment ready.
Verify Docker Installation
First, make sure Docker is installed and running:
docker --version
docker-compose --version
Create Project Directory
mkdir shopware-project
cd shopware-project
2. Shopware6 Setup with Dockware
Create Initial docker-compose.yml
nano docker-compose.yml
Enter the following content:
services:
shopware:
image: dockware/dev:latest # Specify same version as production environment
container_name: shopware # Container name
ports:
- "80:80"
- "3306:3306"
- "22:22"
- "8888:8888"
- "9999:9999"
- "9998:9998"
networks:
- web
environment:
- XDEBUG_ENABLED=1
- PHP_VERSION=8.3 # Same version as production environment
- NODE_VERSION=22 # Same version as production environment
networks:
web:
external: false
Shopware6 Initial Installation
# Start container
docker compose up -d
# Check container start
docker ps
# Copy Shopware files to host
mkdir -p ./src
docker cp shopware:/var/www/html/. ./src
# Set permissions
docker exec -it shopware bash -c 'sudo chown www-data:www-data /var/www/html -R'
# Stop container once
docker compose down
Update docker-compose.yml
Replace with the following content:
services:
shopware:
image: dockware/dev:latest
container_name: shopware
volumes:
- "./src:/var/www/html/"
# Exclusion volumes (managed in container)
- "/var/www/html/.git/"
- "/var/www/html/public/build"
- "/var/www/html/var/cache"
- "/var/www/html/vendor"
- "db_volume:/var/lib/mysql"
ports:
- "80:80"
- "3306:3306"
- "22:22"
- "8888:8888"
- "9999:9999"
- "9998:9998"
networks:
- web
environment:
- XDEBUG_ENABLED=1
- PHP_VERSION=8.3
- NODE_VERSION=22
volumes:
db_volume:
driver: local
networks:
web:
external: false
Start and Check Development Environment
# Restart container
docker compose up -d
# Check in browser
echo "Shop: http://localhost"
echo "Admin: http://localhost/admin (admin/shopware)"
3. Git Management Configuration for Project
Create .gitignore File
Enter the following content:
# IDE
/.idea
/.vscode
# Dependencies
/vendor/
/node_modules/
# Environment files
.env.local
.env.local.php
.env.*.local
# Generated/Compiled Assets
/public/bundles/
/public/css/
/public/fonts/
/public/js/
/public/theme/
/public/asset-manifest.json
# Cache & Temporary Files
/public/thumbnail/*
/public/sitemap/*
/public/media/cache/
/public/media/temp/
/var/cache/
/var/log/
/var/session/
/files/cache/
/files/temp/
/files/media_tmp/
# Security & Installation
/auth.json
/install.lock
/config/jwt/
# Shopware export files
/files/export/
# Docker
docker-compose.override.yml
# Keep important directories
!/var/.htaccess
!/files/.htaccess
# Custom plugins managed by Composer
/custom/plugins/*
!/custom/plugins/.gitkeep
4. Add Necessary Dependencies
Add Deployer-related packages in container:
# Enter container
docker exec -it shopware bash
# Install Deployer-related packages
composer require deployer/deployer shopware/deployment-helper
# Exit container
exit
5. Deployer Configuration
Create deploy.php File
nano deploy.php
Enter the following content (change server IP address accordingly):
<?php
namespace Deployer;
require_once 'recipe/common.php';
require_once 'contrib/cachetool.php';
set('bin/console', '{{bin/php}} {{release_or_current_path}}/bin/console');
set('cachetool', '/run/php/php8.3-fpm.sock');
set('application', 'Shopware 6');
set('allow_anonymous_stats', false);
set('default_timeout', 3600);
// Staging environment configuration
host('staging')
->setHostname('YOUR_SERVER_IP') // Change to server IP address
->setLabels([
'type' => 'web',
'env' => 'staging',
])
->setRemoteUser('www-data')
->set('deploy_path', '/var/www/shopware-staging')
->set('http_user', 'www-data')
->set('writable_mode', 'chmod')
->set('keep_releases', 3);
// Production environment configuration
host('production')
->setHostname('YOUR_SERVER_IP') // Change to server IP address
->setLabels([
'type' => 'web',
'env' => 'production',
])
->setRemoteUser('www-data')
->set('deploy_path', '/var/www/shopware-prod')
->set('http_user', 'www-data')
->set('writable_mode', 'chmod')
->set('keep_releases', 3);
// Shared files
set('shared_files', [
'.env.local',
'install.lock',
'public/.htaccess',
'public/.user.ini',
]);
// Shared directories
set('shared_dirs', [
'config/jwt',
'files',
'var/log',
'public/media',
'public/thumbnail',
'public/sitemap',
'custom/plugins',
'custom/apps',
]);
// Writable directories
set('writable_dirs', [
'config/jwt',
'files',
'public/bundles',
'public/css',
'public/fonts',
'public/js',
'public/media',
'public/sitemap',
'public/theme',
'public/thumbnail',
'var',
]);
// Shopware-specific tasks
task('sw:deployment:helper', static function() {
run('cd {{release_path}} && vendor/bin/shopware-deployment-helper run');
});
task('sw:assets:install', static function() {
run('cd {{release_path}} && {{bin/console}} assets:install');
});
task('sw:touch_install_lock', static function () {
run('cd {{release_path}} && touch install.lock');
});
task('sw:health_checks', static function () {
run('cd {{release_path}} && bin/console system:check --context=pre_rollout');
});
// Upload task
task('deploy:update_code')->setCallback(static function () {
upload('.', '{{release_path}}', [
'options' => [
'--exclude=.git',
'--exclude=deploy.php',
'--exclude=node_modules',
'--exclude=.github',
],
]);
});
// Main deployment task
desc('Deploys your project');
task('deploy', [
'deploy:prepare',
'deploy:clear_paths',
'sw:deployment:helper',
'sw:assets:install',
'sw:touch_install_lock',
'deploy:publish',
]);
// Hooks
after('deploy:failed', 'deploy:unlock');
after('deploy:symlink', 'cachetool:clear:opcache');
after('sw:touch_install_lock', function () {
if (get('labels')['env'] === 'production') {
invoke('sw:health_checks');
}
});
6. Generate and Configure SSH Keys
Generate SSH Keys Locally
# Generate SSH key
ssh-keygen -t ed25519 -f ~/.ssh/shopware_deploy
# Copy public key
cat ~/.ssh/shopware_deploy.pub
Add Public Key to Server
Execute the following on server:
# Add public key to authorized_keys (YOUR_SSH_PUBLIC_KEY_CONTENT is the content copied above)
sudo -u www-data tee -a /var/www/.ssh/authorized_keys << 'EOF'
YOUR_SSH_PUBLIC_KEY_CONTENT_HERE
EOF
# Set permissions
sudo chmod 600 /var/www/.ssh/authorized_keys
SSH Connection Test
# Connection test from local
ssh -i ~/.ssh/shopware_deploy www-data@YOUR_SERVER_IP
7. GitHub Actions Workflow Configuration
Smart Branching Strategy
- staging: Every push automatically deploys to staging for testing
- main: Production deployments (only merge after staging verification!)
Create .github/workflows Directory
mkdir -p .github/workflows
Workflow for Staging Environment
nano .github/workflows/deploy-staging.yml
Enter the following content:
name: Deploy to Staging
on:
push:
branches:
- staging
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
- name: Install Shopware CLI
uses: shopware/shopware-cli-action@v1
- name: Build
run: shopware-cli project ci .
- name: Deploy
uses: deployphp/action@v1
with:
dep: deploy staging
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
Explanation of GitHub Actions Steps
Role of each step:
Checkout: Download repository code to runnerSetup PHP: Prepare same PHP 8.3 as production environmentInstall Shopware CLI: Install Shopware6-specific build toolBuild: Asset build and optimization (shopware-cli project cicommand)Deploy: Deployment to server with Deployer
Workflow for Production Environment
nano .github/workflows/deploy-production.yml
Enter the following content:
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "8.3"
- name: Install Shopware CLI
uses: shopware/shopware-cli-action@v1
- name: Build
run: shopware-cli project ci .
- name: Deploy
uses: deployphp/action@v1
with:
dep: deploy production
private-key: ${{ secrets.SSH_PRIVATE_KEY }}
8. Create and Configure GitHub Repository
Initialize Repository
# Initialize Git repository
git init
# Create .gitkeep file
touch custom/plugins/.gitkeep
# First commit
git add .
git commit -m "Initial commit"
# Add remote after creating GitHub repository
git remote add origin https://github.com/your-username/your-shopware-project.git
git branch -M main
git push -u origin main
# Create staging branch
git switch -c staging
git push -u origin staging
Configure GitHub Secrets
Copy Private Key
# Copy private key locally
cat ~/.ssh/shopware_deploy
Add Secret in GitHub Repository Settings
- Open repository page
Settings>Secrets and variables>Actions - Click
New repository secret - Add as follows:
- Name:
SSH_PRIVATE_KEY - Value: Paste copied private key (from
-----BEGIN OPENSSH PRIVATE KEY-----to-----END OPENSSH PRIVATE KEY-----)
9. Custom Plugin Management
Benefits of VCS Management
By managing custom plugins in separate repositories:
- Independent Development: Plugin and main project independent
- Version Management: Individual versioning of plugins
- Reusability: Same plugins usable in other projects
- Team Development: Easy collaboration with plugin development team
When managing custom plugins in separate repositories:
Update composer.json
Add the following to composer.json:
{
"require": {
"your-org/your-plugin": "dev-develop"
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/your-org/your-plugin.git"
}
]
}
Environment-specific Configuration Examples
Staging Environment (for development and testing):
"your-org/your-plugin": "dev-develop"
Production Environment (only stable versions):
"your-org/your-plugin": "^1.0.0"
Configure GitHub Access Token
A access token is required to access GitHub repositories. Generate token on GitHub and configure in Shopware container.
# Execute in container
docker exec -it shopware bash
composer config --global github-oauth.github.com YOUR_GITHUB_TOKEN
exit
Server Configuration (PHP-FPM Settings)
Add the following configuration to /etc/php/8.3/fpm/pool.d/www.conf.
Without this configuration, errors occur during Shopware updates:
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[GIT_EXEC_PATH] = /usr/bin
env[COMPOSER_AUTH] = '{"github-oauth":{"github.com":"YOUR_ACTUAL_TOKEN_HERE"}}'
After configuration, restart PHP-FPM:
sudo systemctl restart php8.3-fpm
10. Execute First Deployment
Check Deployment Flow
First deployment flow:
- Staging: Push to staging branch and function check
- Production Preparation: After confirmation in staging, merge to main branch
- Production Deployment: Push to main branch for automated deployment
Deployment to Staging Environment
# Switch to staging branch
git switch staging
# Push changes (GitHub Actions will run automatically)
git push origin staging
Activate Staging Mode
After deployment completion, execute the following on server:
# Switch to staging directory
cd /var/www/shopware-staging/current
# Activate staging mode
bin/console system:setup:staging
# Clear cache
bin/console cache:clear
exit
Effect of Staging Mode:
- Prevents search engine indexing
- Adds “Staging” display to admin panel
- Clear distinction from production environment
Deployment to Production Environment
# Switch to main branch
git switch main
# Merge changes from staging
git merge staging
# Push (GitHub Actions will run automatically)
git push origin main
Summary
Benefits of the Built System
Through these steps, a Shopware6 production and staging environment as well as automated deployment system with the following benefits can be built:
- Security: Firewall configuration, SSH key authentication, environment separation
- Performance: PHP-FPM, Caddy optimization, OPcache utilization
- Operability: Zero-downtime deployment with Deployer
- Maintainability: Environment-specific configuration, version control with Git
I hope this article helps in building the Shopware6 production environment. If there are improvement points in the article or you have questions or feedback, please feel free to contact me!