Часть 2. Продвинутая работа с Docker
Настройка базы данных
docker run --rm -d \
-v mysql:/var/lib/mysql \
-v mysql_config:/etc/mysql \
--name mysql \
-e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=blog \
--net cluster \
mysql
Подключимся к рабочей базе и создадим таблицу
docker exec -it mysql mysql -p
# Вводим пароль из переменной MYSQL_ROOT_PASSWORD, который мы сами задали
Создадим табличку posts в базе blog
CREATE TABLE blog.posts (
id INT NOT NULL AUTO_INCREMENT,
title varchar(255),
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
Выйдем из контейнера с помощью ctrl + D
Запускаем Adminer
Запустим Adminer в той же сети
docker run -d -p 8080:8080 --net cluster --name adminer adminer
Подключимся к http://127.0.0.1:8080/ (или IP вашей ВМ, если у вас бридж-сеть).
В открывшемся интерфейсе подключимся к базе, указав:
| Поле | Значение | Примечание |
|---|---|---|
| Сервер | mysql | имя контейнера с СУБД |
| Имя пользователя | root | |
| Пароль | password | |
| База данных | blog |
Если все прошло успешно, вы увидете нашу таблицу posts.
Перейдем в нее и добавим несколько записей с помощью "Новая запись".
Можно указывать только поле title, т.к. остальные поля генерятся автоматически при создании объекта.
При желании можно создасть записи и с помощью SQL через контейнер с mysql или через SQL-запрос в Adminer:
INSERT INTO blog.posts (title)
VALUES ("First Post"), ("Second Post"), ("Third Post");
Запускаем свой сервис
Загрузим себе материалы лабораторной:
git clone https://gitlab.com/tlakatlekutl/devops-lab2 && cd devops-lab2
В каталоге code/ находится пример примитивного API сервиса на Golang. Для того чтобы начать с ним работать, необходимо собрать образ. Для этого воспользуемся следующей командой:
docker build -t step1 -f step1.Dockerfile code/
где:
- опция
-tзадает имя образа, иначе имя будет равно ID образа - опция
-fуказывает путь к Dockerfile, если ее не указывать докет будет искать файл Dockerfile в текущем каталоге code/- это конекст для сборки образа, все файлы, которые долны быть доступны во время сборки.
Запустим наш сервис (собранный ранее образ step1), передадим ему параметры подключения к базе через переменные окружения (с помощью опции -e), а также подключим его к контейнеру mysql.
docker run --net cluster -p 8000:8000 -e MYSQL_DB=blog -e MYSQL_HOST=mysql -e MYSQL_USER=root -e MYSQL_PASS=password step1
Проверим работу нашего приложения выполнив команду curl, в ответе должны увидеть json массив с созданными постами.
curl localhost:8000/posts
Подробнее про сборку образа
Рассмотрим структуру Dockerfile на примере step1.Dockerfile.
В начале любого образа должен быть указан базовый образ, на основе которого собирается новый. В нашем случае FROM golang:1.19.1, самый базовый возможно образ FROM scratch, в нем нет ничего.
COPY копирует файл из контекста (папочки, которою вы указываете при docker build) в указанное место в образе. Команда создает новый слой в образе;
RUN команда - запускает команду в образе, создает новый слой;
Остальные операнды либо создают пустой слой, либо напрямую меняют метаинформацию в образе.
EXPOSE показывает докеру, какие порты слушает приложение;
CMD Задает команду запуска в контейнере;
WORKDIR меняет рабочую директорию;
USER меняет пользователя, под которым идет раб ота;
ENV задает переменные окружения;
и т.д. Подробнее можно ознакомиться в официальной документации.
Взглянем на получившиеся слои у образа:
docker history step1
Как было показано на лекции, каждый получившийся слой - это архив с измененными файлами.
Оптимизируем сборку
Для удобства вынесем переменные окружения в отдельный файл, например config.env:
MYSQL_DB=blog
MYSQL_HOST=mysql
MYSQL_USER=root
MYSQL_PASS=password
Соберем образ step2:
docker build -t step2 -f step2.Dockerfile code/
Запустим образ step2 и проверим, что он работает, аналогично предыдущему:
docker run --link mysql -p 8000:8000 --env-file=config.env step2
Задание: Сравните образы step1 и step2 (их Dockerfile и history) и опишите различия.