Как развернуть приложение docker в рабочей среде без использования Docker compose?

#docker #docker-compose #containers

#docker #docker-compose #контейнеры

Вопрос:

Я слышал, что он сказал, что

Docker compose предназначен для разработки, а НЕ для производства.

Но я видел, как люди использовали Docker compose в рабочей среде с привязкой монтирования. Затем извлеките последние изменения из github, и оно появится в рабочей среде без необходимости перестраивать. Но другие говорят, что вам нужно COPY . . для производства и перестройки.

  1. Но как это работает? Потому что в docker-compose.yaml вы можете указать depends-on , который не запускает один контейнер, пока не будет запущен другой. Если я не использую docker-compose его в рабочей среде, то как насчет этого? Как бы я перенес свой docker-compose в рабочую среду (у меня есть 4 службы / 4 образа, которые мне нужно запустить). С docker-compose up -d этим так просто.

  2. Как мне создавать каждое изображение по отдельности?

  3. Как я могу скопировать эти изображения на свой рабочий сервер, чтобы запустить их (в правильном порядке)? Я даже не могу нигде найти образы сборки на своем компьютере.

Это мой docker-compose.yaml-файл, который отлично подходит для разработки

 version: '3'
services:

  # Nginx client server
  nginx-client:
    container_name: nginx-client
    build:
        context: .                  
    restart: always
    stdin_open: true  
    environment:
      - CHOKIDAR_USEPOLLING=true  
    ports:
      - 28874:3000
    volumes:
      - ./client:/var/www
      - /var/www/node_modules
    networks:
      - app-network


  # MySQL server for the server side app
  mysql-server:
    image: mysql:5.7.22
    container_name: mysql-server
    restart: always
    tty: true
    ports:
      - "16427:3306"
    environment:
      MYSQL_USER: root
      MYSQL_ROOT_PASSWORD: BcGH2Gj41J5VF1
      MYSQL_DATABASE: todo
    volumes:
      - ./docker/mysql-server/my.cnf:/etc/mysql/my.cnf
    networks:
      - app-network


  # Nginx server for the server side app
  nginx-server:
    container_name: nginx-server
    image: nginx:1.17-alpine
    restart: always
    ports:
      - 49691:80
    volumes:
      - ./server:/var/www
      - ./docker/nginx-server/etc/nginx/conf.d:/etc/nginx/conf.d
    depends_on:
    - php-server
    - mysql-server
    networks:
      - app-network


  # PHP server for the server side app
  php-server:
    build:
      context: .        
      dockerfile: ./docker/php-server/Dockerfile
    container_name: php-server
    restart: always
    tty: true
    environment:
      SERVICE_NAME: php
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./server:/var/www
      - ./docker/php-server/local.ini:/usr/local/etc/php/conf.d/local.ini
      - /var/www/vendor
    networks:
      - app-network
    depends_on:
      - mysql-server


# Networks
networks:
  app-network:
    driver: bridge
  

Ответ №1:

Как вы создаете образы docker? Я предполагаю, что вы не планируете использовать реестр, поэтому вам придется:

  • дайте имя образа всем службам
  • создайте образы docker где-нибудь (на сервере CI / CD, локально, это не имеет большого значения)
  • сохраните изображения в файле
  • заархивируйте файл
  • экспортируйте архивированный файл удаленно
  • на сервере разархивируйте и загрузите

Я бы создал для этого скрипт. Что-то вроде этого:

 #!/bin/bash
set -e

docker-compose build

docker save -o images.tar "$( grep  "image: .*" docker-compose.yml | awk '{ print $2 }' )"
gzip images.tar

scp images.tar.gz myserver:~

ssh myserver ./load_images.sh
-----

on myserver, the load_images.sh would look like this:

