В этой главе мы соберём Docker-образ с приложением, используя werf и Dockerfile, а потом проверим собранный образ, запустив его локально.

Подготовка

Установите werf и его зависимости, следуя инструкциям.

Создадим новый репозиторий с приложением

Выполним следующий набор команд в PowerShell:

# Склонируем репозиторий с примерами в ~/werf-guide/guides, если он ещё не был склонирован.
if (-not (Test-Path ~/werf-guide/guides)) {
  git clone https://github.com/werf/website $env:HOMEPATH/werf-guide/guides
}

# Скопируем файлы приложения (пока без изменений) в ~/werf-guide/app.
rm -Recurse -Force ~/werf-guide/app
cp -Recurse -Force ~/werf-guide/guides/examples/basic/000_app ~/werf-guide/app

# Сделаем из директории ~/werf-guide/app git-репозиторий.
cd ~/werf-guide/app
git init
git add .
git commit -m initial

# Чтобы увидеть, какие изменения мы собрались вносить далее в этой главе, заменим все файлы приложения
# в репозитории новыми, уже измененными файлами приложения, которые содержат описанные далее изменения.
git rm -r .
cp -Recurse -Force ~/werf-guide/guides/examples/basic/001_build/* .
git add .
git commit -m WIP
Посмотреть, какие именно изменения мы произведём
# Показать, какие файлы мы собираемся изменить.
git show --stat
# Показать изменения.
git show

Выполним следующий набор команд в Bash:

# Склонируем репозиторий с примерами в ~/werf-guide/guides, если он ещё не был склонирован.
test -e ~/werf-guide/guides || git clone https://github.com/werf/website ~/werf-guide/guides

# Скопируем файлы приложения (пока без изменений) в ~/werf-guide/app.
rm -rf ~/werf-guide/app
cp -rf ~/werf-guide/guides/examples/basic/000_app ~/werf-guide/app

# Сделаем из директории ~/werf-guide/app git-репозиторий.
cd ~/werf-guide/app
git init
git add .
git commit -m initial

# Чтобы увидеть, какие изменения мы собрались вносить далее в этой главе, заменим все файлы приложения
# в репозитории новыми, уже измененными файлами приложения, которые содержат описанные далее изменения.
git rm -r .
cp -rf ~/werf-guide/guides/examples/basic/001_build/. .
git add .
git commit -m WIP
Посмотреть, какие именно изменения мы произведём
# Показать, какие файлы мы собираемся изменить.
git show --stat
# Показать изменения.
git show

Dockerfile

В Windows во избежание проблем при редактировании файлов рекомендуем использовать Notepad++ или любой другой редактор вместо стандартного Блокнота.

Логика сборки нашего приложения будет реализована в Dockerfile:

FROM alpine:3.14
WORKDIR /app

# Устанавливаем зависимости приложения.
RUN apk add --no-cache --update nmap-ncat

# Добавляем в образ скрипт для запуска эхо-сервера и устанавливаем разрешение на выполнение.
COPY start.sh .
RUN chmod +x start.sh
FROM alpine:3.14 WORKDIR /app # Устанавливаем зависимости приложения. RUN apk add --no-cache --update nmap-ncat # Добавляем в образ скрипт для запуска эхо-сервера и устанавливаем разрешение на выполнение. COPY start.sh . RUN chmod +x start.sh

Интеграция werf и Dockerfile

В корне репозитория, в основном файле конфигурации werf werf.yaml будет указано, какой Dockerfile должен будет использоваться при сборке с werf:

project: werf-guide-app
configVersion: 1

---
image: app
dockerfile: Dockerfile
project: werf-guide-app configVersion: 1 --- image: app dockerfile: Dockerfile

В werf.yaml может описываться сборка сразу нескольких образов. Также для сборки образа существует ряд дополнительных настроек, с которыми можно ознакомиться в документации.

Сборка с werf

Обратите внимание, что перед запуском сборки/деплоя с werf все файлы должны быть добавлены в коммит. Чуть позже мы разберём, для чего это нужно и как обойтись без постоянного создания новых коммитов при локальной разработке.

Запустим сборку командой werf build:

werf build

Результат выполнения команды при успешной сборке:

┌ ⛵ image app
│ ┌ Building stage app/dockerfile
│ │ app/dockerfile  Sending build context to Docker daemon  4.096kB
│ │ app/dockerfile  Step 1/14 : FROM alpine:3.14
│ │ app/dockerfile   ---> d4ff818577bc
│ │ app/dockerfile  Step 2/14 : WORKDIR /app
│ │ app/dockerfile   ---> Using cache
│ │ app/dockerfile   ---> fecacd1a1c75
│ │ app/dockerfile  Step 3/14 : RUN apk add --no-cache --update nmap-ncat
│ │ app/dockerfile   ---> Running in 9bead7817a6d
│ │ app/dockerfile  fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/main/x86_64/APKINDEX.tar.gz
│ │ app/dockerfile  fetch https://dl-cdn.alpinelinux.org/alpine/v3.14/community/x86_64/APKINDEX.tar.gz
│ │ app/dockerfile  (1/3) Installing lua5.3-libs (5.3.6-r0)
│ │ app/dockerfile  (2/3) Installing libpcap (1.10.0-r0)
│ │ app/dockerfile  (3/3) Installing nmap-ncat (7.91-r0)
│ │ app/dockerfile  Executing busybox-1.33.1-r2.trigger
│ │ app/dockerfile  OK: 6 MiB in 17 packages
│ │ app/dockerfile  Removing intermediate container 9bead7817a6d
│ │ app/dockerfile   ---> ac1cbf858c89
│ │ app/dockerfile  Step 4/14 : COPY start.sh .
│ │ app/dockerfile   ---> 0f51cefb9aaf
│ │ app/dockerfile  Step 5/14 : RUN chmod +x start.sh
│ │ app/dockerfile   ---> Running in c87188cc85f7
│ │ app/dockerfile  Removing intermediate container c87188cc85f7
│ │ app/dockerfile   ---> 7d47843543ed
│ │ app/dockerfile  ...
│ │ app/dockerfile  Successfully built 3091b84c90c3
│ │ app/dockerfile  Successfully tagged 10560bef-f182-4769-bb23-c4a465814016:latest
│ ├ Info
│ │      name: werf-guide-app:638307ec810d3921a7b4f96c775d8aa8826fb0b2e1ac81fc793f02a6-1625134265354
│ │        id: 4c3c2a9e934c
│ │   created: 2022-07-01 11:11:05.3235952 +0000 UTC
│ │      size: 6.0 MiB
│ └ Building stage app/dockerfile (9.98 seconds)
└ ⛵ image app (10.85 seconds)

Running time 11.02 seconds

Запуск приложения

Запустить контейнер локально на основе собранного образа можно командой werf run:

werf run app --docker-options="-ti --rm -p 8000:8000" -- /app/start.sh

Здесь параметры Docker мы задали опцией --docker-options, а команду для выполнения в контейнере указали в конце, после двух дефисов.

Для проверки работоспособности можно открыть страницу http://127.0.0.1:8000/ping в браузере или воспользоваться утилитой curl в соседнем терминале:

curl http://127.0.0.1:8000/ping

В результате вернётся сообщение pong, а в логе контейнера появится следующий текст:

GET /ping HTTP/1.1
Host: 127.0.0.1:8000
User-Agent: curl/7.67.0
Accept: */*
назад
далее