Typo3 dockerisieren -> HTTP 404

greystone

Active Member
Hallo zusammen,

ich habe gestern mal versucht ein bestehendes Typo3 zu dockerisieren. Ich bin nicht sehr weit gekommen. Die Startseite wird angezeigt. Das Login in für das Backend wird angezeigt. Für alles andere (auch das Typo3-Backend) bekomme ich nur HTTP 404 - Errors. Vielleicht hat ja jemand von Euch einen Tip für mich.

Typo3 neu installieren

Als zweiten Schritt nach der fehlgeschlagenen direkten Dockerisierung habe ich erst mal ein neues Typo3 in einem Docker-Container installiert. Das ging dann irgendwann.

Hier die Configs dazu:
  • NGINX-Reverse-Proxy im Host-OS https://nopaste.debianforum.de/42159
  • docker-compose.yml https://nopaste.debianforum.de/42162

    In der yml-Datei sind falscherweise sowohl build-Direktive als auch ein Image-Direktive angegeben. Das Image habe ich für die Neuinstallation genutzt. Das Build-Directory dann für die Migration der bestehenden Instanz. Auch die Command-Direktive ist nur aktiviert, wenn auch Build-Directory aktiv ist. Das Dockerfile für den eigenen Build (Versionierung noch für 1:1 des Produktivsystems) ist (Ja. Ist EOL. Upgradeprozess läuft aktuell):
    Code:
    FROM debian:11
    RUN apt-get update
    RUN apt-get install -y vim apache2 libapache2-mod-php7.4 php-common php-xmlrpc php7.4 php7.4-bz2 php7.4-cgi php7.4-cli php7.4-common php7.4-curl php7.4-dba php7.4-fpm php7
    .4-gd php7.4-intl php7.4-json php7.4-mbstring php7.4-mysql php7.4-opcache php7.4-readline php7.4-soap php7.4-sqlite3 php7.4-xml php7.4-xmlrpc php7.4-xsl php7.4-zip
  • Apache im Container: https://nopaste.debianforum.de/42161
Wichtig war es, die passenden Einstellungen für das Typo3 vorzunehmen (LocalConfiguration.php):

Code:
return [
        ...
        SYS => [
        'reverseProxyHeaderMultiValue' => 'first',
        'reverseProxyIP' => '172.24.0.1',
        'reverseProxySSL' => '*',
        ...
        ],
        ...
];

Besonders wichtig war die reverseProxyIP. Das muss die RFC1918-IP-Adresse des Hosts sein, in dem der Docker-Container seine IP hat. Ist der Wert falsch, geht überhaupt nichts. (Fehlermeldung: 404 / Page Not Found / The page did not exist or was inaccessible. Reason: No site configuration found.)

Typo3 migrieren

Dann habe ich nochmal die Migration versucht. Die Startseite wird mir interessanterweise korrekt (Bilder, CSS, alles Top) angezeigt. Auch die Loginmaske für das Backend funktioniert. (Das Backend selbst nach Anmeldung aber nicht mehr). Sobald ich einen Link klicke bekomme ich immer nur noch einen HTTP 404. Beispiel (apache httpd access.log aus dem Docker-Container):

Code:
172.29.0.1 - - [14/May/2024:16:24:22 +0000] "GET /guidelines-working-groups/working-groups/list-of-working-groups HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:26 +0000] "GET /memberships-regional-sections/membership/information-registration HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:26 +0000] "GET /memberships-regional-sections/membership/our-domain-members HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:27 +0000] "GET /memberships-regional-sections/regional-sections/regional-development-sub-committee HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:28 +0000] "GET /memberships-regional-sections/regional-sections/our-domain-regions HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:29 +0000] "GET /certification-testing/certified-equipment/list-of-certified-equipment HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:30 +0000] "GET /certification-testing/authorised-testing-laboratories-and-evaluation-officers/list-of-authorised-test-laboratories-atl HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:30 +0000] "GET /certification-testing/authorised-testing-laboratories-and-evaluation-officers/list-of-authorised-evaluation-officers-aeo HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:31 +0000] "GET /certification-testing/useful-information/certification-classes HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:32 +0000] "GET /certification-testing/useful-information/test-methods HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:37 +0000] "GET /typo3/ HTTP/1.1" 200 3578 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:40 +0000] "GET /typo3/ajax/login/preflight HTTP/1.1" 404 436 "https://www.domain.org/typo3/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:47 +0000] "POST /typo3/login?loginProvider=1433416747 HTTP/1.1" 404 436 "https://www.domain.org/typo3/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:24:52 +0000] "POST /typo3/login?loginProvider=1433416747 HTTP/1.1" 404 436 "https://www.domain.org/typo3/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
...
172.29.0.1 - - [14/May/2024:16:35:14 +0000] "GET / HTTP/1.1" 200 8819 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:35:15 +0000] "GET /typo3temp/assets/css/e409372fc3128107f7aff14319dd3ce0.css?1698403516 HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:35:15 +0000] "GET /typo3temp/assets/js/c01c8eb1024cdb1dffde568b4b33e7bd.js?1676039419 HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:35:15 +0000] "GET /typo3conf/ext/contentpackage/Resources/Public/fonts/Roboto-Regular.woff2 HTTP/1.1" 200 52985 "https://www.domain.org/typo3conf/ext/contentpackage/Resources/Public/css/screen.css?1691493742" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:35:15 +0000] "GET /typo3conf/ext/contentpackage/Resources/Public/fonts/icomoon/icomoon.ttf?adhd3y HTTP/1.1" 200 3769 "https://www.domain.org/typo3conf/ext/contentpackage/Resources/Public/css/screen.css?1691493742" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"
172.29.0.1 - - [14/May/2024:16:35:15 +0000] "GET /typo3temp/assets/js/c01c8eb1024cdb1dffde568b4b33e7bd.js?1676039419 HTTP/1.1" 404 436 "https://www.domain.org/" "Mozilla/5.0 (X11; Linux x86_64; rv:125.0) Gecko/20100101 Firefox/125.0"

