Docker Container Entwicklungsumgebung

Bewertung: 4 / 5

Stern aktivStern aktivStern aktivStern aktivStern inaktiv
 

Einblicke in die Joomla! Entwicklungsumgebung bei Medialekt

Im Blog vom JoomISP Projekt hatte ich zuletzt erste Einblicke in unsere Joomla! Entwicklung gewährt.

Vor allem bin ich auf Themen wie die Projektverwaltung, Versionierung, Codequalität sowie Continuous Integration & Development eingegangen.

In diesem Beitrag gehe ich nun näher in die lokale Joomla! Installation ein, genauer gesagt von der bisherigen Virtualisierung zum moderneren Container Prinzip.

 

Bisherige virtuelle Serverumgebung mit VirtualBox

Bis vor wenigen Wochen diente eine VirtualBox Maschine mit einem vollwertigem Debian Webserver als lokale Entwicklungsplattform.
Zur Verwaltung diente wie auf den richtigen Webserver auch das Tool ISPConfig.

Die IDEs vor allem Netbeans hatten Ihre Projekte direkt beim Speichern per FTP darauf synchronisiert, womit die Änderung umgehend Live getestet werden konnte.

Der Nachteil dieser Lösung war zum einen die Ressourcen, so belegte der komplette virtuelle PC rund 20GB meiner SSD.
Außerdem blieb die laufende Instanz immer hängen, sobald der PC in den Ruhezustand gin. Er musste danach also jedesmal von neuen gestartet werden.

 

Anzeige

Neue Lösung mit Docker Container

Da ich bereits seit längerem mit dem Gedanken spiele, mich mit dem Thema Docker zu beschäftigen, nahm ich dies gleich als produktiven Anlass dazu.

 

 

Das aktuelle c´T Wissen - Docker Heft sowie nebenstehendes Buch sind hilfreiche Quellen.

 

 

Die Installation von Docker geht unter Linux relativ einfach:

sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"

sudo apt-get update && sudo apt-get install docker-ce

 

Die Funktion kann mit einem ersten Hello-World-Container überprüft werden:

sudo docker run hello-world

 

Mit Docker-Compose können dann relativ einfach YAML Dateien definiert werden, welche dann mehrere Container miteinander verbinden.

sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

 

Damit ist nun schonmal alles vorbereitet, um mit den Containern loszulegen.

Vorher definiere ich noch gezielt ein eigenes Docker Netzwerk:

sudo docker network create --subnet=172.XX.X.X/16 mynetwork

 

Verwaltung der Docker Container mit Portainer

Sofern man später mehrere Container hat, diese komfortabel verwalten und auch aktualisieren möchte, sind grafische Tools wie Portainer sehr hilfreich.

Mit folgendem Befehl wird das neueste (latest) Image von Portainer heruntergeladen, dem Container ein Hostname sowie IP-Adresse zugewiesen, eine Portweiterleitung definiert sowie persistente Benutzerdaten angelegt.
Er wird als Hintergrundprozess gestartet und startet eigenständig neu, wenn er abstürzt oder der Host neu startet:

sudo docker run --name portainer \
--hostname portainer \
--network mynetwork \
--ip 172.XX.X.2 \
-d \
-p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /opt/docker_portainer/data:/data \
--restart always \
portainer/portainer

 

Persistente Daten lege ich generell bei mir unter /var/docker_NAMEDESCONTAINERS.

 

Portainer ist dann unter localhost:9000 über einen Browser im Netzwerk erreichbar:

docker portainer

 

Er kann auch relativ einfach aktualisiert werden:

sudo docker stop portainer
sudo rm portainer
sudo docker pull portainer/portainer

Zuerst wird der Container gestoppt, anschließend gelöscht und das Image neu heruntergeladen.

Mit dem obigen Befehl kann der Container dann neu gestartet werden. Da er persistente Datenordner hat, sollte er sämtliche Einstellungen, Benutzer etc. von vorher haben.

 

MySQL Docker Container

Hier starte ich das neueste MySQL Image mit eigenem Passwort und auch wieder persistente Daten für meine Datenbanken.
Der MySQL Server Container horcht auf dem Standardport 3306:

docker run --name mysql \
           --hostname mysql \
           --network mynetwork \
           --ip 172.XX.X.3 \
           -d \
           -p 3306:3306 \
           -v /opt/docker_mysql:/var/lib/mysql \
           -e MYSQL_ROOT_PASSWORD="MEINPASSWORT" \
           --restart always \
           mysql

 

PHPMyAdmin sowie andere Applikationen konnten sich erstmal nicht verbinden, hierfür musste mysql_nativ_password gesetzt werden:

sudo docker exec -it mysql bash
mysql -u root -p
MEINPASSWORT
ALTER USER root IDENTIFIED WITH mysql_nativ_password BY "MEINPASSWORD";

 

PHPMyAdmin Docker Container

Zur Verwaltung meiner Datenbanken und Tabellen bin ich PHPMyAdmin gewohnt und möchte diesen auch nicht missen, deshalb stecke ich Ihn in einen eigenen Container:

docker run --name PHPMyAdmin \
           --hostname phpmyadmin \
           --network mynetwork \
           --ip 172.XX.X.4 \
           -d \
           -p 8080:80 \
           -v /opt/docker_phpmyadmin/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php \
           -e PMA_HOST=MySQL \
           --restart always \
           phpmyadmin/phpmyadmin

 

Mit der config.user.inc.php kann ich PHPMyAdmin eine eigene Konfiguration geben, z.B erhöhe ich das Upload-Limit auf 512MB:

$cfg['ExecTimeLimit'] = 0; //Now there is no execution time limit<br/ >ini_set("upload_max_filesize", "512M");
ini_set("post_max_size", "512M");
ini_set("max_execution_time", "1000");
ini_set("max_input_time", "1000");
ini_set("max_input_vars", 10000);

 

Wer auch einen "pmadb fehlerhaft" erhält kann einfach auf anlegen Klicken und den Bildschirmen folgen:

phpmyadmin pmadb fehlerhaft

 

Joomla! Docker Container

Zuletzt werden noch die offiziellen Joomla! Images als Container angelegt, selbstverständlich mit persistente Daten und dem standard Port 80:

sudo docker run --name Joomla \
           --hostname joomla \
           --network mynetwork \
           --ip 172.XX.X.5 \
           -d \
           -p 80:80 \
           --link MySQL:db \
           -e JOOMLA_DB_HOST=MySQL \
           -e JOOMLA_DB_USER="root" \
           -e JOOMLA_DB_PASSWORD="MEINPASSWORT" \
           -v /opt/docker_joomla:/var/www/html \
           joomla

 

Danach kann mit einem Browser die localhost Adresse aufgerufen werden und der gewohnte Joomla! Installationsprozess startet.

In den Datenbankeinstellungen muss als Servername der Hostname vom MySQL Server eingetragen werden. In meinem Fall einfach nur "mysql". Der Rest sollte bekannt sein.

 

Finales Docker-Compose Setup

Da im eigentlichen Joomla! Docker Image PHP als Apache2Handler läuft und ich hierbei Umstände bei den Berechtigungen erwarte, habe ich basierend dem funktionierenden MySQL- & PHPMyAdmin Setup gleich ein Docker-Compose Setup geschrieben. Dieses lädt jedoch einen eigenständigen Apache sowie PHP als FPM.

 

Für meine Containersammlung lege ich unter einem beliebigen Verzeichnis, in meinem Fall /opt/docker_entwicklung folgende Datei- & Ordnerstruktur an:

  • apache
    • demo.apache.conf
    • Dockerfile
  • php
    • Dockerfile
  • public_html
    • entwicklung
      • Joomla! Dateien
    • index.php
  • docker-compose.yml

 

Ich beginne von oben nach unten mit den Dateien und anschließend kurzer Beschreibung.

 

/apache/demo.apache.conf

ServerName localhost

LoadModule deflate_module /usr/local/apache2/modules/mod_deflate.so
LoadModule proxy_module /usr/local/apache2/modules/mod_proxy.so
LoadModule proxy_fcgi_module /usr/local/apache2/modules/mod_proxy_fcgi.so
LoadModule rewrite_module /usr/local/apache2/modules/mod_rewrite.so

<VirtualHost *:80>
    # Proxy .php requests to port 9000 of the php-fpm container.
    ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php:9000/var/www/html/$1
    DocumentRoot /var/www/html/
    
<Directory /var/www/html/> DirectoryIndex index.php Options Indexes FollowSymLinks AllowOverride All Require all granted </Directory> # Send apache logs to stdout and stderr. CustomLog /proc/self/fd/1 common ErrorLog /proc/self/fd/2
</VirtualHost>

Dies ist eine gewöhnlihce von Apache2 bekannt Vhost Datei, welche auf den standard Port 80 hört.
Es sorgt auch dafür, dass PHP-FPM verwendet wird und der Document-Root /var/www/html ist.

 

/apache/Dockerfile

ARG APACHE_VERSION=""
FROM httpd:${APACHE_VERSION:+${APACHE_VERSION}}

RUN apt-get update && apt-get upgrade -y

# Copy apache vhost file to proxy php requests to php-fpm container.
COPY demo.apache.conf /usr/local/apache2/conf/demo.apache.conf
RUN echo "Include /usr/local/apache2/conf/demo.apache.conf" \
    >> /usr/local/apache2/conf/httpd.conf

Hier wird die Apache Version empfangen, welche ich später als Variable einstellen kann und verwendet.
Anschließend wird alles aktualisiert und die Vhost Datei kopiert und eingebunden.

 

/php/Dockerfile

ARG PHP_VERSION=""
FROM php:${PHP_VERSION:+${PHP_VERSION}-}fpm

RUN apt-get update && apt-get upgrade -y
RUN apt-get install build-essential libssl-dev zlib1g-dev libpng-dev libjpeg-dev libfreetype6-dev \
libzip-dev libbz2-dev libxml2-dev -y RUN docker-php-ext-install mysqli zip bz2 RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ \ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/ \ && docker-php-ext-install -j$(nproc) gd RUN usermod -u 1000 www-data

