Это учебный проект, в рамках которого я:
- настроил запуск проекта Kittygram в контейнерах;
- настроил автоматическое тестирование и деплой этого проекта на удалённый сервер.
В этом файле я поделюсь своим опытом, описывая, что я делал, какие проблемы возникали и что я узнал в результате работы над проектом.
Kittygram - это приложение для обмена фотографиями котиков. Оно позволяет пользователям загружать, просматривать фотографии котиков.
В рамках этого проекта я был ответственен за следующие задачи:
Настройка автоматизации с помощью сервиса GitHub Actions.
При пуше в ветку main:
- проект должен тестироваться,
- в случае успешного прохождения тестов образы должны обновляться на Docker Hub,
- на сервере должны быть запущены контейнеры из обновлённых образов.
В ходе уроков спринта мы должны были разместить проект Taski в контейнерах на своём удалённом сервере. На этом же сервере должен быть размещён и Kittygram.
Сервер Nginx, уже развёрнутый на сервере, должен переадресовывать запросы по назначению — в Taski или в Kittygram.
Какие образы и контейнеры мне понадобились:
Имя образа Название контейнера в docker-compose.yml
---------------------------------------------------------------------------------------
kittygram_gateway gateway
---------------------------------------------------------------------------------------
kittygram_backend backend
---------------------------------------------------------------------------------------
kittygram_frontend frontend
---------------------------------------------------------------------------------------
postgres:13 db
---------------------------------------------------------------------------------------
Подключил Docker volumes:
- static — для хранения файлов статики контейнеров
backend
иfrontend
. Доступ к этому volume должен быть и у контейнераgateway
, чтобы Nginx мог раздавать эти файлы. - media — для хранения файлов, загружаемых пользователями. Доступ к этому volume должен быть и у контейнера
backend
, и у контейнераgateway
, чтобы Nginx мог раздавать эти файлы. - pg_data — для хранения данных PostgreSQL из контейнера
db
.
- Написал Dockerfile для образа
kittygram_backend
. За основу взял Dockerfile для бэкенда Taski. - Для создания образа
kittygram_gateway
использовал готовый Dockerfile из папки nginx/.- Обновил конфигурацию Nginx и добавил проксирование запросов для API и админки.
- Для создания контейнера фронтенда использовал готовый Dockerfile из папки frontend/.
- Настроил совместную работу контейнеров
backend
иdb
:- Настроил Django для работы с PostgreSQL.
- Создал файл .env для PostgreSQL и контейнера
backend
: вписал в него переменные для инициализации БД и связи с ней.
- Дописал docker-compose.yml, заготовленный в репозитории. В нём уже есть описание контейнеров, но его нужно было расширить:
- добавить volume для статических файлов админки и фронтенда,
- добавить volume для хранения файлов, загруженных пользователями,
- подключить файл .env к контейнерам
db
иbackend
.
Автоматизировал тестирование и деплой проекта Kittygram с помощью GitHub Actions.
Написал в файле .github/workflows/main.yml workflow, который будет:
- проверять код бэкенда в репозитории на соответствие PEP8;
- запускать тесты для фронтенда и бэкенда (тесты уже написаны);
- собирать образы проекта и отправлять их на Docker Hub:
sanfootball/kittygram_backend
,sanfootball/kittygram_frontend
,sanfootball/kittygram_gateway
.
- обновлять образы на сервере и перезапускать приложение при помощи Docker Compose;
- выполнять команды для сборки статики в приложении бэкенда, переносить статику в volume; выполнять миграции;
- извещать в Telegram об успешном завершении деплоя.
Подготовил удалённый сервер к публикации проекта Kittygram:
- Очистил диск сервера от лишних данных:
- удалил кеш npm: npm
cache clean --force
; - удалиk кеш APT:
sudo apt-get clean
; - удалиk старые системные логи:
sudo journalctl --vacuum-time=1d
выполнил командуsudo docker system prune -af
: она уберает все лишние объекты, которые мы могли создать в докере за время выполнения заданий спринта, — неиспользуемые контейнеры, образы и сети.
- удалил кеш npm: npm
- Удалил Gunicorn-сервис Kittygram.
- Создал директорию kittygram/ в домашней директории сервера.
- Поменял содержимое файла конфигурации Nginx для Kittygram так, что все запросы пойдут в Docker, на порт 9000.
- После подготовки — развернул Kittygram на сервере автоматически, с помощью GitHub Actions.
- Проект Taski доступен по доменному имени:
mytaskiproject.ddns.net
. - Проект Kittygram доступен по доменному имени:
mykittyproject.ddns.net
. - Пуш в ветку main запускает тестирование и деплой Kittygram, а после успешного деплоя приходит сообщение в Телеграм.
- В корне проекта есть файл kittygram_workflow.yml.
├── .env.example
├── .github
│ └── workflows
│ └── main.yml # Файл с воркфлоу, который вы добавите
├── .gitignore
├── README.md
├── backend
│ ├── .dockerignore
│ ├── Dockerfile # Докерфайл для бэкенда
│ ├── README.md
│ ├── cats
│ ├── kittygram_backend
│ ├── manage.py
│ └── requirements.txt
├── docker-compose.production.yml
├── docker-compose.yml
├── frontend
│ ├── .dockerignore
│ ├── .gitignore
│ ├── Dockerfile
│ ├── README.md
│ ├── package-lock.json
│ ├── package.json
│ ├── public
│ └── src
├── nginx
│ ├── Dockerfile
│ └── nginx.conf
└── tests.yml # Файл с данными для проверки
В процессе работы над проектом возникли следующие трудности:
при абсолютно корректно выполненном задании картинки на удалённом сервере не работали. Проблема коварная, т.к. при разворачивании контейнеров на локальной машине всё работает, а вот удалённо нет. Студент нашей когорты предоставил нам инструкцию по устранению этой проблемы: Прежде всего нужно убедиться, что контейнеры действительно корректно настроены, гуникорн сохраняет картинки в нужный том, а nginx их оттуда раздаёт:
- Загрузите кота с картинкой на удалённый сервер и перейдите на главную.
- Через Dev Tools (F12) браузера выделите тег со сломанной картинкой, увидите плохой путь, начинающийся со
http://127.0.0.1:9000/media/...
, с таким путем браузер, конечно же, показать картинку не сможет. Скопируйте путь. На иллюстрации Firefox, в других браузерах аналогично. - В адресной строке скомбинируйте этот путь со своим доменом, заменив локальный адрес на ваш домен, чтобы вышло примерно так:
https://<ДОМЕН>/media/cats/images/temp.jpeg
. Убедитесь, что картинка открывается.
Если же картинка по сети доступна, значит, гуникорн на сервере успешно получил запрос, джанго сохранил картинку в нужный том, nginx её нашел и смог раздать. Проблема с отображением идёт из кода бекенда: в нём в прошлом спринте создавалось доп. поле image_url
в JSON'е, но яндексовский пулл-реквест, добавивший это поле в infra_sprint1, забыли замержить ещё и в kittygram_final. Можете сравнить serializers.py из прошлого и этого спринтов и увидеть, что нужное нам поле с относительным путем картинки пропало. На второй иллюстрации видно, что поле image
содержит плохой путь, а image_url
- хороший. Локально по плохому пути можно достать картинку, а вот удаленно невозможно.
Чтобы картинки отобразились, фронт тоже должен вытаскивать из JSON'а от сервера нужное поле. Дмитрий нашёл три React-компонента, где оно должно использоваться: main-page.jsx (infra_sprint1, kittygram_final), card-page.jsx (infra_sprint1, kittygram_final), edit-card-page.jsx (infra_sprint1, kittygram_final) - главная, страница кота и страница редактирования кота. В первых двух в прошлом спринте использовалось поле image_url
, поэтому картинки были видны, а вот в третьем, если кто помнит, была бага, картинки при редактировании не показывались, и мы его правили, меняя image
на image_url
. А в этом спринте во всех трёх местах стоит image
, и поэтому ничего не работает.
Как это исправить: Дмитрий сделал патч для гита, который можно применить в любой момент после клонирования kittygram_final, и он поправит сериалайзер в беке и три компонента на фронте. Чтобы его применить, скачайте патч images.patch
из этого поста, запомните путь до него (например, C:\Users\User\Downloads), и, находясь в корневой папке проекта, выполните команду git apply <путь до патча>
(в случае гитбаша это будет git apply /c/Users/User/Downloads/images.patch
). Если не будет никаких ошибок, то можете коммитить и пушить на свой сервер, когда всё задеплоится, картинки появятся.
Работа над проектом "Kittygram" позволила мне узнать следующее:
- как настроить запуск проекта в контейнерах;
- как настроить автоматическое тестирование и деплой этого проекта на удалённый сервер.
Технические навыки: Проект позволил мне углубить свои знания и навыки в области настройки автоматизации с помощью сервиса GitHub Actions. Я приобрел опыт работы по настройке и запуску проекта в контейнерах и CI/CD с помощью GitHub Actions.
Настроить запуск проекта Kittygram в контейнерах и CI/CD с помощью GitHub Actions
В корне репозитория создайте файл tests.yml со следующим содержимым:
repo_owner: ваш_логин_на_гитхабе
kittygram_domain: полная ссылка (https://доменное_имя) на ваш проект Kittygram
taski_domain: полная ссылка (https://доменное_имя) на ваш проект Taski
dockerhub_username: ваш_логин_на_докерхабе
Скопируйте содержимое файла .github/workflows/main.yml
в файл kittygram_workflow.yml
в корневой директории проекта.
Для локального запуска тестов создайте виртуальное окружение, установите в него зависимости из backend/requirements.txt и запустите в корневой директории проекта pytest
.
- Проект Taski доступен по доменному имени, указанному в
tests.yml
. - Проект Kittygram доступен по доменному имени, указанному в
tests.yml
. - Пуш в ветку main запускает тестирование и деплой Kittygram, а после успешного деплоя вам приходит сообщение в телеграм.
- В корне проекта есть файл
kittygram_workflow.yml
.
Трубников Александр
email: petrovskii1980@mail.ru
Telegram: https://t.me/sanfootball