Ich habe auch schon aus dem git aus der 11er Version von Typo3 die Original .htaccess des root-Folders geholt (Diese .htaccess) und ausprobiert. Hat nichts geändert.

Die .htaccess im Typo3 ist die Standarddatei plus eigene zusätzliche Weiterleitungen.

$webroot/typo3temp habe ich gelöscht (find $webroot/typo3temp -type f -exec rm -f {} \+) . Berechtigungen im Docker-Container habe ich manuell angepasst.

Möglicherweise hat das irgendwie mit dem URL-Routing von Typo3 zu tun. Damit kenn ich mich aber leider gar nicht aus.

Danke im Voraus
 
Last edited:
Gibt es einen Grund, wieso Du nicht gleich die 12er Typo3 Version nimmst? Aber ok, bleiben wir bei 11.

Du solltest dieses docker-compose File als Basis verwenden: https://github.com/martin-helmich/docker-typo3/blob/master/11.5/docker-compose.yml
Dazu einige Anmerkungen:
- Der Container Ersteller geht von MySQL aus, Du verwendest MariaDB. Kann funktionieren, muss nicht.
- Wozu ports: "127.0.0.1:8080:80"? M.E. hat die IP Adresse hier nichts zu suchen.
- Die zweite bis fünfte Zeile ist bereits in der ersten Zeile enthalten. Daher ist m.E. nur die erste Zeile nötig, wenn die Ordnerstruktur darin so aussieht wie hier angedeutet. Der Autor verwendet Volumes, Du verwendet Pfade. Passen alle Rechte? M.E. solltest Du den Vorgaben des Autors folgen und hier lieber Volumes verwenden.
- ./data/www:/var/www/html
- ./data/www/fileadmin:/var/www/html/fileadmin
- ./data/www/typo3conf:/var/www/html/typo3conf
- ./data/www/typo3temp:/var/www/html/typo3temp
- ./data/www/uploads:/var/www/html/uploads
Alternativ:
- ./data/www/html:/var/www/html
wenn Du die anderen vier auch noch beibehalten willst. Wenn die Ordnerstruktur nicht mit dem was Typo3 erwartet übereinstimmt, passts hinten und vorne nicht.
TLDR: nimm die vorgesehenen Volumes.

- Einrückungen: passen nicht.
- Volumes am Ende:
volumes:
db_data:
typo3_data:
Wozu weshalb warum? Werden nirgendwo verwendet.

Proxy:
lass den Nginx im Host OS sein und verwende einen containerisierten Proxy wie https://nginxproxymanager.com/ . Packe ihn ins gleiche Netzwerk und fertig. In diesem Fall brauchst Du auch Ports überhaupt nicht rauslegen und kannst Dir die "ports:" Sektion komplett sparen. Zudem kümmert sich der NPM dann automatisch um Let's Encrypt Zertifikate.

Das waren erst mal einige Punkte, da gibts sicher noch deutlich mehr.

TIPS:
- separiere Deine compose-files von Deinen Daten (jeweils in einem anderen Dir). Das hat den Vorteil, dass Du Deine compose Files in ein privates Github Repo pushen kannst und Deine Daten mit Backupsoftware sichern kannst.
- Wenn Du eine GUI haben willst: https://github.com/louislam/dockge
- https://containrrr.dev/watchtower/ für Updates
- Telegram Bot für Updatenachrichten:
To view this content we will need your consent to set third party cookies.
For more detailed information, see our cookies page.
 
Grundsätzlich: Ich habe mittlerweile eine Aussage des PHP-Programmierers, dass hier seitens Typo3 einiges beachtet werden muss, bei der Konfiguration und der sonstigen Einrichtung. Insofern hat sich das Thema also vermutlich erledigt.