```bash
#!/bin/bash

if [ ! -f images.tar.gz ] ; then
    echo "no file"
    exit 1
fi

gunzip images.tar.gz
docker load -i images.tar
  

Затем вам нужно будет создать команды docker для эмуляции конфигурации docker-compose (я не буду туда заходить, поскольку в этом нет ничего сложного, но это скучно, и мне не хочется это писать). Как вы моделируете depends_on ? Что ж, вам придется запускать каждый контейнер отдельно, поэтому вы либо подготовите другой сценарий, либо сделаете это вручную.


Об использовании docker-compose в рабочей среде:

На самом деле нет большой проблемы с использованием docker-compose в рабочей среде, как только вы сделаете это правильно. например, некоторые из моих производственных настроек имеют тенденцию выглядеть так:

  • docker-compose.yml
  • docker-compose.dev.yml
  • docker-compose.prd.yml

Разработчики будут использовать docker-compose -f docker-compose.yml -f docker-compose.dev.yml $cmd его во время работы, которую вы будете использовать docker-compose -f docker-compose.yml -f docker-compose.prd.yml $cmd .

Взяв ваш файл в качестве примера, я бы переместил все volumes подразделы , ports , tty и stdin_open из docker-compose.yml в docker-compose.dev.yml. например, docker-compose.dev.yml будет выглядеть так:

 version: '3'
services:
  nginx-client:
    stdin_open: true
    ports:
      - 28874:3000
    volumes:
      - ./client:/var/www
      - /var/www/node_modules

  mysql-server:
    tty: true
    ports:
      - "16427:3306"
    volumes:
      - ./docker/mysql-server/my.cnf:/etc/mysql/my.cnf

  nginx-server:
    ports:
      - 49691:80
    volumes:
      - ./server:/var/www
      - ./docker/nginx-server/etc/nginx/conf.d:/etc/nginx/conf.d

  php-server:
    restart: always
    tty: true
    volumes:
      - ./server:/var/www
      - ./docker/php-server/local.ini:/usr/local/etc/php/conf.d/local.ini
      - /var/www/vendor
  

в рабочей среде docker-compose у вас будут строго необходимые port подразделы, определите файл рабочей среды, в котором хранятся требуемые пароли (файл будет находиться только на рабочем сервере, а не в git) И т. Д. И т. Д.

На самом деле, у вас есть так много разных подходов, которые вы можете использовать.

Ответ №2:

Как правило, docker-compose используется в качестве инструмента для компоновки контейнеров при разработке. В большинстве популярных хостинговых сервисов, таких как GCP и AWS, доступно несколько других инструментов для компоновки контейнеров производственного уровня. Kubernetes на сегодняшний день является самым популярным и наиболее часто используемым.

Исходя из служб, используемых в вашем docker-compose, рекомендуется не использовать его непосредственно в рабочей среде. Запуск контейнера mysql может привести к проблемам с потерей данных, поскольку контейнеры предназначены для временного использования. Вместо этого лучше выбрать управляемую службу MySQL, такую как RDS. Аналогично, nginx также лучше настроить с любыми службами обратного прокси / балансировки нагрузки, которые предоставляет ваша служба хостинга.

Когда дело доходит до создания образов, вы можете использовать конвейер CI / CD для создания этих образов из соответствующих файлов Dockerfile, а затем нажать на реестр образов по вашему выбору, и пусть ваша служба хостинга забирает образ и развертывает его с помощью инструмента управления контейнерами, который предоставляет ваша служба хостинга.

Ответ №3:

Если вам нужна облегченная производственная среда, использование Compose, вероятно, подойдет. Другие ответы здесь намекают на более сложные инструменты, которые имеют такие преимущества, как поддержка кластеров с несколькими хостами и развертывания с нулевым временем простоя, но они гораздо более сложны.

В вашем описании отсутствует одна основная часть — реестр изображений. Docker Hub подходит для этой роли, если вы хотите его использовать; у крупных облачных провайдеров есть один; даже на GitHub теперь есть реестр контейнеров (для общедоступных репозиториев); или вы можете запустить свой собственный. Это решает пару ваших проблем: (2) вы docker build размещаете изображения локально (или в выделенной системе непрерывной интеграции) и docker push помещаете их в реестр, затем (3) размещаете docker pull изображения в рабочей системе или позволяете Docker делать это самостоятельно.

Хорошая практика, которая сопровождается этим, — присвоить каждой сборке уникальный тег, возможно, метку даты или идентификатор фиксации. Это упрощает обновление (или понижение) путем изменения тега и повторного запуска docker-compose up .

Для этого вы бы изменили свой docker-compose.yml лайк:

 services:
  nginx-client:
    # No `build:`
    image: registry.example.com/nginx:${NGINX_TAG:latest}
  php-server:
    # No `build:`
    image: registry.example.com/php:${PHP_TAG:latest}
  

И затем вы можете обновить такие вещи, как:

 docker build -t registry.example.com/nginx:20201101 ./nginx
docker build -t registry.example.com/php:20201101 ./php
docker push registry.example.com/nginx:20201101 registry.example.com/php:20201101

ssh production-system.example.com 
  NGINX_TAG=20201101 PHP_TAG=20201101 docker-compose up -d
  

Вы можете использовать несколько docker-compose.yml файлов для использования docker-compose build и docker-compose push для своих пользовательских изображений, используя файл наложения только для разработки. В документации Docker есть пример.

Не копируйте свой код отдельно; он содержится в образе. Не привязывайте локальный код поверх кода образа. Особенно не используйте анонимный том для хранения библиотек, поскольку это полностью игнорирует любые обновления в базовом образе. Это тоже хорошая практика в разработке, поскольку, если вы заменяете все интересное в образе монтированием тома, это не имеет никакого отношения к тому, что вы используете в рабочей среде.

Вам нужно будет отдельно скопировать файлы конфигурации, на которые вы ссылаетесь, и docker-compose.yml само приложение в целевую систему и взять на себя ответственность за резервное копирование данных базы данных.

Наконец, я бы рекомендовал удалить ненужные параметры из docker-compose.yml файла (не указывайте вручную container_name: , используйте default сеть, предоставляемую Compose, предпочитайте указывать command: в изображении и так далее). Это не обязательно, но может помочь уменьшить размер файла YAML.