mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-11-20 12:06:25 +00:00
Compare commits
10 Commits
feature/sh
...
493d5bbbda
| Author | SHA1 | Date | |
|---|---|---|---|
| 493d5bbbda | |||
| 2fcbae8fc7 | |||
| 02f38d60db | |||
| d66ad37c5d | |||
| 0c16f9c43c | |||
| 7330aeb8ec | |||
| d3aad632c0 | |||
| d1bad3d7a6 | |||
| 43056a8b92 | |||
| 0bf286f62a |
@@ -15,6 +15,7 @@ location {{location}}
|
|||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
proxy_set_header X-Forwarded-Port {{ WEB_PORT }};
|
proxy_set_header X-Forwarded-Port {{ WEB_PORT }};
|
||||||
|
proxy_set_header X-Forwarded-Ssl on;
|
||||||
proxy_pass_request_headers on;
|
proxy_pass_request_headers on;
|
||||||
|
|
||||||
{% include 'roles/sys-svc-proxy/templates/headers/content_security_policy.conf.j2' %}
|
{% include 'roles/sys-svc-proxy/templates/headers/content_security_policy.conf.j2' %}
|
||||||
|
|||||||
@@ -30,6 +30,8 @@
|
|||||||
argv:
|
argv:
|
||||||
- docker
|
- docker
|
||||||
- exec
|
- exec
|
||||||
|
- --user
|
||||||
|
- "{{ JOOMLA_WEB_USER }}"
|
||||||
- "{{ JOOMLA_CONTAINER }}"
|
- "{{ JOOMLA_CONTAINER }}"
|
||||||
- php
|
- php
|
||||||
- "{{ JOOMLA_INSTALLER_CLI_FILE }}"
|
- "{{ JOOMLA_INSTALLER_CLI_FILE }}"
|
||||||
|
|||||||
@@ -21,3 +21,4 @@ JOOMLA_USER_NAME: "{{ users.administrator.username }}"
|
|||||||
JOOMLA_USER: "{{ JOOMLA_USER_NAME | capitalize }}"
|
JOOMLA_USER: "{{ JOOMLA_USER_NAME | capitalize }}"
|
||||||
JOOMLA_USER_PASSWORD: "{{ users.administrator.password }}"
|
JOOMLA_USER_PASSWORD: "{{ users.administrator.password }}"
|
||||||
JOOMLA_USER_EMAIL: "{{ users.administrator.email }}"
|
JOOMLA_USER_EMAIL: "{{ users.administrator.email }}"
|
||||||
|
JOOMLA_WEB_USER: "www-data"
|
||||||
@@ -21,6 +21,7 @@ server:
|
|||||||
connect-src:
|
connect-src:
|
||||||
- https://q.clarity.ms
|
- https://q.clarity.ms
|
||||||
- https://n.clarity.ms
|
- https://n.clarity.ms
|
||||||
|
- https://z.clarity.ms
|
||||||
- "data:"
|
- "data:"
|
||||||
style-src-elem: []
|
style-src-elem: []
|
||||||
font-src: []
|
font-src: []
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ docker:
|
|||||||
services:
|
services:
|
||||||
redis:
|
redis:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
cpus: "0.5"
|
||||||
|
mem_reservation: "256m"
|
||||||
|
mem_limit: "512m"
|
||||||
|
pids_limit: 512
|
||||||
database:
|
database:
|
||||||
enabled: true
|
enabled: true
|
||||||
peertube:
|
peertube:
|
||||||
@@ -38,6 +42,10 @@ docker:
|
|||||||
image: "chocobozzz/peertube"
|
image: "chocobozzz/peertube"
|
||||||
backup:
|
backup:
|
||||||
no_stop_required: true
|
no_stop_required: true
|
||||||
|
cpus: 4
|
||||||
|
mem_reservation: "4g"
|
||||||
|
mem_limit: "8g"
|
||||||
|
pids_limit: 2048 # ffmpeg spawnt Threads/Prozesse
|
||||||
volumes:
|
volumes:
|
||||||
data: peertube_data
|
data: peertube_data
|
||||||
config: peertube_config
|
config: peertube_config
|
||||||
@@ -12,6 +12,17 @@
|
|||||||
- assets:/app/client/dist
|
- assets:/app/client/dist
|
||||||
- data:/data
|
- data:/data
|
||||||
- config:/config
|
- config:/config
|
||||||
|
environment:
|
||||||
|
- NODE_OPTIONS=--max-old-space-size={{ PEERTUBE_MAX_OLD_SPACE_SIZE }}
|
||||||
|
- PEERTUBE_TRANSCODING_CONCURRENCY={{ PEERTUBE_TRANSCODING_CONCURRENCY }}
|
||||||
|
shm_size: "512m"
|
||||||
|
tmpfs:
|
||||||
|
- /tmp:size=1g,exec
|
||||||
|
ulimits:
|
||||||
|
nofile:
|
||||||
|
soft: 131072
|
||||||
|
hard: 131072
|
||||||
|
nproc: 8192
|
||||||
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
|
{% include 'roles/docker-container/templates/depends_on/dmbs_excl.yml.j2' %}
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
|
{% include 'roles/docker-container/templates/healthcheck/tcp.yml.j2' %}
|
||||||
|
|||||||
@@ -14,4 +14,34 @@ PEERTUBE_CONFIG_VOLUME: "{{ applications | get_app_conf(application_id,
|
|||||||
|
|
||||||
# OIDC
|
# OIDC
|
||||||
PEERTUBE_OIDC_PLUGIN: "peertube-plugin-auth-openid-connect"
|
PEERTUBE_OIDC_PLUGIN: "peertube-plugin-auth-openid-connect"
|
||||||
PEERTUBE_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc', False) }}"
|
PEERTUBE_OIDC_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') }}"
|
||||||
|
|
||||||
|
# === Dynamic performance defaults ==========================================
|
||||||
|
|
||||||
|
# Raw Docker configuration values (with sane fallbacks)
|
||||||
|
peertube_cpus: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.cpus') | float }}"
|
||||||
|
peertube_mem_limit_raw: "{{ applications | get_app_conf(application_id, 'docker.services.peertube.mem_limit') }}"
|
||||||
|
peertube_mem_bytes: "{{ peertube_mem_limit_raw | human_to_bytes }}"
|
||||||
|
peertube_mem_mb: "{{ ((peertube_mem_bytes | int) // (1024 * 1024)) | int }}"
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Node heap size:
|
||||||
|
# ~35% of total RAM, but at least 768 MB, at most 3072 MB,
|
||||||
|
# and never more than 60% of total memory (safety cap for small containers)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
_peertube_heap_candidate_mb: "{{ ((peertube_mem_mb | float) * 0.35) | round(0, 'floor') | int }}"
|
||||||
|
_peertube_heap_cap_mb: "{{ ((peertube_mem_mb | float) * 0.60) | round(0, 'floor') | int }}"
|
||||||
|
|
||||||
|
# Step 1: enforce minimum (≥768 MB)
|
||||||
|
_peertube_heap_min_applied: "{{ [ (_peertube_heap_candidate_mb | int), 768 ] | max }}"
|
||||||
|
|
||||||
|
# Step 2: determine hard cap (min of 3072 MB and 60% of total memory)
|
||||||
|
_peertube_heap_hardcap: "{{ [ 3072, (_peertube_heap_cap_mb | int) ] | min }}"
|
||||||
|
|
||||||
|
# Step 3: final heap = min(min-applied, hardcap)
|
||||||
|
PEERTUBE_MAX_OLD_SPACE_SIZE: "{{ [ (_peertube_heap_min_applied | int), (_peertube_heap_hardcap | int) ] | min }}"
|
||||||
|
|
||||||
|
# Transcoding concurrency: half the vCPUs; min 1, max 8
|
||||||
|
_peertube_concurrency_candidate: "{{ ((peertube_cpus | float) * 0.5) | round(0, 'floor') | int }}"
|
||||||
|
PEERTUBE_TRANSCODING_CONCURRENCY: "{{ [ ( [ (_peertube_concurrency_candidate | int), 1 ] | max ), 8 ] | min }}"
|
||||||
|
|||||||
@@ -5,12 +5,17 @@ features:
|
|||||||
ldap: false # Not implemented yet
|
ldap: false # Not implemented yet
|
||||||
oidc: false # Not implemented yet
|
oidc: false # Not implemented yet
|
||||||
logout: true
|
logout: true
|
||||||
|
desktop: true
|
||||||
|
css: true
|
||||||
server:
|
server:
|
||||||
csp:
|
csp:
|
||||||
flags:
|
flags:
|
||||||
script-src-elem:
|
script-src-elem:
|
||||||
unsafe-inline: true
|
unsafe-inline: true
|
||||||
whitelist: {}
|
unsafe-eval: true
|
||||||
|
whitelist:
|
||||||
|
font-src:
|
||||||
|
- "data:"
|
||||||
domains:
|
domains:
|
||||||
aliases: []
|
aliases: []
|
||||||
canonical:
|
canonical:
|
||||||
|
|||||||
7
roles/web-app-shopware/files/framework.yaml
Normal file
7
roles/web-app-shopware/files/framework.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
framework:
|
||||||
|
trusted_proxies: '%env(TRUSTED_PROXIES)%'
|
||||||
|
trusted_headers:
|
||||||
|
- x-forwarded-for
|
||||||
|
- x-forwarded-proto
|
||||||
|
- x-forwarded-host
|
||||||
|
- x-forwarded-port
|
||||||
@@ -1,81 +1,146 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
# Shopware initialization script (POSIX sh)
|
||||||
|
# - Root phase: fix volumes & permissions, then switch to www-data
|
||||||
|
# - First run: perform system:install
|
||||||
|
# - Every run: run DB migrations + rebuild cache + compile assets & themes
|
||||||
|
# - Verifies admin bundles exist, otherwise exits with error
|
||||||
|
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
# Paths / constants
|
|
||||||
APP_ROOT="/var/www/html"
|
APP_ROOT="/var/www/html"
|
||||||
MARKER="$APP_ROOT/.infinito/installed"
|
MARKER="$APP_ROOT/.infinito/installed"
|
||||||
|
LOG_PREFIX="[INIT]"
|
||||||
|
PHP_BIN="php"
|
||||||
|
|
||||||
cd "$APP_ROOT"
|
log() { printf "%s %s\n" "$LOG_PREFIX" "$1"; }
|
||||||
mkdir -p "$APP_ROOT/.infinito"
|
fail() { printf "%s [ERROR] %s\n" "$LOG_PREFIX" "$1" >&2; exit 1; }
|
||||||
|
|
||||||
echo "[INIT] Checking database via PDO..."
|
# ---------------------------
|
||||||
php -r '
|
# 0) Root phase (if running as root)
|
||||||
|
# ---------------------------
|
||||||
|
if [ "$(id -u)" -eq 0 ]; then
|
||||||
|
# Prepare required folders and shared volumes
|
||||||
|
mkdir -p "$APP_ROOT/.infinito" \
|
||||||
|
"$APP_ROOT/public/bundles" \
|
||||||
|
"$APP_ROOT/public/media" \
|
||||||
|
"$APP_ROOT/public/theme" \
|
||||||
|
"$APP_ROOT/public/thumbnail" \
|
||||||
|
"$APP_ROOT/public/sitemap" \
|
||||||
|
"$APP_ROOT/var"
|
||||||
|
|
||||||
|
log "Fixing permissions on shared volumes..."
|
||||||
|
chown -R www-data:www-data \
|
||||||
|
"$APP_ROOT/public" \
|
||||||
|
"$APP_ROOT/var" \
|
||||||
|
"$APP_ROOT/.infinito" || true
|
||||||
|
chmod -R 775 \
|
||||||
|
"$APP_ROOT/public" \
|
||||||
|
"$APP_ROOT/var" \
|
||||||
|
"$APP_ROOT/.infinito" || true
|
||||||
|
|
||||||
|
# Switch to www-data for all subsequent operations
|
||||||
|
exec su -s /bin/sh www-data "$0" "$@"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# From here on: running as www-data
|
||||||
|
cd "$APP_ROOT" || fail "Cannot cd to $APP_ROOT"
|
||||||
|
|
||||||
|
# Optional environment hints
|
||||||
|
APP_ENV_STR=$($PHP_BIN -r 'echo getenv("APP_ENV") ?: "";' 2>/dev/null || true)
|
||||||
|
APP_URL_STR=$($PHP_BIN -r 'echo getenv("APP_URL") ?: "";' 2>/dev/null || true)
|
||||||
|
[ -n "$APP_ENV_STR" ] || log "APP_ENV not set (using defaults)"
|
||||||
|
[ -n "$APP_URL_STR" ] || log "APP_URL not set (reverse proxy must set headers)"
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# 1) Database reachability check (PDO)
|
||||||
|
# ---------------------------
|
||||||
|
log "Checking database via PDO..."
|
||||||
|
$PHP_BIN -r '
|
||||||
$url = getenv("DATABASE_URL");
|
$url = getenv("DATABASE_URL");
|
||||||
if (!$url) { fwrite(STDERR, "DATABASE_URL not set\n"); exit(1); }
|
if (!$url) { fwrite(STDERR, "DATABASE_URL not set\n"); exit(1); }
|
||||||
$p = parse_url($url);
|
$p = parse_url($url);
|
||||||
if (!$p || !isset($p["scheme"])) { fwrite(STDERR, "Invalid DATABASE_URL\n"); exit(1); }
|
if (!$p || !isset($p["scheme"])) { fwrite(STDERR, "Invalid DATABASE_URL\n"); exit(1); }
|
||||||
$scheme = $p["scheme"];
|
|
||||||
if ($scheme === "mysql" || $scheme === "mariadb") {
|
|
||||||
$host = $p["host"] ?? "localhost";
|
$host = $p["host"] ?? "localhost";
|
||||||
$port = $p["port"] ?? 3306;
|
$port = $p["port"] ?? 3306;
|
||||||
$db = ltrim($p["path"] ?? "", "/");
|
$db = ltrim($p["path"] ?? "", "/");
|
||||||
$user = $p["user"] ?? "";
|
$user = $p["user"] ?? "";
|
||||||
$pass = $p["pass"] ?? "";
|
$pass = $p["pass"] ?? "";
|
||||||
$dsn = "mysql:host=".$host.";port=".$port.";dbname=".$db.";charset=utf8mb4";
|
$dsn = "mysql:host=".$host.";port=".$port.";dbname=".$db.";charset=utf8mb4";
|
||||||
} else {
|
|
||||||
fwrite(STDERR, "Unsupported DB scheme: ".$scheme."\n"); exit(1);
|
|
||||||
}
|
|
||||||
$retries = 60;
|
$retries = 60;
|
||||||
while ($retries-- > 0) {
|
while ($retries-- > 0) {
|
||||||
try { $pdo = new PDO($dsn, $user, $pass, [PDO::ATTR_TIMEOUT => 3]); exit(0); }
|
try { new PDO($dsn, $user, $pass, [PDO::ATTR_TIMEOUT => 3]); exit(0); }
|
||||||
catch (Exception $e) { sleep(2); }
|
catch (Exception $e) { sleep(2); }
|
||||||
}
|
}
|
||||||
fwrite(STDERR, "DB not reachable\n"); exit(1);
|
fwrite(STDERR, "DB not reachable\n"); exit(1);
|
||||||
'
|
' || fail "Database not reachable"
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# 2) First-time install detection
|
||||||
|
# ---------------------------
|
||||||
|
FIRST_INSTALL=0
|
||||||
if [ ! -f "$MARKER" ]; then
|
if [ ! -f "$MARKER" ]; then
|
||||||
echo "[INIT] Checking if database is empty..."
|
log "Checking if database is empty..."
|
||||||
# PHP exits: 0 = empty, 100 = non-empty, 1 = error
|
if $PHP_BIN -r '
|
||||||
if php -r '
|
|
||||||
$url = getenv("DATABASE_URL");
|
$url = getenv("DATABASE_URL");
|
||||||
$p = parse_url($url);
|
$p = parse_url($url);
|
||||||
$db = ltrim($p["path"] ?? "", "/");
|
$db = ltrim($p["path"] ?? "", "/");
|
||||||
$dsn = "mysql:host=".($p["host"]??"localhost").";port=".($p["port"]??3306).";dbname=".$db.";charset=utf8mb4";
|
$dsn = "mysql:host=".($p["host"]??"localhost").";port=".($p["port"]??3306).";dbname=".$db.";charset=utf8mb4";
|
||||||
try {
|
|
||||||
$pdo = new PDO($dsn, $p["user"] ?? "", $p["pass"] ?? "");
|
$pdo = new PDO($dsn, $p["user"] ?? "", $p["pass"] ?? "");
|
||||||
$q = $pdo->query("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=".$pdo->quote($db));
|
$q = $pdo->query("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=".$pdo->quote($db));
|
||||||
$cnt = (int)$q->fetchColumn();
|
$cnt = (int)$q->fetchColumn();
|
||||||
if ($cnt === 0) { exit(0); } else { exit(100); }
|
exit($cnt === 0 ? 0 : 100);
|
||||||
} catch (Exception $e) { fwrite(STDERR, $e->getMessage()."\n"); exit(1); }
|
|
||||||
'; then
|
'; then
|
||||||
DBCHK=0
|
FIRST_INSTALL=1
|
||||||
else
|
else
|
||||||
DBCHK=$?
|
ST=$?
|
||||||
|
if [ "$ST" -eq 100 ]; then
|
||||||
|
log "Database not empty → skipping install"
|
||||||
|
else
|
||||||
|
fail "Database check failed (exit code $ST)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$DBCHK" -eq 0 ]; then
|
if [ "$FIRST_INSTALL" -eq 1 ]; then
|
||||||
echo "[INIT] Installing Shopware (empty DB detected)..."
|
log "Performing first-time Shopware installation..."
|
||||||
# IMPORTANT: no --force; let Shopware run its internal steps only on empty DB
|
$PHP_BIN -d memory_limit=1024M bin/console system:install --basic-setup --create-database
|
||||||
php -d memory_limit=1024M bin/console system:install --basic-setup --create-database
|
mkdir -p "$(dirname "$MARKER")"
|
||||||
elif [ "$DBCHK" -eq 100 ]; then
|
: > "$MARKER"
|
||||||
echo "[INIT] Database is not empty -> skipping system:install"
|
|
||||||
else
|
|
||||||
echo "[INIT] Database check failed (code $DBCHK)"; exit 1
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Safe to run (no-ops when up-to-date)
|
# ---------------------------
|
||||||
php -d memory_limit=1024M bin/console database:migrate --all || true
|
# 3) Always run migrations
|
||||||
php -d memory_limit=1024M bin/console database:migrate-destructive --all || true
|
# ---------------------------
|
||||||
|
log "Running database migrations..."
|
||||||
|
$PHP_BIN -d memory_limit=1024M bin/console database:migrate --all
|
||||||
|
$PHP_BIN -d memory_limit=1024M bin/console database:migrate-destructive --all
|
||||||
|
|
||||||
# Housekeeping
|
# ---------------------------
|
||||||
php bin/console cache:clear || true
|
# 4) Always rebuild caches, bundles, and themes
|
||||||
php bin/console dal:refresh:index || true
|
# ---------------------------
|
||||||
|
log "Rebuilding caches and assets..."
|
||||||
|
$PHP_BIN bin/console cache:clear
|
||||||
|
$PHP_BIN bin/console bundle:dump
|
||||||
|
# Use --copy if symlinks cause issues
|
||||||
|
$PHP_BIN bin/console assets:install --no-interaction --force
|
||||||
|
$PHP_BIN bin/console theme:refresh
|
||||||
|
$PHP_BIN bin/console theme:compile
|
||||||
|
# Best-effort: not critical if it fails
|
||||||
|
$PHP_BIN bin/console dal:refresh:index || log "dal:refresh:index failed (non-critical)"
|
||||||
|
|
||||||
# Marker + perms
|
# ---------------------------
|
||||||
touch "$MARKER"
|
# 5) Verify admin bundles
|
||||||
chown -R www-data:www-data "$APP_ROOT"
|
# ---------------------------
|
||||||
|
if [ ! -d "public/bundles/administration" ]; then
|
||||||
echo "[INIT] Done."
|
fail "Missing directory public/bundles/administration (asset build failed)"
|
||||||
else
|
|
||||||
echo "[INIT] Marker found, skipping install."
|
|
||||||
fi
|
fi
|
||||||
|
if ! ls public/bundles/administration/* >/dev/null 2>&1; then
|
||||||
|
fail "No files found in public/bundles/administration (asset build failed)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ---------------------------
|
||||||
|
# 6) Show version info
|
||||||
|
# ---------------------------
|
||||||
|
$PHP_BIN bin/console system:version 2>/dev/null || log "system:version not available"
|
||||||
|
|
||||||
|
log "Initialization complete."
|
||||||
|
|||||||
@@ -1,4 +1,22 @@
|
|||||||
# Ensures that the admin user exists and always has the desired password
|
- name: "Rename default Shopware admin user to {{ users.administrator.username }}"
|
||||||
|
shell: |
|
||||||
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
|
set -e
|
||||||
|
cd {{ SHOPWARE_ROOT }}
|
||||||
|
old_user="admin"
|
||||||
|
new_user="{{ users.administrator.username }}"
|
||||||
|
if php bin/console user:list | grep -q "^$old_user "; then
|
||||||
|
echo "[INFO] Renaming Shopware user: $old_user -> $new_user"
|
||||||
|
php bin/console user:update "$old_user" --username="$new_user" || true
|
||||||
|
else
|
||||||
|
echo "[INFO] No user named $old_user found (already renamed or custom setup)"
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
args:
|
||||||
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
|
changed_when: false
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
|
|
||||||
- name: "Ensure Shopware admin exists and has the desired password"
|
- name: "Ensure Shopware admin exists and has the desired password"
|
||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
@@ -17,3 +35,4 @@
|
|||||||
'
|
'
|
||||||
args:
|
args:
|
||||||
chdir: "{{ docker_compose.directories.instance }}"
|
chdir: "{{ docker_compose.directories.instance }}"
|
||||||
|
no_log: "{{ MASK_CREDENTIALS_IN_LOGS | bool }}"
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
- name: "Deactivate/uninstall LDAP plugin if present"
|
- name: "Deactivate/uninstall LDAP plugin if present"
|
||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} bash -lc '
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
cd {{ SHOPWARE_ROOT }}
|
cd {{ SHOPWARE_ROOT }}
|
||||||
php bin/console plugin:deactivate INFX_LDAP_PLUGIN || true
|
php bin/console plugin:deactivate INFX_LDAP_PLUGIN || true
|
||||||
php bin/console plugin:uninstall INFX_LDAP_PLUGIN --keep-user-data || true
|
php bin/console plugin:uninstall INFX_LDAP_PLUGIN --keep-user-data || true
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
- name: "Deactivate/uninstall OIDC plugin if present"
|
- name: "Deactivate/uninstall OIDC plugin if present"
|
||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} bash -lc '
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
cd {{ SHOPWARE_ROOT }}
|
cd {{ SHOPWARE_ROOT }}
|
||||||
php bin/console plugin:deactivate INFX_OIDC_PLUGIN || true
|
php bin/console plugin:deactivate INFX_OIDC_PLUGIN || true
|
||||||
php bin/console plugin:uninstall INFX_OIDC_PLUGIN --keep-user-data || true
|
php bin/console plugin:uninstall INFX_OIDC_PLUGIN --keep-user-data || true
|
||||||
|
|||||||
@@ -14,6 +14,14 @@
|
|||||||
- docker compose up
|
- docker compose up
|
||||||
- docker compose build
|
- docker compose build
|
||||||
|
|
||||||
|
- name: "Render framework.yaml (trusted proxies/headers/hosts)"
|
||||||
|
copy:
|
||||||
|
src: "framework.yaml"
|
||||||
|
dest: "{{ SHOPWARE_FRAMEWORK_HOST }}"
|
||||||
|
mode: "0644"
|
||||||
|
notify:
|
||||||
|
- docker compose up
|
||||||
|
|
||||||
- name: "Flush docker compose handlers"
|
- name: "Flush docker compose handlers"
|
||||||
meta: flush_handlers
|
meta: flush_handlers
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Replace INFX_LDAP_PLUGIN with the actual plugin name you use
|
# Replace INFX_LDAP_PLUGIN with the actual plugin name you use
|
||||||
- name: "Install LDAP admin plugin & activate"
|
- name: "Install LDAP admin plugin & activate"
|
||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} bash -lc '
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
set -e
|
set -e
|
||||||
cd {{ SHOPWARE_ROOT }}
|
cd {{ SHOPWARE_ROOT }}
|
||||||
php bin/console plugin:refresh
|
php bin/console plugin:refresh
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
- name: "Configure LDAP connection"
|
- name: "Configure LDAP connection"
|
||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} bash -lc '
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
set -e
|
set -e
|
||||||
cd {{ SHOPWARE_ROOT }}
|
cd {{ SHOPWARE_ROOT }}
|
||||||
php bin/console system:config:set "InfxLdap.config.host" "{{ LDAP.SERVER.DOMAIN }}"
|
php bin/console system:config:set "InfxLdap.config.host" "{{ LDAP.SERVER.DOMAIN }}"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Replace INFX_OIDC_PLUGIN with the actual plugin name (Composer or local)
|
# Replace INFX_OIDC_PLUGIN with the actual plugin name (Composer or local)
|
||||||
- name: "Install OIDC plugin & activate"
|
- name: "Install OIDC plugin & activate"
|
||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} bash -lc '
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
set -e
|
set -e
|
||||||
cd {{ SHOPWARE_ROOT }}
|
cd {{ SHOPWARE_ROOT }}
|
||||||
php bin/console plugin:refresh
|
php bin/console plugin:refresh
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
- name: "Configure OIDC via system:config"
|
- name: "Configure OIDC via system:config"
|
||||||
shell: |
|
shell: |
|
||||||
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} bash -lc '
|
docker exec -i --user {{ SHOPWARE_USER }} {{ SHOPWARE_WEB_CONTAINER }} sh -lc '
|
||||||
set -e
|
set -e
|
||||||
cd {{ SHOPWARE_ROOT }}
|
cd {{ SHOPWARE_ROOT }}
|
||||||
php bin/console system:config:set "InfxOidc.config.clientId" "{{ OIDC.CLIENT.ID }}"
|
php bin/console system:config:set "InfxOidc.config.clientId" "{{ OIDC.CLIENT.ID }}"
|
||||||
|
|||||||
@@ -76,17 +76,5 @@ RUN set -eux; \
|
|||||||
/var/www/html/public/theme; \
|
/var/www/html/public/theme; \
|
||||||
chown -R www-data:www-data /var/www/html
|
chown -R www-data:www-data /var/www/html
|
||||||
|
|
||||||
# Add trusted proxies wiring (Symfony reads env TRUSTED_PROXIES)
|
|
||||||
RUN set -eux; \
|
|
||||||
mkdir -p /var/www/html/config/packages; \
|
|
||||||
if [ ! -f /var/www/html/config/packages/framework.yaml ]; then \
|
|
||||||
printf "framework:\n trusted_proxies: '%%env(TRUSTED_PROXIES)%%'\n" > /var/www/html/config/packages/framework.yaml; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Drop back to the app user
|
# Drop back to the app user
|
||||||
USER www-data
|
USER www-data
|
||||||
|
|
||||||
# Expose internal port & add a lightweight healthcheck
|
|
||||||
EXPOSE 8000
|
|
||||||
HEALTHCHECK --interval=30s --timeout=5s --retries=5 --start-period=20s \
|
|
||||||
CMD php -r '$s=@fsockopen("127.0.0.1", 8000, $e, $t, 3); if(!$s) exit(1); fclose($s);'
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ x-environment: &shopware
|
|||||||
- thumbnail:/var/www/html/public/thumbnail
|
- thumbnail:/var/www/html/public/thumbnail
|
||||||
- sitemap:/var/www/html/public/sitemap
|
- sitemap:/var/www/html/public/sitemap
|
||||||
- "{{ SHOPWARE_INIT_HOST }}:{{ SHOPWARE_INIT_DOCKER }}:ro"
|
- "{{ SHOPWARE_INIT_HOST }}:{{ SHOPWARE_INIT_DOCKER }}:ro"
|
||||||
|
- bundles:/var/www/html/public/bundles
|
||||||
|
- "{{ SHOPWARE_FRAMEWORK_HOST }}:{{ SHOPWARE_FRAMEWORK_DOCKER }}:ro"
|
||||||
working_dir: {{ SHOPWARE_ROOT }}
|
working_dir: {{ SHOPWARE_ROOT }}
|
||||||
|
|
||||||
{% include 'roles/docker-compose/templates/base.yml.j2' %}
|
{% include 'roles/docker-compose/templates/base.yml.j2' %}
|
||||||
@@ -22,6 +24,7 @@ x-environment: &shopware
|
|||||||
<<: *shopware
|
<<: *shopware
|
||||||
container_name: "{{ SHOPWARE_INIT_CONTAINER }}"
|
container_name: "{{ SHOPWARE_INIT_CONTAINER }}"
|
||||||
entrypoint: [ "sh", "{{ SHOPWARE_INIT_DOCKER }}" ]
|
entrypoint: [ "sh", "{{ SHOPWARE_INIT_DOCKER }}" ]
|
||||||
|
user: "0:0"
|
||||||
|
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
@@ -40,9 +43,13 @@ x-environment: &shopware
|
|||||||
depends_on:
|
depends_on:
|
||||||
init:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
{% filter indent(4) %}
|
healthcheck:
|
||||||
{% include 'roles/docker-container/templates/healthcheck/http.yml.j2' %}
|
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:{{ container_port }}/robots.txt || wget -q --spider http://127.0.0.1:{{ container_port }}/ || exit 1"]
|
||||||
{% endfilter %}
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
start_period: 120s
|
||||||
|
|
||||||
|
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
@@ -62,6 +69,12 @@ x-environment: &shopware
|
|||||||
# @todo Activate for swarm deploy
|
# @todo Activate for swarm deploy
|
||||||
# deploy:
|
# deploy:
|
||||||
# replicas: {{ SHOPWARE_WORKER_REPLICAS }}
|
# replicas: {{ SHOPWARE_WORKER_REPLICAS }}
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "php", "-v"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
@@ -78,6 +91,13 @@ x-environment: &shopware
|
|||||||
depends_on:
|
depends_on:
|
||||||
init:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "php", "-v"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
|
|
||||||
@@ -97,6 +117,12 @@ x-environment: &shopware
|
|||||||
depends_on:
|
depends_on:
|
||||||
init:
|
init:
|
||||||
condition: service_completed_successfully
|
condition: service_completed_successfully
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -fsSL http://127.0.0.1:{{ SHOPWARE_OPENSEARCH_PORT }}/_cluster/health || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 5
|
||||||
|
start_period: 60s
|
||||||
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
{% include 'roles/docker-container/templates/networks.yml.j2' %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
@@ -113,5 +139,7 @@ x-environment: &shopware
|
|||||||
name: {{ entity_name }}_thumbnail
|
name: {{ entity_name }}_thumbnail
|
||||||
sitemap:
|
sitemap:
|
||||||
name: {{ entity_name }}_sitemap
|
name: {{ entity_name }}_sitemap
|
||||||
|
bundles:
|
||||||
|
name: {{ entity_name }}_bundles
|
||||||
|
|
||||||
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
{% include 'roles/docker-compose/templates/networks.yml.j2' %}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
# DOMAIN/URL
|
# DOMAIN/URL
|
||||||
DOMAIN={{ domains | get_domain(application_id) }}
|
DOMAIN={{ SHOPWARE_DOMAIN }}
|
||||||
APP_URL="{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
APP_URL="{{ domains | get_url(application_id, WEB_PROTOCOL) }}"
|
||||||
APP_DEBUG="{{ MODE_DEBUG | ternary(1, 0) }}"
|
APP_DEBUG="{{ MODE_DEBUG | ternary(1, 0) }}"
|
||||||
|
|
||||||
# Shopware
|
# Shopware
|
||||||
APP_ENV={{ 'dev' if (ENVIRONMENT | lower) == 'development' else 'prod' }}
|
APP_ENV={{ 'dev' if (ENVIRONMENT | lower) == 'development' else 'prod' }}
|
||||||
#TRUSTED_PROXIES=127.0.0.1
|
|
||||||
INSTANCE_ID={{ application_id }}
|
INSTANCE_ID={{ application_id }}
|
||||||
|
|
||||||
|
# Proxy
|
||||||
|
TRUSTED_PROXIES="{{ networks.internet.values() | select | join(',') }},127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
|
||||||
|
TRUSTED_HOSTS="{{ SHOPWARE_DOMAIN }}"
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
DATABASE_URL="mysql://{{ database_username }}:{{ database_password }}@{{ database_host }}:{{ database_port }}/{{ database_name }}"
|
DATABASE_URL="mysql://{{ database_username }}:{{ database_password }}@{{ database_host }}:{{ database_port }}/{{ database_name }}"
|
||||||
|
|
||||||
@@ -22,10 +25,10 @@ CACHE_URL="file://cache"
|
|||||||
|
|
||||||
{% if SHOPWARE_OPENSEARCH_ENABLED %}
|
{% if SHOPWARE_OPENSEARCH_ENABLED %}
|
||||||
# Search
|
# Search
|
||||||
ELASTICSEARCH_URL="http://opensearch:9200"
|
ELASTICSEARCH_URL="http://opensearch:{{ SHOPWARE_OPENSEARCH_PORT }}"
|
||||||
OPENSEARCH_URL="http://opensearch:9200"
|
OPENSEARCH_URL="http://opensearch:{{ SHOPWARE_OPENSEARCH_PORT }}"
|
||||||
OPENSEARCH_HOST="opensearch"
|
OPENSEARCH_HOST="opensearch"
|
||||||
OPENSEARCH_PORT_NUMBER="9200"
|
OPENSEARCH_PORT_NUMBER="{{ SHOPWARE_OPENSEARCH_PORT }}"
|
||||||
OPENSEARCH_INITIAL_ADMIN_PASSWORD="{{ users.administrator.password }}"
|
OPENSEARCH_INITIAL_ADMIN_PASSWORD="{{ users.administrator.password }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ entity_name: "{{ application_id | get_entity_name }}"
|
|||||||
container_port: "{{ applications | get_app_conf(application_id, 'docker.services.web.port') }}"
|
container_port: "{{ applications | get_app_conf(application_id, 'docker.services.web.port') }}"
|
||||||
docker_compose_flush_handlers: true
|
docker_compose_flush_handlers: true
|
||||||
|
|
||||||
|
SHOPWARE_DOMAIN: "{{ domains | get_domain(application_id) }}"
|
||||||
|
|
||||||
# Shopware container/image vars
|
# Shopware container/image vars
|
||||||
SHOPWARE_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.shopware.version') }}"
|
SHOPWARE_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.shopware.version') }}"
|
||||||
SHOPWARE_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.shopware.image') }}"
|
SHOPWARE_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.shopware.image') }}"
|
||||||
@@ -22,22 +24,22 @@ SHOPWARE_WORKER_CONTAINER: "{{ applications | get_app_conf(application_id,
|
|||||||
SHOPWARE_SCHED_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.scheduler.name') }}"
|
SHOPWARE_SCHED_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.scheduler.name') }}"
|
||||||
SHOPWARE_INIT_HOST: "{{ [ docker_compose.directories.volumes, 'init.sh' ] | path_join }}"
|
SHOPWARE_INIT_HOST: "{{ [ docker_compose.directories.volumes, 'init.sh' ] | path_join }}"
|
||||||
SHOPWARE_INIT_DOCKER: "/usr/local/bin/init.sh"
|
SHOPWARE_INIT_DOCKER: "/usr/local/bin/init.sh"
|
||||||
|
SHOPWARE_FRAMEWORK_HOST: "{{ [ docker_compose.directories.config, 'framework.yaml' ] | path_join }}"
|
||||||
|
SHOPWARE_FRAMEWORK_DOCKER: "/var/www/html/config/packages/framework.yaml"
|
||||||
|
|
||||||
# Entrypoints & replicas
|
# Entrypoints & replicas
|
||||||
SHOPWARE_WORKER_ENTRYPOINT: "{{ applications | get_app_conf(application_id, 'docker.services.worker.entrypoint') }}"
|
SHOPWARE_WORKER_ENTRYPOINT: "{{ applications | get_app_conf(application_id, 'docker.services.worker.entrypoint') }}"
|
||||||
SHOPWARE_SCHED_ENTRYPOINT: "{{ applications | get_app_conf(application_id, 'docker.services.scheduler.entrypoint') }}"
|
SHOPWARE_SCHED_ENTRYPOINT: "{{ applications | get_app_conf(application_id, 'docker.services.scheduler.entrypoint') }}"
|
||||||
SHOPWARE_WORKER_REPLICAS: "{{ applications | get_app_conf(application_id, 'docker.services.worker.replicas') }}"
|
SHOPWARE_WORKER_REPLICAS: "{{ applications | get_app_conf(application_id, 'docker.services.worker.replicas') }}"
|
||||||
|
|
||||||
# Search/Cache
|
# Redis Cache
|
||||||
SHOPWARE_REDIS_ENABLED: "{{ applications | get_app_conf(application_id, 'docker.services.redis.enabled') }}"
|
SHOPWARE_REDIS_ENABLED: "{{ applications | get_app_conf(application_id, 'docker.services.redis.enabled') }}"
|
||||||
SHOPWARE_REDIS_ADDRESS: "redis:6379"
|
SHOPWARE_REDIS_ADDRESS: "redis:6379"
|
||||||
|
|
||||||
|
# Opensearch
|
||||||
|
SHOPWARE_OPENSEARCH_PORT: "9200"
|
||||||
SHOPWARE_OPENSEARCH_ENABLED: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.enabled') }}"
|
SHOPWARE_OPENSEARCH_ENABLED: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.enabled') }}"
|
||||||
SHOPWARE_OPENSEARCH_ENGINE: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.engine') }}"
|
|
||||||
SHOPWARE_OPENSEARCH_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.image') }}"
|
SHOPWARE_OPENSEARCH_IMAGE: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.image') }}"
|
||||||
SHOPWARE_OPENSEARCH_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.version') }}"
|
SHOPWARE_OPENSEARCH_VERSION: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.version') }}"
|
||||||
SHOPWARE_OPENSEARCH_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.name') }}"
|
SHOPWARE_OPENSEARCH_CONTAINER: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.name') }}"
|
||||||
SHOPWARE_OPENSEARCH_MEM_RESERVATION: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.mem_reservation') }}"
|
SHOPWARE_OPENSEARCH_MEM_RESERVATION: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.mem_reservation') }}"
|
||||||
SHOPWARE_OPENSEARCH_MEM_LIMIT: "{{ applications | get_app_conf(application_id, 'docker.services.opensearch.mem_limit') }}"
|
|
||||||
|
|
||||||
# IAM (true if either OIDC or LDAP is enabled)
|
|
||||||
SHOPWARE_IAM_ENABLED: "{{ applications | get_app_conf(application_id, 'features.oidc') or applications | get_app_conf(application_id, 'features.ldap') }}"
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ BUILTIN_FILTERS: Set[str] = {
|
|||||||
"type_debug", "json_query", "mandatory", "hash", "checksum",
|
"type_debug", "json_query", "mandatory", "hash", "checksum",
|
||||||
"lower", "upper", "capitalize", "unique", "dict2items", "items2dict",
|
"lower", "upper", "capitalize", "unique", "dict2items", "items2dict",
|
||||||
"password_hash", "path_join", "product", "quote", "split", "ternary", "to_nice_yaml",
|
"password_hash", "path_join", "product", "quote", "split", "ternary", "to_nice_yaml",
|
||||||
"tojson", "to_nice_json",
|
"tojson", "to_nice_json", "human_to_bytes",
|
||||||
|
|
||||||
|
|
||||||
# Date/time-ish
|
# Date/time-ish
|
||||||
|
|||||||
Reference in New Issue
Block a user