Docker - Starten des DEV-Containers stopped den PROD-Container

greystone

Active Member
Hallo,

ich habe mir gerade einen mariadb-Container gebaut und habe da eine DEV-Umgebung und eine PROD-Umgebung.

Das witzige ist jetzt, wenn ich die PROD-Umgebung starte, dann bekomme ich die Ausgabe...
Code:
cd $prod/app_database
docker-compose up -d
Recreating nextcloud_test_db ... OK
...und der mariadb-DEV container wird heruntergefahren.

Umgekehrt, wenn ich die DEV-Umgebung starte, dann bekomme ich die Ausgabe:
Code:
cd $dev/app_database
docker-compose up -d
Recreating nextcloud_db ... OK
...und der mariadb-PROD container wird heruntergefahren.

Mit den beiden Nextcloud-Webservercontainern ist dieses Verhalten nicht zu sehen. Woran könnte das liegen?

Das sind die Dateien:

nextcloud/app_database/docker-compose.yml
Code:
version: '2.4'

services:
  db:
    container_name: nextcloud_db
    build: ../../build/mariadb
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - ../data_db:/var/lib/mysql
    ports:
      - ${MYSQL_HOST_SOCKET}:3306
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    networks:
      - nextcloud_prod

networks:
   nextcloud_prod:
     name: nextcloud_prod

nextcloud/app_database/.env
Code:
MYSQL_ROOT_PASSWORD=sehrgeheim
MYSQL_HOST_SOCKET=127.0.0.1:13307

nextcloud_test/app_database/docker-compose.yml
Code:
version: '2.4'

services:
  db:
    container_name: nextcloud_test_db
    build: ../../build/mariadb
    restart: always
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW
    volumes:
      - ../data_db:/var/lib/mysql
    ports:
      - ${MYSQL_HOST_SOCKET}:3306
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    networks:
      - nextcloud_test

networks:
   nextcloud_test:
     name: nextcloud_test
name: nextcloud_prod

nextcloud_test/app_database/.env
Code:
MYSQL_ROOT_PASSWORD=nichtsogeheim
MYSQL_HOST_SOCKET=127.0.0.1:13308

Hier ist noch das Dockerfile aus dem Build-Verzeichnis:

Code:
FROM mariadb:10.5

COPY docker-entrypoint.sh /usr/local/bin
RUN mkdir /scripts
COPY deferred_execution_starter /scripts/deferred_execution_starter
COPY add_data /scripts/add_data

ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]
 
Nachtrag
Ich habe jetzt in den docker-compose-Dateien build ... durch image: mariadb10.5 ersetzt, weil ich die Anpassung nicht mehr benötige und deswegen das Original-Image verwenden kann. Das Verhalten ist identisch.
 
Ich habe jetzt mal das container-label unterhalb von services, also db in beiden Fällen umbenannt. Jetzt kann ich beide Container starten.

Aber trotzdem bekomme ich noch die Warnmeldung, dass der jeweils andere ein orphan vom aktuellen wäre:

Code:
cd $dev/app_database
docker-compose down

WARNING: Found orphan containers (nextcloud_db) for this project.
If you removed or renamed this service in your compose file, you can
run this command with the --remove-orphans flag to clean it up.

Wenn ich das empfohlene ausführe, dann wird der andere Container wieder gekillt.

Wenn ich noch eine weitere Testumgebung nextcloud_test2 erstelle und die IDs alle individualisiere, dann findet auch diese Umgebung die beiden anderen Umgegebungen und informiert dass beide orphan seien.
 
Last edited:
Sei froh dass sich der Docker-Schrott so verhält, sonst hättest Du wahrscheinlich schon Deine DBs geschrottet.
Hint: /var/lib/mysql
 
Sei froh dass sich der Docker-Schrott so verhält, sonst hättest Du wahrscheinlich schon Deine DBs geschrottet.
Hint: /var/lib/mysql

Code:
- ../data_db:/var/lib/mysql

Die obige Zeile aus dem docker-compose file bedeutet, dass der Pfad /var/lib/mysql (im Container) dem relativen Hostpfad ../data_db zugeordnet wird. Das sind in beiden Fällen unterschiedliche Verzeichnisse:

  • /home/docker/nextcloud_test/data_db
  • /home/docker/nextcloud/data_db

Da gibt es keinen Zugriffskonflikt.

