web-dev-qa-db-fra.com

docker-compose: utilisation de plusieurs Dockerfiles pour plusieurs services

J'utilise docker-compose et j'aimerais utiliser différents Dockerfiles pour différentes étapes de construction de services. Les docs semblent suggérer de placer différents Dockerfiles dans différents répertoires, mais je voudrais qu'ils soient tous dans le même (et peut-être distingués en utilisant la convention suivante: Dockerfile.postgres, Dockerfile.main. ..). Est-ce possible?

Edit: Le scénario que j'ai contient ce fichier docker-compose:

main:
  build: .
  volumes:
    - .:/code
  environment:
    - DEBUG=true

postgresdb:
  extends:
    file: docker-compose.yml
    service: main
  build: utils/sql/
  ports:
    - "5432"
  environment:
    - DEBUG=true

où le Dockerfile de postgresdb est:

FROM postgres

# http://www.slideshare.net/tarkasteve/developerweek-2015-docker-tutorial
ADD make-db.sh /docker-entrypoint-initdb.d/

et le principal est:

FROM python:2.7

RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/

RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ADD . /code/

Cela fonctionne en ce moment, mais je voudrais étendre le Dockerfile de postgresdb en appelant un script Python qui crée des tables dans la base de données selon des modèles construits sur SQL Alchemy (le script Python serait être appelé comme python manage.py create_tables). Je voulais l'ajouter au Dockerfile de la base de données, mais en raison de l'isolement des conteneurs, je ne peux pas y utiliser SQL Alchemy parce que cette image est basée sur l'image postgres au lieu de Python, et qu'elle ne contient pas le package sqlalchemy ...

Que puis-je faire? J'ai essayé d'utiliser le service main dans postgresdb, mais malheureusement il ne transporte pas python et ses packages, donc je ne peux toujours pas écrire un seul Dockerfile qui crée le Base de données Postgres (via le script Shell) ainsi que ses tables (via un script Python).

14
aralar

Cela n'est pas possible en raison de la façon dont Docker gère les contextes de génération.

Vous devrez utiliser et placer un Dockerfile dans chaque répertoire qui fera partie du contexte de construction Docker pour le service that.

Voir: Dockerfile

Vous aurez en fait besoin d'un docker-compose.yml qui ressemble à:

service1:
    build: service1

service2:
    build: service2

Voir: docker-compose

Mise à jour:

Pour répondre à votre cas d'utilisation particulier - Bien que je comprenne ce que vous essayez de faire et pourquoi je ne le ferais pas personnellement moi-même. L'isolement est un bonne chose et aide à gérer les attentes et la complexité. Je voudrais effectuer la "création de base de données" comme un autre conteneur basé sur le code source de votre application ou dans le conteneur d'application lui-même.

Alternativement, vous pouvez regarder des solutions plus scriptées et basées sur des modèles telles que shutit ( Je n'ai aucune expérience mais j'ai entendu parler de Dieu).

FWIW: Séparation des préoccupations ftw :)

12
James Mills

Vous devez l'ajouter dans la section build. Ainsi, vous pouvez spécifier différents fichiers docker alternatifs pour chaque service.

services:
  service1:
    build:
        context: .
        args:
            - NODE_ENV=local
        dockerfile: Dockerfile_X
    ports:
        - "8765:8765"
8
mulg0r

Créateur de ShutIt ici. Heureux d'entendre que les gens entendent de bonnes choses à ce sujet.

Pour être honnête, à votre place, j'écrirais votre propre Dockerfile et utiliserais la gestion de paquets standard comme apt ou yum. Une vérification rapide avec une image ubuntu et python-pip et python-sqlalchemy sont disponibles gratuitement.

Il existe des solutions plus compliquées qui peuvent fonctionner pour vous en utilisant ShutIt, heureux d'en discuter hors ligne, car je pense que c'est un peu hors sujet. ShutIt a été écrit pour ce type de cas d'utilisation, car je pouvais voir que ce serait un problème courant étant donné l'utilité limitée de Dockerfiles en dehors de l'espace des microservices.

2
ianmiell

Vous pouvez utiliser l'argument dockerfile dans votre docker-compose.yml pour spécifier un autre pour un service spécifique.

Je ne sais pas quand il a été ajouté, car la discussion est ancienne, mais vous pouvez le voir dans la référence https://docs.docker.com/compose/compose-file/#dockerfile

Je l'ai essayé hier et ça marche avec moi. C'est le répertoire de base de mon projet, j'ai Dockerfile et Dockerfile-service3 et dans le docker-compose.yml:

version: '2'

services:
    service1:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8765:8765"
        # other args skipped for clarity
    service2:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8766:8766"
        # other args skipped for clarity
    service3:
        build:
            context: .
            dockerfile: Dockerfile-service3
            args:
                - NODE_ENV=local
        ports:
            - "8767:8767"
        # other args skipped for clarity
    service4:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8768:8768"
        # other args skipped for clarity

De cette façon, tous les services, sauf service3 sera construit en utilisant les standards Dockerfile et service3 sera construit en utilisant le Dockerfile-service3.

2
mandarin