Danke für die diversen Anregungen. Muss ich mir mal anschauen und drüber nachdenken.

Weiterhin hat ja das frische Typo3 wunderbar funktioniert.

Schließlich noch Sorry für das chaotische docker-compose.yml. Ich habe da halt schon diverse Iterationen an Tests gemacht. Deswegen ist das nicht ganz perfekt und geradlinig. Kann auch sein, dass die Übernahme des Dateinhalts die Formatierung verändert hat (Einrückungen, ...)

Gibt es einen Grund, wieso Du nicht gleich die 12er Typo3 Version nimmst? Aber ok, bleiben wir bei 11.
Es geht letztlich um eine Migration einer bestehenden komplexen Typo3-Seite in einen Container. Und die läuft aktuell noch mit Typo3 v11.

Wozu ports: "127.0.0.1:8080:80"? M.E. hat die IP Adresse hier nichts zu suchen.
Ich binde Ports, die von außen nicht erreichbar sein müssen, bevorzugt an localhost.

Der Autor verwendet Volumes, Du verwendet Pfade. Passen alle Rechte? M.E. solltest Du den Vorgaben des Autors folgen und hier lieber Volumes verwenden.
Ich mag es lieber, wenn alle Daten eines Containers in einem Ordner auf dem Host liegen. Rechte passen (habe ich bei laufendem Containern wie benötigt gesetzt).

Lass den Nginx im Host OS sein und verwende einen containerisierten Proxy wie https://nginxproxymanager.com/ . Packe ihn ins gleiche Netzwerk und fertig. In diesem Fall brauchst Du auch Ports überhaupt nicht rauslegen und kannst Dir die "ports:" Sektion komplett sparen. Zudem kümmert sich der NPM dann automatisch um Let's Encrypt Zertifikate.
Geht nicht. Da ist noch mehr, was integriert werden muss. Bewusste Entscheidung das erst einmal über den Host-Nginx zu lösen.
 
Last edited:
Ich habe nochmal spasseshalber einen externen NGINX-Proxy vor die Live-Seite im Internet geschaltet. Das geht auch direkt. Hmmm ...

Das sind die beiden NGINX-Konfigurationen...

NGINX der den Docker-Container bedient (nur T3-Hauptseite funktioniert):

Code:
server {

    listen 1.2.32.4:80 default_server;
    return 301 https://www.mydomain.tld$uri;

}

server {
        listen 1.2.32.4:443 ssl;

        server_name               mydomain.tld;
        ssl_certificate           /etc/ssl/private/mydomain.tld/bundle.pem;
        ssl_certificate_key       /etc/ssl/private/mydomain.tld/mydomain.tld.key;

        ssl_session_cache  builtin:1000  shared:SSL:10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers on;

        return 301 https://www.mydomain.tld$uri;

}

server {
        listen 1.2.32.4:443 ssl;

        server_name               www.mydomain.tld;
        ssl_certificate           /etc/ssl/private/mydomain.tld/bundle.pem;
        ssl_certificate_key       /etc/ssl/private/mydomain.tld/mydomain.tld.key;

        ssl_session_cache  builtin:1000  shared:SSL:10m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers on;

        location / {

            proxy_pass                          http://127.0.0.1:8080;
            proxy_set_header  Host              $http_host;   # required for docker client's sake
            proxy_set_header  X-Real-IP         $remote_addr; # pass on real client's IP
            proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
            proxy_set_header  X-Forwarded-Proto https;
            proxy_read_timeout                  900;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";
        }

}

NGINX der den Live-Server im Internet anspricht (Funktioniert komplett einwandfrei):

Code:
# configuration file /etc/nginx/sites-enabled/mydomain.tld.conf:
server {
        listen 80;
        listen [::]:80;

        server_name mydomain.tld;

        return 301 https://$host$request_uri;

        client_max_body_size 50M;
}

server {

        listen              443 ssl;
        server_name         mydomain.tld;
        ssl_certificate     /etc/ssl/private/mydomain.tld/bundle.pem;
        ssl_certificate_key /etc/ssl/private/mydomain.tld/mydomain.tld.key;
        proxy_ssl_verify    off;
        include letsencrypt.conf;

        location / {

                proxy_pass https://mydomain.tld;
                proxy_set_header Host mydomain.tld;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        client_max_body_size 50M;

        include /etc/nginx/ssl.conf;

}

# configuration file /etc/nginx/letsencrypt.conf:
location '/.well-known/acme-challenge' {
  default_type "text/plain";
  root        /var/www/html;
}

# configuration file /etc/nginx/ssl.conf:
add_header Strict-Transport-Security max-age=15768000;

ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';

ssl_prefer_server_ciphers on;

ssl_protocols       TLSv1.2 TLSv1.3;

ssl_session_cache shared:SSL:50m;
ssl_session_timeout 5m;

ssl_dhparam /etc/nginx/ssl-dhparams.pem;
 
Back
Top