Je déploie un projet avec NextJS, Django, Postgres, Nginx dans Docker Compose, cela fonctionne bien en local (ubunutu 18.04). Mais dans le serveur (ubuntu 20.04), cela génère une erreur Error: ENOTEMPTY: directory not empty, rmdir '/frontend/out/node_modules/cacache/node_modules/.bin'. Comment régler ceci. P.S. J'utilise wait-for.sh pour le frontend pour attendre que le service api soit prêt (sinon j'obtiens également une erreur de compilation) et ma version locale de docker est Docker version 19.03.12, build 48a66213fe, la version docker de mes serveurs est Docker version 19.03.11, build dd360c7 peut-être possible causes de l'erreur?

Mon Dockerfile pour le service frontend:

USER root
WORKDIR /frontend
COPY . /frontend

# Add wait-for-it
COPY wait-for.sh wait-for.sh
RUN chmod +x wait-for.sh

RUN yarn

Mon docker-compose.yml:


services:
  db:
    image: postgres:12.0-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=purple_postgres_user
      - POSTGRES_PASSWORD=purple_p@ssW0rd
      - POSTGRES_DB=purple_db
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    #    command: ./manage.py purple.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - ./backend/:/home/purple_user/purple/
      - static_volume:/home/purple_user/purple/static/
      - media_volume:/home/purple_user/purple/media/
    expose:
      - 8000
    ports:
      - 8000:8000
    env_file:
      - ./.env.dev
    depends_on:
      - db
  nginx:
    build: ./nginx
    ports:
      - 80:80
    volumes:
      - static_volume:/var/www/staticfiles/
      - media_volume:/var/www/mediafiles/
      - build_folder:/var/www/frontend/
    depends_on:
      - web
  frontend:
    container_name: frontend
    build:
      context: ./frontend
    volumes:
      - build_folder:/frontend/out
    depends_on:
      - web
    command: ./wait-for.sh web:8000 -- yarn build
volumes:
  postgres_data:
  static_volume:
  media_volume:
  build_folder:```
0
Alihaydar Gubatov 1 nov. 2020 à 06:03

2 réponses

Meilleure réponse

Pour moi, la solution était de supprimer le volume du service frontend, qui s'appelle build_folder. Pour obtenir le nom correct du dossier de construction, vous pouvez exécuter docker volume ls - pour moi, c'était purple_build_folder - et supprimer le dossier en exécutant la commande docker volume rm [volume name].

0
Alihaydar Gubatov 4 nov. 2020 à 22:26

Les volumes nommés dans Docker sont persistants. Lorsque votre fichier docker-compose.yml a

volumes:
  - build_folder:/frontend/out

Cela entraîne le stockage des résultats de la construction précédente dans build_folder, et ils sont toujours là la prochaine fois que ce conteneur s'exécute. C'est ce qui conduit au message d'erreur que vous voyez.

J'éviterais de configurer un service Compose juste pour créer des fichiers pour un autre service. Au lieu de cela, utilisez une build multi-étapes pour construire les artefacts à le temps de création de l'image. Au lieu de cela, dans votre fichier Dockerfile d'image Nginx, créez l'application frontale:

FROM node:12 AS frontend
WORKDIR /frontend
COPY frontend/package.json frontend/yarn.lock .
RUN yarn install
COPY frontend .
RUN yarn build

FROM nginx
# ... whatever this Dockerfile had before ...
# (except, change `COPY stuff /image/path` to `COPY nginx/stuff /image/path`)
COPY --from=frontend /frontend/out /var/www/frontend

Vous pouvez utiliser une technique similaire pour COPY les fichiers statiques --from votre web image; soit utilisez une étape de construction supplémentaire, COPY directement à partir du contexte de construction, ou COPY --from le nom de l'image construite séparée. (Ceci est un peu plus difficile à orchestrer car Compose n'ordonnera pas les constructions dépendantes.) Cela évite un problème similaire où le contenu de static_volume cache les fichiers statiques modifiés dans les deux images.

services:
  nginx:
    # The build context must be an ancestor of anything that
    # it needs to `COPY` in.  Since we `COPY` from both the `frontend`
    # and `nginx` directories, we need to specify
    build: .
    ports: ['80:80']
    depends_on: [web]
    # No `volumes:`; the image is self-contained
  # No build-only `frontend` container
1
David Maze 1 nov. 2020 à 17:43