Нужно ли создавать новый докер-контейнер для запуска каждого рейка? - PullRequest
2 голосов
/ 26 сентября 2019

Допустим, у меня есть Dockerfile, который будет запускать приложение Ruby on Rails:

FROM ruby:2.5.1

# - apt-get update, install nodejs, yarn, bundler, etc...
# - run yarn install, bundle install, etc...
# - create working directory and copy files
# ....

CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]

Насколько я понимаю, контейнер является неизменяемым запущенным экземпляром изображения и набором параметров времени выполнения (например,сопоставления портов, сопоставления томов, сети и т. д.).

Так что, если я соберу и запущу контейнер из вышеуказанного файла, я получу что-то, что выполняет значение по умолчанию CMD выше (rails server)

docker build -t myapp_web:latest
docker create --name myapp_web -p 3000:3000 -v $PWD:/app -e RAILS_ENV='production' myapp_web:latest
docker start myapp_web

Отлично, так что теперьон запускает rails server в контейнере с CONTAINER_ID.

Но, скажем, завтра я хочу запустить rake db:migrate, потому что я что-то обновил.Как мне это сделать?

  1. Я не могу использовать docker exec, чтобы запустить его в этом контейнере, потому что db:migrate завершится ошибкой, пока rails server работает

  2. Если я остановлю rails server (и, следовательно, контейнер), мне нужно будет создать новый контейнер с теми же параметрами времени выполнения, но другой командой (rake db:migrate), которая создаст новый CONTAINER_ID.А затем, после запуска, я должен перезапустить свой оригинальный контейнер, который запускает rails server.

Неужели # 2 - это то, с чем мы должны жить?Каждое новое рейк-задание, которое я запускаю и требует закрытия rails server, должно будет создавать новый КОНТЕЙНЕР, который со временем накапливается.Есть ли более "правильный" способ запустить это?

Спасибо!

РЕДАКТИРОВАТЬ : Если путь №2 - это путь, есть ли простой способ создать новый контейнер из существующего контейнера, чтобы я мог скопироватьвсе конфиги времени выполнения и просто поменять команду?

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

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

Есть два трюка, которые могут помочь описанному вами сценарию.Прежде всего, когда вы docker run контейнер с --name, вы можете использовать это имя для всех последующих операций Docker;вам никогда не нужно знать шестнадцатеричный идентификатор контейнера.Во-вторых, когда вы запускаете однократную команду, вы можете добавить опцию --rm, чтобы контейнер удалял себя по завершении.

Таким образом, этот рабочий процесс может выглядеть следующим образом:

# Build the new image
docker build -t myapp_web:latest .

# Stop and delete the old server
docker stop myapp_web
docker rm myapp_web

# Run the migration task
docker run --rm myapp_web:latest rake db:migrate

# Restart the server
docker run -d --name myapp_web -p 3000:3000 myapp_web

Вы также можете посмотреть команду docker system prune для очистки неиспользуемых контейнеров и изображений.Во-вторых, я рекомендую Docker Compose инкапсулировать простые опции docker run, но вы также можете записывать последовательности команд, подобные этой, в сценарий оболочки вместо того, чтобы вводить их вручную несколько раз.

1 голос
/ 26 сентября 2019

Я настоятельно рекомендую использовать docker-compose.В моей базе кода я назову мой раздел docker-compose для rails 'web', а затем, когда я захочу запустить консоль rails, например, я сделаю:

docker-compose run web bundle exec rails console

И вы можете использовать точку входаскрипт для запуска консоли rails, таким образом, вы бы запустили сервер, запустив:

docker-compose up

в каталоге приложений.

Дополнительная информация о docker-compose здесь: https://docs.docker.com/compose/

Больше причин использовать compose, а не запускать образы докеров вручную: - Предоставляет синтаксис для установки таких параметров, как открытые порты для каждого изображения, вместо того, чтобы записывать это каждый раз. - Позволяет легко запускать несколько изображений одновременно, т.е.Контейнеры в моем файле для: rails, redis, postgres, sidekiq и т. д. Рано или поздно вам понадобится несколько изображений.- Легко указать локальные или удаленные изображения.Вы можете использовать up для сборки и запуска вашего стека.Легко получить новых разработчиков и запустить их.

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