Docker: перенос проектов

Свершилось! Обновил дистрибутив и один проект отвалился. В связи с этим решил перенести проекты в docker.

НАСТРОЙКА DOCKER

После установки надо править файл /etc/docker/daemon.json. У меня zfs примонтирован в директории /data.

{
  "graph": "/data/docker",
  "hosts": ["unix:///data/docker/docker.sock"],
  "storage-driver": "zfs"
}

Далее надо проверить конфиги в /etc/sysconfig и стартовые скрипты в /lib/systemd/system. Если в них есть настройки graph, hosts и storage-driver, то их надо закоментировать. Далее стартуем сервис и в директории /data должна появиться директория docker аналогичная той, что находится в /var/lib/docker. В этой директории будут храниться образы и контейнеры.

НАСТРОЙКА ОБРАЗА

Задача следующая. Поскольку переношу PKI и он требует для работы клиент ssh и openssl, то решил развернуть в контейнере образ CentOS 7 и уже на нем развернуть Python и все остальное. Для этого надо скачать образ CentOS и запустить его в контейнере:

docker pull centos7

Поскольку в контейнерах ничего не сохраняется, то надо примонтировать директорию из файловой системы, где расположен код PKI в контейнер. Так же не будем делать никаких пробросов портов поскольку у контейнера будет свой IP-адрес, который позволит хост системе взаимодействовать с контейнером т.е. это просто вопрос настройки веб-сервера.
Выполняем docker images, копируем IMAGE ID и создаем контейнер:

REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
docker.io/centos     centos7             8652b9f0cb4c        5 months ago        204 MB

docker run -it --name mypki -v /data/mypki:/data/mypki 8652b9f0cb4c

Опцией name задаем имя образа. С помощью ключа -v указываем какую директорию из файловой системы монтировать в файловую систему контейнера и далее уже указываем IMAGE ID на основе которого и создается контейнер. Ключи -it говорят о том, что мы желаем подключиться к контейнеру по терминалу сразу после запуска. Тут надо понимать что команда docker run используется только для создания контейнера. Если дофига раз запустите эту команду, то создадите дофига контейнеров. Потому после того как контейнер уже настроен и запущен, то необходимо управлять командами stop/start/exec. Итак, обновляем ОС, ставим весь необходимый для работы спектр ПО, делаем пробный запуск нашей программы и убеждаемся, что все работает. Мне пришлось немного обновить код в связи с новыми реалиями запуска. Теперь, чтобы отключиться от контейнера нажимаем следующие клавиши:

ctrl+p
ctrl+q

Поскольку, если просто наберете exit или ctrl+d, то контейнер завершит свою работу. Вообще если основная программа, которую запускаете в контейнере завершается, то контейнер тоже тухнет. Так же не доступна система инициализации приложений (например systemd), потому придется запускать приложения вручную.

Убедится в том, что контейнер запущен можно командой docker ps:

CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
a3c8b2940759        e83d6e92ff3d        "/bin/bash"         3 days ago          Up 3 days                               mypki

Теперь сохраняем все изменения в новый образ. Для этого указываем CONTAINER ID и задаем имя образу:

docker commit a3c8b2940759 mypki-image

Удаляем контейнер и создаем новый с новым образом:

docker rm a3c8b2940759
docker run -it --name mypki -v /data/mypki:/data/mypki <IMAGE ID>

Еще надо сделать так, чтобы после ребута сервера контейнер сам запускался:

docker update --restart unless-stopped <CONTAINER ID>

Финальная проверка:

nc -vz 172.17.0.2 5000
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 172.17.0.2:5000.
Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds.

Вот теперь точно все.

НЕКОТОРЫЕ ПОЛЕЗНОСТИ

Подключиться к запущенному контейнеру можно командой:

docker attach <CONTAINER ID>

Отключаемся соответственно следующими комбинациями:

ctrl+p
ctrl+q

Запустить что-либо в уже запущенном контейнере можно командой exec:

docker exec <CONTAINER ID> nohup /usr/bin/python3 /data/mypki/main.py &

Удалить контейнер:

docker rm <CONTAINER ID>

Удалить образ:

docker rmi <IMAGE ID>

Конечно я поставил автозапуск контейнера, но поскольку контейнер по-умолчанию запускает /bin/bash (что видно в выводе docker ps), то думаю контейнер остановится сразу после запуска. Потому сделал следующий автозапуск:

chmod a+x /etc/rc.local

cat /root/bin/docker.sh
#!/bin/bash

MYPKI="a3c8b2940759"

docker exec $MYPKI nohup /usr/bin/python3 /data/mypki/main.py &
docker exec $MYPKI nohup /usr/bin/python3 /data/mypki/mypki-km.py &

chmod +x /root/bin/docker.sh
echo "/root/bin/docker.sh" >> /etc/rc.local

Скрипт не проверял, но должно работать.