Ich habe gelesen, dass man --link nicht mehr verwenden soll, um
Docker-Container zu "verbinden" - vielleicht brauche ich das auch nicht,
aber wie mache ich das:
Ich habe schon einen funktionierenden mysql-Container, der Port 3306
publiziert, da kann ich mich vom Host aus auch mit mysql hin verbinden.
Jetzt baue ich einen zweiten Container (node.js), und aus diesem heraus
möchte ich auch in die Datenbank vom mysql-Container greifen können -
möglichst auch noch nach einem Neustart der beiden Container.
Wie macht man das jetzt? Nur weil der Host Zugriff hat, hat man das vom
Container innerhalb ja nicht, oder?
Wehc schrieb:> Na wenn es sein muss, wie geht das da? Ich habe den Container sonst> immer mit einem Kommando in einer Batch-datei gestartet.
Du schreibst eine docker-compose.yml, die die beiden Container und deren
Verbindungen und abhängigkeiten beschreibt, und dann startest du deinen
Container-Verbund einfach per "docker-compose up". Das ist genau für
solche Anwendungsfälle gedacht.
https://docs.docker.com/compose/
Jetzt bin ich weiter, und teilweise funktioniert es schon - meine
docker-compose.yml sieht so aus:
1
version: "3.7"
2
services:
3
s_node:
4
image: "node"
5
depends_on:
6
- s_db
7
networks:
8
- the-shared-network
9
user: "node"
10
working_dir: /home/node/app
11
environment:
12
- NODE_ENV=production
13
volumes:
14
- ./:/home/node/app
15
expose:
16
- "8081"
17
command: "node server.js"
18
19
s_db:
20
image: mariadb
21
ports:
22
- "3306:3306"
23
networks:
24
- the-shared-network
25
volumes:
26
- mysql-storage:/var/lib/mysql
27
environment:
28
MARIADB_ROOT_PASSWORD: XXXXXX
29
30
volumes:
31
mysql-storage:
32
external: true
33
34
networks:
35
the-shared-network: {}
Im gleichen loklaen Verzeichnis wie die docker-compose.yml Verzeichnis
(was als volume gemountet wird nach /home/node/app im container) liegt
eine Datei server.js, die das modul express benutzt. Dieses wird aber
nicht gefunden, obwohl ich der Meinung war, es ist im node-image
enthalten. Was fehlt?
die Fehlerzeile lautet:
s_node_1 | Error: Cannot find module 'express'
Wehc schrieb:> Dieses wird aber> nicht gefunden, obwohl ich der Meinung war, es ist im node-image> enthalten. Was fehlt?
Dann wird es wohl nicht enthalten sein. Hast du im Ordner, der da nach
/home/node/app reingezogen wird, einen "node_modules" Unterordner incl.
express?
Falls nicht, fehlt ein npm install. Quick-n-dirty:
command: "node server.js"
durch
command: "npm install"
ersetzen, einmal docker-compose up, und dann wieder zurückstellen.
Geht auch zuverlässig ohne compose:
Option 1: Zugriff über die Gateway IP. Wenn du die Default Bridge
verwendest, ist das 172.17.0.1. der entsprechende Port muss forwarded
werden (-p 3306:3306).
Option 2: beide Container dem gleichen Network zuweisen (Bridge, aber
nicht die Default bridge).
Dann kann der name des MySQL Containers verwendet werden, um sich aus
anderen Containern damit zu verbinden. Kein portforwarding erforderlich.
Εrnst B. schrieb:> Falls nicht, fehlt ein npm install. Quick-n-dirty:> command: "node server.js"> durch> command: "npm install"> ersetzen, einmal docker-compose up, und dann wieder zurückstellen.
Besser wäre es aber, das "npm install" ins Dockerfile per RUN
einzutragen.
Moskito schrieb:> Geht auch zuverlässig ohne compose:
Klar geht's auch ohne, nur eben umständlicher.
Εrnst B. schrieb:> Falls nicht, fehlt ein npm install. Quick-n-dirty:> command: "node server.js"> durch> command: "npm install"> ersetzen, einmal docker-compose up, und dann wieder zurückstellen.
Was ist eigentlich ein Dockerfile? Genau: eine Vorschrift, um Images zu
bauen. Womöglich könnte man "npm install" beim Bauen des Image...? Oder
zur Not im Entrypoint?
Sheeva P. schrieb:> Was ist eigentlich ein Dockerfile? Genau: eine Vorschrift, um Images zu> bauen. Womöglich könnte man "npm install" beim Bauen des Image...?
Natürlich ist das die schönere Lösung.
Er verwendet aber direkt das "node"-Image, und baut kein eigenes. Und er
mountet direkt seinen gesamten Source-Tree als volume in den container.
d.H.: nur einen eigenen Container "FROM: node" mit "npm install" bauen
reicht nicht, sein volume-mount macht die ganzen dadurch installierten
Module wieder unsichtbar.
"von außen" einmal npm install laufen lassen könnte reichen, aber: Dafür
muss auch außerhalb vom Docker ein nodejs installiert sein, in einer
kompatiblen Version.
Der vorgeschlagene "Quick&Dirty"-Hack mit dem einmaligen "command: npm
install" installiert die Packages ja nicht (nur) in den container,
sondern in das volume. d.H: Das übersteht auch ein "recreate" und in
gewissen Grenzen auch pull/updates.
Solange man noch am entwickeln ist und sich der Sourcecode oft ändert,
halte ich das für eine durchaus brauchbare Lösung, weil man mit einem
einfachen&schnellem restart statt einem langwierigerem build auskommt.
Εrnst B. schrieb:> Sheeva P. schrieb:>> Was ist eigentlich ein Dockerfile? Genau: eine Vorschrift, um Images zu>> bauen. Womöglich könnte man "npm install" beim Bauen des Image...?>> Natürlich ist das die schönere Lösung.> Er verwendet aber direkt das "node"-Image, und baut kein eigenes.
Was aber sehr einfach wäre.
> Und er mountet direkt seinen gesamten Source-Tree als volume in den> container.
Was nicht nötig wäre.
> d.H.: nur einen eigenen Container "FROM: node" mit "npm install" bauen> reicht nicht, sein volume-mount macht die ganzen dadurch installierten> Module wieder unsichtbar.>> "von außen" einmal npm install laufen lassen könnte reichen, aber: Dafür> muss auch außerhalb vom Docker ein nodejs installiert sein, in einer> kompatiblen Version.
Was dann den Sinn von Docker irgendwie über den Haufen wirft.
Εrnst B. schrieb:> Sheeva P. schrieb:>> Was ist eigentlich ein Dockerfile? Genau: eine Vorschrift, um Images zu>> bauen. Womöglich könnte man "npm install" beim Bauen des Image...?>> Natürlich ist das die schönere Lösung.
Ich wäre froh, wenn es "die schönere Lösung" wäre.
> Er verwendet aber direkt das "node"-Image, und baut kein eigenes. Und er> mountet direkt seinen gesamten Source-Tree als volume in den container.
How to shoot yourself in the foot: Container nicht verstanden. ;-)