5. Прототип анализ #53
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "5. Прототип анализ" | |
on: | |
push: | |
branches: | |
- main | |
jobs: | |
check_tag_08_docker_compose: | |
name: "Проверка наличия тега 0.8 и работоспособности docker-compose" | |
runs-on: ubuntu-20.04 | |
steps: | |
- uses: actions/checkout@v4 | |
name: Check out current commit | |
with: | |
fetch-depth: 0 | |
- name: There are at least one Dockerfile | |
run: | | |
if ! find ./ | grep -q 'Dockerfile$' | |
then | |
echo "::error:: Не найдены файлы с названием Dockerfile." | |
exit 1 | |
fi | |
- name: Lint Dockerfile | |
uses: hadolint/[email protected] | |
with: | |
dockerfile: Dockerfile | |
recursive: true | |
failure-threshold: error | |
override-error: DL3006, DL3000, DL3007, DL3008, DL3009, DL3013, DL3016, DL3018, DL3020, DL3028, DL3037, DL3047, DL4001, DL4003, DL4004 | |
- name: Check docker-compose.yml | |
run: | | |
set -e | |
dc_file=${1:-"./docker-compose.yml"} | |
services_count=`yq '.services | length' ${dc_file}` | |
if [[ "${services_count}" < "2" ]]; | |
then | |
echo "::error:: Ошибка - слишком мало сервисов в конфигурации. У вас должно быть минимум два сервиса - приложение и СУБД." | |
exit 1 | |
fi | |
db_service=`yq '.services.db' ${dc_file}` | |
if [[ "${db_service}" == "null" ]]; | |
then | |
echo "::error:: Ошибка - нет явно заданного сервиса для СУБД (с названием db)" | |
exit 1 | |
fi | |
if [[ "`yq '.services.db.ports' ${dc_file}`" != "null" ]]; | |
then | |
echo "::error:: Ошибка - в сервисе db открыты сетевые порты через ports. Для работы приложения они не нужны, если вам требуется доступ для СУБД в отладочных целях, то можно или поднять веб-интерфейс (и ему открыть порты), или получать доступ по внутренней сети докера. " | |
exit 1 | |
fi | |
if [[ "`yq '.services.db.volumes' ${dc_file}`" == "null" ]]; | |
then | |
echo "::error:: Ошибка - в сервисе db не организованы volumes. По заданию они требуются для того, чтобы сохранять данные БД между запусками вашей конфигурации" | |
exit 1 | |
fi | |
if yq '.services.db.volumes' ${dc_file} | grep -q '^[^/a-zA-Z]*/' | |
then | |
echo "::error:: Ошибка - в сервисе db volumes использует монтирование каталогов. Используйте вместо этого именно volumes ( https://docs.docker.com/storage/volumes/#use-a-volume-with-docker-compose) - это гораздо удобнее и позволяет управлять таким хранилищем через докер." | |
exit 1 | |
fi | |
if yq '.network' ${dc_file} | grep -q 'host' ; | |
then | |
echo "::error:: Ошибка - сеть типа host. Пожалуйста, не используйте данный тип сети: он максимально небезопасен (так как неглядя мапит все порты вашей конфигурации на адаптер хоста) и неудобен. Укажите вместо этого конкретные маппинги портов в соответствующих директивах ports" | |
exit 1 | |
fi | |
# Проверка volumes | |
echo "::info:: Ниже будут все volumes всех сервисов" | |
yq '.services.*.volumes' ${dc_file} | |
if yq '.services.*.volumes' ${dc_file} | grep -v ':ro$' | grep -q '^[^/a-zA-Z]*/' | |
then | |
echo "::error:: Ошибка - у вас есть смонтированные в volumes файлы и/или каталоги без метки ro (read-only, https://docs.docker.com/compose/compose-file/05-services/#short-syntax-5). Монтируемый каталог или файл нужно или копировать на этапе сборки контейнера (если там данные, которые не предполагают изменение), или ставить опцию :ro ." | |
exit 1 | |
fi | |
# Проверка всех сервисов на общие ошибки | |
for i in $(seq 0 $(( services_count - 1 )) ); | |
do | |
service=`yq '.services | keys ['$i']' ${dc_file}` | |
echo "::info:: Проверка сервиса: ${service}" | |
yq '.services.'$service ${dc_file} | |
image=`yq '.services.'$service'.image' ${dc_file}` | |
if [[ "${image}" != "null" ]]; | |
then | |
if echo ${image} | grep -qE ':latest|^[^:]*$'; | |
then | |
echo "::error:: Ошибка - отсутствие тега или использование тега latest. Обе эти ситуации означают, что вы не привязаны к опредлеленной версии образа и в случае его обновления работа приложения может нарушится (а вы об этом узнаете только постфактум). Укажите явно тег." | |
exit 1 | |
fi | |
fi | |
ports=`yq '.services.'$service'.ports' ${dc_file}` | |
if [[ "${ports}" != "null" ]]; | |
then | |
if echo ${ports} | grep -qv '^[^0-9]*127.0.0.1:'; | |
then | |
echo "::error:: Ошибка - явно не указан интерфейс при маппинге портов. По умолчанию (если не указывать вот так 127.0.0.1:3000:80), докер мапит на все доступные интерфейсы и это нарушает безопасность. Добавьте 127.0.0.1: к содержимому директивы ports " | |
exit 1 | |
fi | |
fi | |
external_ports=`echo $ports | grep '127.0.0.1' | sed 's/^[^1]*127.0.0.1:\([^:]*\):[^:]*$/\1/g'` | |
for port in $external_ports; | |
do | |
if [[ "$port" < 1025 ]]; | |
then | |
echo "::error:: Ошибка - использование внешних портов хоста <=1024. Данные порты зарезервированы под системные нужды, лучше использовать порты с номерами выше 8000 (чтобы не было коллизий). " | |
exit 1 | |
fi | |
done | |
done | |
- name: Build docker-compose | |
run: | | |
docker-compose build --no-cache | |
- name: Run docker-compose | |
run: | | |
docker-compose up -d | |
sleep 30 | |
- name: Check containers are alive | |
run: | | |
echo "::notice:: docker ps --filter status=exited" | |
docker ps --filter status=exited | |
exited_count=`docker ps --filter status=exited | tail -n +2 | wc -l` | |
echo "::notice:: docker ps --filter status=dead" | |
docker ps --filter status=dead | |
dead_count=`docker ps --filter status=dead | tail -n +2 | wc -l` | |
echo "::notice:: docker ps --filter status=restarting" | |
docker ps --filter status=restarting | |
restarting_count=`docker ps --filter status=restarting | tail -n +2 | wc -l` | |
echo "::notice:: docker ps --filter status=paused" | |
docker ps --filter status=paused | |
paused_count=`docker ps --filter status=paused | tail -n +2 | wc -l` | |
echo "::notice:: docker ps --filter status=created" | |
docker ps --filter status=created | |
created_count=`docker ps --filter status=created | tail -n +2 | wc -l` | |
if [[ "${exited_count}" != "0" ]] || [[ "${restarting_count}" != "0" ]] || [[ "${paused_count}" != "0" ]] || [[ "${created_count}" != "0" ]] || [[ "${created_count}" != "0" ]]; then | |
echo "::error::Часть контейнеров не находится в состоянии running (завершили или не начали свою работу корректно) " | |
exit 1 | |
fi | |
- name: check_tag | |
run: | | |
TAG="0.8" | |
if [ $(git tag -l "${TAG}") ]; then | |
echo "::notice::Тег ${TAG} найден" | |
else | |
echo "::error::Тег ${TAG} не найден" | |
exit 1 | |
fi |