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).
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 :)
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"
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.
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
.