У меня есть проект со следующей структурой.
ProjectName/
├── Dockerfile
├── api/
│ ├── Dockerfile
│ └── manage.py
├── docker-compose.yml
├── frontend/
│ ├── Dockerfile
│ ├── build/
│ └── src/
└── manifests/
├── development.yml
└── production.yml
docker-compose.yml имеет образ базы данных, общий для обеих сред, а dev.yml и prod.yml имеют похожие, но немного разные образы для производства и разработки.
Пример: api dev использует django и просто запускает python manage.py runserver
, но в продукте он будет запускать gunicorn api.wsgi
.
И интерфейс работает под управлением npm start
, но в продукте я хочу, чтобы он был основан на другом образе. В настоящее время файл dockerfile работает только с одним или другим, поскольку команда npm
обнаруживается только тогда, когда я использую FROM node
, а команда nginx
отображается только тогда, когда я использую FROM kyma/docker-nginx
.
Итак, как я могу разделить их в разных средах?
./frontend/Dockerfile:
FROM node
WORKDIR /app/frontend
COPY package.json /app/frontend
RUN npm install
EXPOSE 3000
CMD ["npm", "start"]
# Only run this bit in production environment, and not anything above this line.
#FROM kyma/docker-nginx
#COPY build/ /var/www
#CMD 'nginx'
./api/Dockerfile:
FROM python:3.5
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
postgresql-client \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app/api
COPY requirements.txt /app/api
RUN pip install -r requirements.txt
EXPOSE 8000
# Run this command in dev
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
# Run this command in prod
#CMD ["gunicorn", "api.wsgi", "-b 0.0.0.0:8000"]
./docker-compose.yml:
version: '3'
services:
db:
image: postgres
restart: always
ports:
- "5432:5432"
volumes:
node-modules:
./manifests/production.yml:
version: '3'
services:
gunicorn:
build: ./api
command: ["gunicorn", "api.wsgi", "-b", "0.0.0.0:8000"]
restart: always
volumes:
- ./api:/app/api
ports:
- "8000:8000"
depends_on:
- db
nginx:
build: ./frontend
command: ["nginx"]
restart: always
volumes:
- ./frontend:/app/frontend
- ./frontend:/var/www
- node-modules:/app/frontend/node_modules
ports:
- "80:80"
volumes:
node-modules:
./manifests/development.yml:
version: '3'
services:
django:
build: ./api
command: ["python", "manage.py", "runserver", "0.0.0.0:8000"]
restart: always
volumes:
- ./api:/app/api
ports:
- "8000:8000"
depends_on:
- db
frontend:
build: ./frontend
command: ["npm", "start"]
restart: always
volumes:
- ./frontend:/app/frontend
- node-modules:/app/frontend/node_modules
ports:
- "3000:3000"
volumes:
node-modules:
У вас может быть в качестве ENTRYPOINT сценарий, выполняющий ту или иную команду в зависимости от переменной среды, которую вы можете установить во время выполнения:
docker run -e env=DEV
# or
docker run -e env=PROD
Вы можете установить тот же переменная окружения в файле компоновки докеров.
@cclloyd ваш файл докеров вызовет один уникальный скрипт, который, в зависимости от значения переменной среды, вызовет правильную команду.
Но тогда как мне сделать так, чтобы контейнеры были основаны на разных базах? (Еще не слишком знаком с тем, как работают файлы докеров)
@cclloyd Вам нужно будет создать образ, способный делать и то, и другое, с установленными обоими фреймворками.
Хорошо, поэтому я добавляю среду: - DEV (или PROD) ко всем изображениям. Но как мне использовать его в моем Dockerfile? У меня всего 2 раздела, с
ENTRYPOINT "DEV"
вверху?