Ansonsten: DB schrotten ist zum jetzigen Zeitpunkt noch kein Problem. Habe aber trotzdem lieber nochmal schnell das regelmässige Backup reingehackt. Nicht dass es doch noch gebraucht wird.
 
Last edited:
Die obige Zeile aus dem docker-compose file bedeutet, dass der Pfad /var/lib/mysql (im Container) dem relativen Hostpfad ../data_db zugeordnet wird.
OK, sah für mich eher nach Aufzählung als nach Alias aus.

PID-File, Lock-File und Socket der MariaDB sind ebenfalls strickt getrennt?

Was sagen die MariaDB-Logs dazu?
Hat Docker Verbose-Logs?
 
Docker-Compose verwendet de Namen des beinhalteten Verzeichnis standardmässig als Applikationsname. Dein Applikation heisst hier also beiden Fällen app_database laut Angaben. Du kannst dies über den "-p <NAME>" Flag von docker-compose umgehen oder eine ENV-Variable definieren, ich würde aber empfehlen die Verzeichnisse zu ändern.

Anmerkungen:
Für das Docker Netzwerkverhalten ist es nicht notwendig ist den Port 3306 zu exposieren solange du nicht ausserhalb des Stacks auf Mysql zugreifewn willst. Da die mysql CLI über "docker-compose exec <container> <shell>" abrufbar ist und Phpmyadmin als optionaler Container im Compose sein kann, ist das Exposieren generell nicht notwendig.

Standardmässig hat jeder docker-compose Stack sein eigenes interne Netzwerk. Es ist also nicht notwendig gesondert an zu geben ausser du willst Strukturen abbilden wie Frontend--nur-->Backend aber Backend--auch-->Datenbank

Es ist aufwendig und damit potentiell unsicher/problematisch eigene Container für Standardwerkzeug zu bauen (Datenbanken, ...) wenn der Originalhersteller diese bereits angibt. Nach Docker-Prinzip von segregation-of-duties soll jeder Container nur eine Aufgabe erfüllen so dass bis auf deine Applikation alles in Standardcontainer laufen kann und auch die Applikation würde auf einem Standardcontainer basieren.
 
@Joe User: Danke für die Bereitschaft zu helfen.
@d4f: Danke für die Erklärung.

Grundsätzlich versuche ich bei der Aufgabe eine Struktur zu finden, die praktisch ist. Ob's dabei gegen irgendwelche Grundsätze verstösst, ohne dass das für mich in der Situation Sinn ergibt, ist für mich erst einmal zweitrangig. Ich experimentiere dabei auch einfach noch etwas. Das nach aussen führen der DB-Ports war der Gedanke, dass es so einfacher ist mich darauf einzuloggen(Wartung, Diagnose), aber das geht mit docker exec natürlich genauso und ist wohl die bessere Wahl, weil ich dann mit dem korrekten DB-Client im Container zugreife und nicht mit einer unpassenden Version oder Typ(mariadb statt mysql) vom Hostsystem aus. Siehe [1].

Was das anpassen von Docker Images betrifft: In dem Fall war es bei mir für den MariaDB nicht mehr notewendig. Das fiel also weg. Beim Nextcloud-Container gibt es aber einige notwendige Anpassungen: Eigene Logos, diverse Konfigurationseinstellungen. Dafür braucht es einen Weg um die durchzuführen. D. h. ich muss den Container irgendwie anpassen. Den Weg, der mir da gut gefällt sehe ich noch nicht, also mache ich, dass es geht und denke drüber nach, wie es besser gehen kann.

Falls es interessiert, noch ein paar Worte zur Konfiguration:

Ich habe eine VM dort gibt es pro Nextcloud-Umgebung("Prod", "Test", ...) einen DB-Container und dann mehrere Anwendungscontainer(nextcloud mit Apache), d. h. einzelne Nextcloud-Instanzen. Die Instanzen bekommen jeweils eine Datenbank im DB-Container.

Mir ist klar, dass ich das in eine einzelne docker-compose-Datei unterbringen kann und auch die einzelnen Services(DB, Instanz1, ... Instanz N) dediziert starten und stoppen kann. Ich habe mich aber dazu entschieden, dass ich das auf verschiedene Dateien und Verzeichnisse aufteilen will. Ganz einfach aus dem Grund der Praktikabilität und Fehlervermeidung. Will ich eine Instanz herunterfahren gehe ich in das Verzeichnis und gebe "docker-compose down" ein. Das vermindert die Gefahr eines Flüchtigkeitsfehlers, dass ich (oder jemand anderes) aus Versehen mal einfach nur alles herunterfahre, weil ich vergessen habe, den Service explizit aufzuführen.

