J'ai quelques conteneurs pour une application web pour le moment (nginx, gunicorn, postgres et node pour construire des fichiers statiques à partir de la source et un rendu côté serveur React). Dans un fichier Docker pour le conteneur de nœuds, j’ai deux étapes: construire et exécuter ( Dockerfile.node ). Il se termine avec deux répertoires à l'intérieur d'un conteneur: bundle_client
- est un statique pour un nginx et bundle_server
- utilisé dans le conteneur de nœud lui-même pour démarrer un serveur express.
Ensuite, je dois partager un dossier statique construit (bundle_client
) avec le conteneur nginx. Pour ce faire, conformément à la référence de docker-compose dans mon docker-compose.yml
, j’ai les services suivants (voir complet docker-compose.yml ):
node:
volumes:
- vnode:/usr/src
nginx:
volumes:
- vnode:/var/www/tg/static
depends_on:
- node
et volumes:
volumes:
vnode:
L'exécution de docker-compose build
se termine sans erreur. Exécuter docker-compose up
fonctionne correctement et je peux ouvrir localhost:80
et il y a nginx, gunicorn et node express SSR tout fonctionne très bien et je peux voir une page Web mais tous les fichiers statiques retournent une erreur 404 non trouvée.
Si je vérifie les volumes avec docker volume ls
, je peux voir deux volumes nouvellement créés nommés tg_vnode
(que nous considérons ici) et tg_vdata
(voir full docker-compose.yml)
Si je vais dans un conteneur nginx avec docker run -ti -v /tmp:/tmp tg_node /bin/bash
, je ne pourrai pas voir mon dossier www/tg/static
qui mappera mes fichiers statiques à partir du volume du noeud. De plus, j'ai essayé de créer un dossier /var/www/tg/static
vide avec le conteneur nginx Dockerfile.nginx
mais il reste vide.
Si je mappe un dossier bundle_client
à partir de la machine hôte dans le docker-compose.yml
dans une section nginx.volumes
en tant que - ./client/bundle_client:/var/www/tg/static
, cela fonctionne bien et je peux voir tous les fichiers statiques servis avec nginx dans le navigateur.
Qu'est-ce que je fais de mal et comment faire en sorte que mon conteneur partage le contenu statique construit avec le conteneur nginx?
PS: J'ai lu tous les docs, tous les problèmes de github et les questions et réponses de stackoverflow et, si j'ai bien compris, il doit fonctionner et il n'y a aucune information à propos de ce qu'il faut faire quand ne l'est pas.
UPD: Résultat de docker volume inspect vnode
:
[
{
"CreatedAt": "2018-05-18T12:24:38Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "tg",
"com.docker.compose.version": "1.21.1",
"com.docker.compose.volume": "vnode"
},
"Mountpoint": "/var/lib/docker/volumes/tg_vnode/_data",
"Name": "tg_vnode",
"Options": null,
"Scope": "local"
}
]
Fichiers: Dockerfile.node , docker-compose.yml
Nginx dockerfile: Dockerfile.nginx
UPD: J'ai créé un référentiel simplifié pour reproduire une question: repo (Il y a des avertissements sur npm install
que rien ne s'installera et que l'on construira correctement). Lorsque nous ouvrons localhost:80
, nous voyons finalement une page vide et 404 messages pour les fichiers statiques (vendor.js
et app.js
) dans les outils de développement de Chrome, mais il devrait y avoir un message React app: static loaded
généré par le script react.
Deux changements dont vous avez besoin. Dans votre service de nœud et le volume comme
volumes:
- vnode:/usr/src/bundle_client
Puisque vous voulez partager /usr/src/bundle_client
, vous ne devez PAS utiliser /usr/src/
car cela partagera également le dossier complet et la structure.
Et puis dans votre service nginx, ajoutez le volume comme
volumes:
- type: volume
source: vnode
target: /var/www/test/static
volume:
nocopy: true
Le nocopy: true
indique clairement que sur la carte initiale du conteneur, le contenu du dossier mappé ne doit pas être copié. Et par défaut, le premier conteneur mappé sur le volume obtiendra le contenu du dossier mappé. Dans votre cas, vous souhaitez que ce soit le conteneur node
.
De même, avant de procéder aux tests, assurez-vous d’exécuter la commande ci-dessous pour supprimer les volumes mis en cache.
docker-compose down -v
Vous pouvez voir pendant le test que le conteneur contenait les fichiers
Dockerfile.node
...
COPY ./client /usr/src
...
docker-compose.yml
services:
...
node:
...
volumes:
- ./server/nginx.conf:/etc/nginx/nginx.conf:ro
- vnode:/usr/src
...
volumes:
vnode:
docker-compose up
crée avec ce Dockerfile.node et la section docker-compose un volume nommé avec les données enregistrées dans/usr/src.Dockerfile.nginx
FROM nginx:latest
COPY ./server/nginx.conf /etc/nginx/nginx.conf
RUN mkdir -p /var/www/tg/static
EXPOSE 80
EXPOSE 443
CMD ["nginx", "-g", "daemon off;"]
docker-compose
auront un /var/www/tg/static/
vide docker-compose.yml
...
nginx:
build:
context: .
dockerfile: ./Dockerfile.nginx
container_name: tg_nginx
restart: always
volumes:
- ./server/nginx.conf:/etc/nginx/nginx.conf:ro
- vnode:/var/www/tg/static
ports:
- "80:80"
- "443:443"
depends_on:
- node
- gunicorn
networks:
- nw_web_tg
volumes:
vdata:
vnode:
docker-compose up
produira que le volume vnode
nommé est créé et rempli avec les données de /var/www/tg/static
(vide à présent) dans un vnode existant.Donc, à ce stade, - Le conteneur nginx a/var/www/tg/static vide car il a été créé vide (voir mkdir dans Dockerfile.nginx) - Le conteneur de noeud a/usr/src dir avec le fichier client (voir ce qui a été copié dans Dockerfile.node) - vnode a le contenu de/usr/src de node
et /var/www/tg/static
de nginx.
En définitive, pour passer des données de/usr/src de votre conteneur
node
à/var/www/tg/static
dans un conteneurnginx
, vous devez faire quelque chose qui n’est pas très joli car Docker n’a pas encore développé une autre méthode: vous devez combiner nommé volume in dossier source avec bind volume in destination:nginx: build: context: . dockerfile: ./Dockerfile.nginx container_name: tg_nginx restart: always volumes: - ./server/nginx.conf:/etc/nginx/nginx.conf:ro - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static ports: - "80:80" - "443:443" depends_on: - node - gunicorn networks: - nw_web_tg
Il suffit de changer docker-composer - vnode:/var/www/tg/static
par - /var/lib/docker/volumes/vnode/_data:/var/www/tg/static