Введение
В предыдущей лабораторной работе вы узнали о «контроле качества» (CI). Теперь перейдём к следующему этапу: упаковке.
Представьте программное обеспечение как продукт на фабрике. После прохождения всех проверок качества его нужно положить в коробку, запечатать и промаркировать, прежде чем отправить заказчикам. В мире программного обеспечения такой «коробкой» часто служит Docker-контейнер.
Упакованный результат мы называем артефактом. После сборки артефакты нужно сохранить в реестре, чтобы следующие этапы, например развёртывание, могли получить точно такую же сборку.
Именно воспроизводимость является ключевой идеей. При развёртывании нужно использовать известный результат сборки, а не заново собирать код по-разному на каждой целевой машине.
GitHub предоставляет реестр под названием GitHub Container Registry (GHCR).
В этой лабораторной работе вы научите своего робота-помощника:
- Упаковывать приложение в Docker-контейнер.
- Помечать его тегом версии.
- Отправлять (push) его на склад GitHub автоматически.
Предварительные требования
Мы продолжим использовать репозиторий github-actions-basics.
Создайте Dockerfile
Прежде чем робот сможет упаковать приложение, ему нужны инструкции. В Docker эти инструкции записывают в специальный файл Dockerfile.
Перейдите в каталог проекта.
cd ~/project
git clone https://github.com/your-username/github-actions-basics.git
cd github-actions-basics
Примечание: замените your-username своим именем пользователя GitHub.
Создайте файл с именем Dockerfile (с прописной буквы D и без расширения) со следующим содержимым.
cat > Dockerfile << EOF
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["node", "index.js"]
EOF
Вот что именно этот список инструкций велит роботу сделать:
FROM node:16-alpine: начать с лёгкой базовой системы, в которой уже установлен Node.js;WORKDIR /app: создать рабочую папку внутри контейнера;COPY ...: скопировать файлы проекта в контейнер;RUN npm install: установить необходимые зависимости внутри контейнера;CMD ...: при запуске контейнера запустить приложение.
Теперь добавьте этот файл в репозиторий и отправьте изменения на GitHub.
git add Dockerfile
git commit -m "Add Dockerfile"
git push
Создайте рабочий процесс публикации
Теперь создадим новый рабочий процесс для упаковки и отправки приложения. Назовём его docker-publish.yml.
Создайте файл:
touch .github/workflows/docker-publish.yml
Откройте его в nano.
nano .github/workflows/docker-publish.yml
Добавьте следующую конфигурацию. Здесь мы вводим новое понятие — permissions (разрешения).
name: Docker Publish
on:
push:
branches: ["master", "main"]
permissions:
contents: read
packages: write
jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
Зачем нужны разрешения?
По умолчанию робот имеет ограниченный доступ из соображений безопасности. Поскольку мы хотим, чтобы робот загружал данные в вашу учётную запись GitHub (в раздел «packages»), ему нужно явно предоставить ключ от склада. Именно это делает параметр packages: write.
Это хороший пример принципа минимально необходимых привилегий при проектировании конвейера. Рабочие процессы должны получать только те разрешения, которые нужны для выполняемой задачи.
Сохраните файл и выйдите из nano (Ctrl+X, Y, Enter).
Добавьте этапы сборки и отправки
Теперь проверим самую важную часть — сборку и отправку образа.
Мы воспользуемся двумя официальными инструментами Docker (actions):
docker/login-action: для входа в склад;docker/build-push-action: для сборки контейнера и его отправки.
Этот этап соединяет CI и доставку. После успешного прохождения тестов конвейер создаёт версионированный артефакт, который другие системы смогут развернуть позже без повторной сборки из исходного кода.
Снова откройте .github/workflows/docker-publish.yml.
nano .github/workflows/docker-publish.yml
Добавьте следующие этапы в задание build-and-push:
- name: Log in to the Container registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}/app:latest
Разберём специальные переменные:
ghcr.io: адрес «склада» GitHub;${{ github.actor }}: переменная, которая автоматически подставляет ваше имя пользователя GitHub;${{ secrets.GITHUB_TOKEN }}: специальный временный пароль, который GitHub создаёт для робота. Вам ничего не нужно делать — всё работает автоматически. Этот токен позволяет роботу безопасно войти в систему без ручного ввода пароля;tags: метка для контейнера. Она имеет формат:Адрес склада / Ваше имя / Имя репозитория / Имя приложения : Версия.
Сохраните файл и выйдите из nano.
Теперь отправьте этот рабочий процесс на GitHub, чтобы запустить процесс.
git add .
git commit -m "Add Docker publishing workflow"
git push
Проверьте артефакт
Теперь ваш робот усердно работает: настраивает сервер, входит в систему, собирает контейнер и отправляет его.
- Откройте свой репозиторий на GitHub.
- Перейдите на вкладку Actions.
- Нажмите запуск рабочего процесса «Docker Publish».
- Дождитесь, пока этапы станут зелёными.

После успешного завершения этапа «Build and push Docker image» ваш пакет окажется на складе. Давайте найдём его.
- Перейдите на главную страницу репозитория, на вкладку Code.
- Посмотрите на боковую панель справа. Вы должны увидеть раздел Packages.
- В этом разделе появится новый пакет.
Нажмите имя пакета, чтобы просмотреть его сведения. Это готовый артефакт. Любой пользователь с доступом к вашему репозиторию (или любой пользователь, если репозиторий общедоступен) теперь сможет скачать и запустить ваше приложение с помощью этого образа.

Итоги
В этой лабораторной работе вы создали полный конвейер доставки.
Вы научились:
- Упаковке: создавать
Dockerfile, чтобы помещать приложение в контейнер; - Разрешениям: предоставлять рабочему процессу доступ на запись в раздел packages;
- Хранению: использовать GitHub Container Registry (GHCR) для хранения образов;
- Автоматизации: автоматически собирать и отправлять код с помощью стандартных actions.
Теперь ваш робот-помощник умеет проверять код (CI) и отправлять код в виде артефактов. В следующей лабораторной работе мы рассмотрим безопасную работу с конфиденциальной информацией, например паролями.



