From e7c1043e4124444cba40950167f1f6146366503f Mon Sep 17 00:00:00 2001 From: Hans-Christian Payer Date: Mon, 22 Jun 2026 20:21:04 +0200 Subject: [PATCH] initial --- README.md | 344 ++++++++++++++++++++++++++++++++++++++++++++++++ header.php | 197 +++++++++++++++++++++++++++ header.php_orig | 191 +++++++++++++++++++++++++++ 3 files changed, 732 insertions(+) create mode 100644 README.md create mode 100644 header.php create mode 100644 header.php_orig diff --git a/README.md b/README.md new file mode 100644 index 0000000..932e91f --- /dev/null +++ b/README.md @@ -0,0 +1,344 @@ +# WordPress Testumgebung mit Docker + +**Datum:** 22. Juni 2026 +**Zielumgebung:** Ubuntu Server, Docker, Portainer +**Produktionssystem:** WordPress 7.0, PHP 8.1, Apache, Ubuntu 22.04, MariaDB 10.6 +**Testsystem:** Docker Compose, MariaDB 10.6, WordPress 7.0 FPM-Alpine, Nginx, phpMyAdmin, WP-CLI + +--- + +## 1. Vorbereitung: Produktionssystem sichern + +### 1.1 WP-CLI auf Produktionsserver installieren + +```bash +curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar +chmod +x wp-cli.phar +sudo mv wp-cli.phar /usr/local/bin/wp +wp --info +``` + +### 1.2 Datenbank exportieren + +```bash +sudo -u www-data wp --path=/var/www/html db export /tmp/muckibackup.sql +``` + +### 1.3 wp-content sichern + +```bash +tar czf /tmp/wp-content.tar.gz -C /var/www/html wp-content +``` + +### 1.4 Dateien auf den Docker-Host übertragen + +```bash +scp user@prod-server:/tmp/muckibackup.sql ~/muckibackup/ +scp user@prod-server:/tmp/wp-content.tar.gz ~/muckibackup/ +``` + +--- + +## 2. Verzeichnisstruktur anlegen + +```bash +mkdir -p ~/muckibackup/wp-content +cd ~/muckibackup + +# wp-content entpacken +tar xzf wp-content.tar.gz -C ./wp-content --strip-components=1 + +# Berechtigungen setzen (UID 82 = www-data in Alpine) +sudo chown -R 82:82 ./wp-content +``` + +Tabellenprefix aus dem Dump prüfen: + +```bash +grep -m1 "CREATE TABLE" ~/muckibackup/muckibackup.sql +``` + +--- + +## 3. Konfigurationsdateien erstellen + +### 3.1 `.env` + +```env +MYSQL_ROOT_PASSWORD=sicheresRootPW +MYSQL_DATABASE=wordpress +MYSQL_USER=wp_user +MYSQL_PASSWORD=sicheresUserPW +WP_TABLE_PREFIX=wp_ +WP_PORT=8088 +PMA_PORT=8181 +``` + +### 3.2 `docker-compose.yml` + +```yaml +services: + db: + image: mariadb:10.6 + restart: unless-stopped + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} + MYSQL_DATABASE: ${MYSQL_DATABASE} + MYSQL_USER: ${MYSQL_USER} + MYSQL_PASSWORD: ${MYSQL_PASSWORD} + volumes: + - wp_db_data:/var/lib/mysql + networks: + - wp_internal + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 10s + timeout: 5s + retries: 5 + + wordpress: + image: wordpress:7.0-php8.5-fpm-alpine + restart: unless-stopped + depends_on: + db: + condition: service_healthy + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_NAME: ${MYSQL_DATABASE} + WORDPRESS_DB_USER: ${MYSQL_USER} + WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD} + WORDPRESS_TABLE_PREFIX: ${WP_TABLE_PREFIX} + volumes: + - wp_core:/var/www/html + - /home/hans/muckibackup/wp-content:/var/www/html/wp-content + networks: + - wp_internal + + nginx: + image: nginx:1.27-alpine + restart: unless-stopped + depends_on: + - wordpress + ports: + - "${WP_PORT}:80" + volumes: + - wp_core:/var/www/html:ro + - /home/hans/muckibackup/wp-content:/var/www/html/wp-content:ro + - /home/hans/muckibackup/nginx.conf:/etc/nginx/conf.d/default.conf:ro + networks: + - wp_internal + + phpmyadmin: + image: phpmyadmin:5.2-apache + restart: unless-stopped + depends_on: + - db + ports: + - "${PMA_PORT}:80" + environment: + PMA_HOST: db + PMA_USER: ${MYSQL_USER} + PMA_PASSWORD: ${MYSQL_PASSWORD} + UPLOAD_LIMIT: 512M + networks: + - wp_internal + + wpcli: + image: wordpress:cli-php8.3 + restart: "no" + depends_on: + db: + condition: service_healthy + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_NAME: ${MYSQL_DATABASE} + WORDPRESS_DB_USER: ${MYSQL_USER} + WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD} + volumes: + - wp_core:/var/www/html + - /home/hans/muckibackup/wp-content:/var/www/html/wp-content + networks: + - wp_internal + entrypoint: ["wp", "--allow-root"] + +volumes: + wp_db_data: + driver: local + wp_core: + driver: local + +networks: + wp_internal: + driver: bridge +``` + +### 3.3 `nginx.conf` + +```nginx +server { + listen 80; + root /var/www/html; + index index.php; + + client_max_body_size 64M; + + location / { + try_files $uri $uri/ /index.php?$args; + } + + location ~ \.php$ { + fastcgi_pass wordpress:9000; + fastcgi_index index.php; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_read_timeout 300; + } + + location ~ /\.ht { + deny all; + } +} +``` + +--- + +## 4. Stack in Portainer deployen + +1. Portainer öffnen → **Stacks → Add Stack** +2. Name: `wordpress-test` +3. Build method: **Upload** → `docker-compose.yml` hochladen +4. Unter **Environment variables**: Inhalt der `.env` eintragen +5. **Deploy the stack** + +Warten bis alle Container den Status **running** zeigen. + +--- + +## 5. Datenbank importieren + +### Option A: Via phpMyAdmin (empfohlen bis 512 MB) + +1. Browser: `http://SERVERIP:8181` +2. Links: Datenbank **wordpress** anklicken +3. Reiter **Importieren** → Datei `muckibackup.sql` auswählen +4. **OK** + +### Option B: Via CLI + +```bash +docker exec -i wordpress-test_db_1 \ + mysql -u wp_user -psicheresUserPW wordpress \ + < ~/muckibackup/muckibackup.sql +``` + +--- + +## 6. Produktions-URL anpassen + +Aktuelle URL aus der DB ermitteln (phpMyAdmin → wordpress → SQL-Reiter): + +```sql +SELECT option_name, option_value +FROM wp_options +WHERE option_name IN ('siteurl', 'home'); +``` + +URL ersetzen — im WordPress-Container (Portainer → wordpress-Container → Console): + +```bash +curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar +php wp-cli.phar search-replace \ + 'http://www.gh-muschitz.at' \ + 'http://SERVERIP:8088' \ + --skip-columns=guid --allow-root --path=/var/www/html +``` + +--- + +## 7. Funktionstest + +```bash +# HTTP-Status prüfen +curl -sI http://SERVERIP:8088 | head -3 + +# Uploads erreichbar? +curl -sI http://SERVERIP:8088/wp-content/uploads/2022/03/beispiel.jpg | head -3 + +# Logs beobachten +docker logs wordpress-test_wordpress_1 --tail=20 +docker logs wordpress-test_nginx_1 --tail=20 +``` + +- Testsystem: `http://SERVERIP:8088` +- phpMyAdmin: `http://SERVERIP:8181` + +--- + +## 8. Theme-Dateien anpassen und deployen + +### 8.1 Theme-Verzeichnis ermitteln + +```bash +ssh user@prod-server "ls /var/www/html/wp-content/themes/" +``` + +### 8.2 Datei lokal bearbeiten + +Theme-Dateien liegen im Testsystem unter: + +``` +/home/hans/muckibackup/wp-content/themes/THEME-NAME/ +``` + +### 8.3 Geänderte Datei auf Produktion übertragen + +```bash +# Backup der Originaldatei +ssh user@prod-server \ + "cp /var/www/html/wp-content/themes/THEME-NAME/header.php \ + /var/www/html/wp-content/themes/THEME-NAME/header.php.bak" + +# Neue Datei übertragen +scp header.php user@prod-server:/var/www/html/wp-content/themes/THEME-NAME/header.php + +# Berechtigungen prüfen +ssh user@prod-server \ + "chown www-data:www-data /var/www/html/wp-content/themes/THEME-NAME/header.php" +``` + +### 8.4 Bilder/Assets auf Produktion übertragen + +```bash +scp burgenlandlogo.png user@prod-server:/var/www/html/wp-content/uploads/2026/06/ +ssh user@prod-server \ + "chown www-data:www-data /var/www/html/wp-content/uploads/2026/06/burgenlandlogo.png" +``` + +--- + +## 9. Stack verwalten + +```bash +# Stack stoppen +docker compose -f ~/muckibackup/docker-compose.yml down + +# Stack neu starten +docker compose -f ~/muckibackup/docker-compose.yml up -d + +# Alles löschen inkl. DB-Volumes (für Neustart von Null) +docker compose -f ~/muckibackup/docker-compose.yml down -v +``` + +--- + +## Hinweise + +> **Pi-hole Konflikt:** Pi-hole belegt Port 80 auf allen Interfaces. Nginx immer auf einem anderen Port betreiben (z.B. 8088). + +> **UID/GID:** Das `fpm-alpine` Image verwendet UID 82 für www-data. Bind-Mounts mit `sudo chown -R 82:82` setzen. + +> **Nginx muss wp-content mounten:** Nginx benötigt denselben `wp-content` Bind-Mount wie WordPress — sonst werden statische Dateien (Bilder, CSS, JS) nicht gefunden und PHP gibt 404 zurück. + +> **URL nach jedem DB-Import anpassen:** Nach erneutem Import muss `search-replace` wiederholt werden. + +> **WP-CLI auf Produktion:** Immer als `sudo -u www-data wp --path=/var/www/html` ausführen, nicht als root — sonst wechseln Dateibesitzer auf root. diff --git a/header.php b/header.php new file mode 100644 index 0000000..7d66d34 --- /dev/null +++ b/header.php @@ -0,0 +1,197 @@ + section and everything up till
+ * + * @package SKT Restaurant + */ +?> + +> + + + + + + + + + + +> +
+
+ + + + + + + + +
+
+ +
+ + + + +
+ +
+ + + +
+ 10 ) { + $slAr[$m]['image_src'] = of_get_option('slide'.$i, true); + $slAr[$m]['image_button'] = of_get_option('slidebutton'.$i, true); + $slAr[$m]['image_url'] = of_get_option('slidelink'.$i, true); + $m++; + } + } + } + $slideno = array(); + if( $slAr > 0 ){ + $n = 0;?> +
+ + <?php echo esc_attr($sv['image_title']);?> + +
+ +
+
+ + +

+
+ + + +
+

+ + + +
+ + +
+
+ +
+
+ + + +
+ width.'" height="'.get_custom_header()->height.'" alt="" />'; + } else { + echo ''; + } + } + elseif( has_post_thumbnail() ) { + $src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'homepage-thumb' ); + $thumbnailSrc = $src[0]; + echo ''; + } + elseif ( ! empty( $header_image ) ) { + echo ''; + } + else { + echo ''; + } ?> +
+ + + + + + + 0 ) { + $numSections = esc_attr( of_get_option('numsection', true) ); + for( $s=1; $s<=$numSections; $s++ ){ + $title = ( of_get_option('sectiontitle'.$s, true) != '' ) ? esc_html( of_get_option('sectiontitle'.$s, true) ) : ''; + $secid = ( of_get_option('menutitle'.$s, true) != '') ? esc_html( of_get_option('menutitle'.$s, true) ) : ''; + $class = ( of_get_option('sectionclass'.$s, true) != '' ) ? esc_html( of_get_option('sectionclass'.$s, true) ) : ''; + $content = ( of_get_option('sectioncontent'.$s, true) != '' ) ? of_get_option('sectioncontent'.$s, true) : ''; + $hide = ( of_get_option('hidesec'.$s, true) != '' ) ? of_get_option('hidesec'.$s, true) : ''; + $bgcolor = ( of_get_option('sectionbgcolor'.$s, true) != '' ) ? of_get_option('sectionbgcolor'.$s, true) : ''; + $bgimage = ( of_get_option('sectionbgimage'.$s, true) != '' ) ? of_get_option('sectionbgimage'.$s, true) : ''; + ?> +
style="" id="" class=""> +
style="width:100%"> +
+ +

+ + +
+
+
+ +
+ + \ No newline at end of file diff --git a/header.php_orig b/header.php_orig new file mode 100644 index 0000000..1bec777 --- /dev/null +++ b/header.php_orig @@ -0,0 +1,191 @@ + section and everything up till
+ * + * @package SKT Restaurant + */ +?> + +> + + + + + + + + + + +> +
+
+ + + + + + +
+
+ +
+ + + + +
+ +
+ + + +
+ 10 ) { + $slAr[$m]['image_src'] = of_get_option('slide'.$i, true); + $slAr[$m]['image_button'] = of_get_option('slidebutton'.$i, true); + $slAr[$m]['image_url'] = of_get_option('slidelink'.$i, true); + $m++; + } + } + } + $slideno = array(); + if( $slAr > 0 ){ + $n = 0;?> +
+ + <?php echo esc_attr($sv['image_title']);?> + +
+ +
+
+ + +

+
+ + + +
+

+ + + +
+ + +
+
+ +
+
+ + + +
+ width.'" height="'.get_custom_header()->height.'" alt="" />'; + } else { + echo ''; + } + } + elseif( has_post_thumbnail() ) { + $src = wp_get_attachment_image_src( get_post_thumbnail_id($post->ID), 'homepage-thumb' ); + $thumbnailSrc = $src[0]; + echo ''; + } + elseif ( ! empty( $header_image ) ) { + echo ''; + } + else { + echo ''; + } ?> +
+ + + + + + + 0 ) { + $numSections = esc_attr( of_get_option('numsection', true) ); + for( $s=1; $s<=$numSections; $s++ ){ + $title = ( of_get_option('sectiontitle'.$s, true) != '' ) ? esc_html( of_get_option('sectiontitle'.$s, true) ) : ''; + $secid = ( of_get_option('menutitle'.$s, true) != '') ? esc_html( of_get_option('menutitle'.$s, true) ) : ''; + $class = ( of_get_option('sectionclass'.$s, true) != '' ) ? esc_html( of_get_option('sectionclass'.$s, true) ) : ''; + $content = ( of_get_option('sectioncontent'.$s, true) != '' ) ? of_get_option('sectioncontent'.$s, true) : ''; + $hide = ( of_get_option('hidesec'.$s, true) != '' ) ? of_get_option('hidesec'.$s, true) : ''; + $bgcolor = ( of_get_option('sectionbgcolor'.$s, true) != '' ) ? of_get_option('sectionbgcolor'.$s, true) : ''; + $bgimage = ( of_get_option('sectionbgimage'.$s, true) != '' ) ? of_get_option('sectionbgimage'.$s, true) : ''; + ?> +
style="" id="" class=""> +
style="width:100%"> +
+ +

+ + +
+
+
+ +
+ + \ No newline at end of file