Auch hier wird die PHP Version empfangen, welche verwendet werden soll.
Anschließend wird das System aktualisiert und einige PHP-Erweiterungen installiert.
Zuletzt wird der Webserver User noch die UID 1000 zugewiesen. Dies entspricht auch meinem User auf dem Host, sodass es keine Berechtigungskonflikte gibt.

 

Die Dateien in public_html sollten klar sein, in der obersten index.php habe ich testweise ein:

echo phpinfo();

 

Zuletzt noch die eigentliche docker-compose.yml

version: "3.7"
services:
  mysql:
    container_name: mysql
    image: mysql:${MYSQL_VERSION:-latest}
    restart: always
    networks:
      - mynetwork
    ports:
      - "3306:3306"
    volumes:
      - "/opt/docker_mysql:/var/lib/mysql"
    environment:
      MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD}"
  phpmyadmin:
    container_name: phpmyadmin
    image: phpmyadmin/phpmyadmin
    restart: always
    depends_on:
      - mysql
    networks:
      - mynetwork
    ports:
      - "8080:80"
    volumes:
      - "/opt/docker_phpmyadmin/config.user.inc.php:/etc/phpmyadmin/config.user.inc.php"
    environment:
      PMA_HOST: "mysql"
  php:
    container_name: php
    build:
      context: './php/'
      args:
        PHP_VERSION: ${PHP_VERSION}
    restart: always
    networks:
      - mynetwork
    volumes:
      - "/opt/docker_php/php.ini:/usr/local/etc/php/php.ini"
      - ${PROJECT_ROOT}/:/var/www/html/
  apache:
    container_name: apache
    build:
      context: './apache/'
      args:
       APACHE_VERSION: ${APACHE_VERSION}
    restart: always
    depends_on:
      - php
      - mysql
    networks:
      - mynetwork
    ports:
      - "80:80"
    volumes:
      - ${PROJECT_ROOT}/:/var/www/html/
networks:
  mynetwork:

Hier dann wieder die bereits bekannten MySQL  & PHPMyAdmin Container, welche als Passwort jedoch diejenigen aus den Environments auslesen, deren Ports & persistente Datenordner.
PHP mit eigener php.ini um flexibel zu sein, um z.B. die Uploadgröße von Dateien zu erhöhen.
Apache & PHP bekommen jeweils den Document Root der Webdateien, Apache hängt zusätzlich von einem laufenden PHP sowie MySQL Container ab.

 

Ich habe bei mir dann noch im gleichen Wurzelverzeichnis wie die docker-compose.yml eine verstecke Datei .env worin ich diverse Variablen setze:

PHP_VERSION=7.3
MYSQL_VERSION=5.7
APACHE_VERSION=2.4

DB_ROOT_PASSWORD=MEINPASSWORT

PROJECT_ROOT=./public_html

 

Die Docker Instanzen können dann mit folgendem Befehl gestartet werden:

sudo docker-compose up -d

 

Auf der Konsole kann man einige Zeit verfolgen was das System macht. Am Ende sollten alle Container korrekt hochfahren und die index.php im Webroot sollte mit localhost/index.php aufgerufen werden können:

portainer entwicklungsumgebung gestartet

 

Nun kann man in Unterordnern des public_html Ordners die Joomla! oder andere CMS kopieren und entsprechend installiert werden.
Über den PHPMyAdmin Container können bequem die Datenbanken erstellt werden.

 

Wie im speziellen ein GIT-Repository Ordner mit dem Webordner abgeglichen werden kann, beschreibe ich mit Hilfe eines Inotify&Rsync-Skripts in meinem Webdesign Facts Blog!

 

e-max.it: your social media marketing partner

Geschäftszeiten

Montag - Freitag: 14:00 - 18:00
Samstag: 10:00 - 18:00

Newsletter

Tragen Sie sich in unseren Newsletter ein und erhalten Sie nützliche Infos.

JooWI Online

JooWI 3D BoxJooWI Online Warenwirtschaft ist einfach, flexibel und optimal für Ihr Unternehmen.
Weitere Infos finden Sie auf JooWI Online.

Bestellen Sie noch heute die 30 Tage GRATIS Version!

Kontakt

Medialekt eK
Bahnhofstr. 4a
DE-93342 Saal a.d. Donau

Telefon: +49 9441 1750403

contact email icon

Medialekt eK (2024) - Ihr Partner für:
Webdesign, Web Entwicklung, Webhosting, Server Wartung, Mediendesign, Mediendruck, IT Hardware & Software, Internet & Netzwerke, Reparatur & Instandhaltung, Datenrettung

Medialekt and this site is not affiliated with or endorsed by The Joomla! Project™. Any products and services provided through this site are not supported or warrantied by The Joomla! Project or Open Source Matters, Inc. Use of the Joomla!® name, symbol, logo and related trademarks is permitted under a limited license granted by Open Source Matters, Inc.