Die Verzeichnisstruktur sieht so aus:

Code:
.
├── app_database
│   ├── .env
│   └── docker-compose.yml
├── app_nx_heisenberg
│   ├── .env
│   └── docker-compose.yml
├── data_backup
│   ├── mysql.sql.xz.0000
│   └── heisenberg.sql.xz.0000
├── data_db
│   ├── aria_log.00000001
│   ├── aria_log_control
│   ├── ib_buffer_pool
│   ├── ib_logfile0
│   ├── ibdata1
│   ├── ibtmp1
│   ├── multi-master.info
│   ├── mysql
│   ├── mysql_upgrade_info
│   ├── heisenberg
│   └── performance_schema
└── data_nextcloud
    ├── heisenberg
    └── heisenberg_tmp

Was die Anpassung am Nextcloud-Image betrifft, so muss ich da am Anfang ein Script reinhängen, dass mir die Instanz-DB, den Benutzer und die Berechtigung in der MariaDB anlegt/konfiguriert. Dann muss ich zusätzlich am Ende ein Script reinhängen, was mir nachdem die Nextcloud-Installation durchgeführt wurde meine Instanzkonfiguration einspielt. Den Weg, den ich da im Moment gewählt habe ist dass ich das im entrypoint-Script entsprechend als externe Scriptaufrufe reingesetzt habe. Was mir daran auch nicht gefällt, ist, dass ich dem Nextcloud-Container dann das DB-Root-PW mitgeben muss, was dann da als Shellvariable gesetzt ist.

Wenn die Verzeichnisse anders heissen müssen, dann hänge ich da halt noch ein Eindeutigkeitsmerkmal dran.

Ein weiterer Grund, warum ich die Konfiguration auf mehrere docker-compose-Umgebungen aufgeteilt habe, ist der, dass die docker-compose-Dateien und auch die .env-Dateien dann alle strukturell identisch sind. Hätte ich es in einer Datei, dann hätte ich auch kompliziertere Variablen-Namen: Statt einfach nur NEXTCLOUD_ADMIN_PASSWORD müsste ich dann z. B. NEXTCLOUD_ADMIN_PASSWORD_1 oder NEXTCLOUD_ADMIN_PASSWORD_INSTANZNAME1 nehmen.

Die Ausführung als getrennte Docker-Compose Umgebungen ist dann auch der Grund, warum ich das Netzwerk explizit definieren muss, weil ich mich in den Nextcloud-Instanzen dann darauf mit external darauf beziehe.

Das Datenverzeichnis der Instanz (hier ./data_nextcloud/heisenberg) ist ein ZFS mit der gewünschten Quota drauf.

Hier auch nochmal die Nextcloud Docker-Compose:

Code:
version: '2.4'

services:
  app:
    container_name: nextcloud_${ID}
    build: ../../build/nextcloud_apache
    restart: always
    ports:
      - ${NEXTCLOUD_HOST_SOCKET}:80
    external_links:
      - nextcloud_db:db
    volumes:
      - ../data_nextcloud/${ID}:/var/www/html
      - ../data_nextcloud/${ID}_tmp:/mytmp
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${ID}
      - MYSQL_USER=${ID}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - MYSQL_HOST=db
      - TRUSTED_PROXIES=${TRUSTED_PROXIES}
      - OVERWRITEPROTOCOL=${OVERWRITEPROTOCOL}
      - OVERWRITEHOST=${OVERWRITEHOST}
      - NEXTCLOUD_ADMIN_USER=${NEXTCLOUD_ADMIN_USER}
      - NEXTCLOUD_ADMIN_PASSWORD=${NEXTCLOUD_ADMIN_PASSWORD}
      - SMTP_HOST=${SMTP_HOST}
      - MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS}
      - MAIL_DOMAIN=${MAIL_DOMAIN}
    networks:
      - nextcloud_prod

networks:
  nextcloud_prod:
    name: nextcloud_prod
    external: true

[1] https://codeberg.org/megabert/script-pastebin/src/branch/main/docker-mysql-client
 
Last edited:
Die Lösung, die mir zu dem MariaDB-Root-PW noch einfällt ist, dass ich das Password in eine Datei schreibe, die vom Hostsystem aus eingebunden ist. Nach der Ausführung des Setup-Scriptes wird diese Datei dann gelöscht.
 
Back
Top