/0303_tomcat

Primary LanguageDockerfile

Week 03. Apache Tomcat Task (Slurm Навыкум "Build Containers!")

Задача

Есть проект, использующий Servlet API из Jakarta EE

Проект рассчитан на запуск в Apache Tomcat версии 10.1.x

Безопасность

В этом проекте всё максимально серьёзно: мы никому не доверяем, поэтому сами собрали ключевые компоненты:

  1. Root ФС (вместе с установленной Java)
  2. Maven
  3. Tomcat

Для всех файлов сосчитаны контрольные суммы (файлы с расширением *.sha512) и все файлы с контрольными суммами подписаны (файлы с расширением *.sha512.asc)

Публичный ключ, с помощью которого можно проверить подпись, расположен в репозитории под именем key.gpg

Отпечаток ключа: 70092656FB28DBB76C3BB42E89619023B6601234

Посмотреть можно командой:

gpg --dry-run --import --import-options import-show ./key.gpg 
pub   rsa4096 2023-04-09 [SCEA] [expires: 2033-04-06]
      70092656FB28DBB76C3BB42E89619023B6601234
uid                      Slurm (Main Key) <slurm@slurm.io>

gpg: Total number processed: 1

Сборка

Этап 1 (верификация)

Для верификации файлов берём доверенный образ от Bellsoft

Важно: при ссылке на образ указывайте не tag, а sha256 digest!

Важно: URL'ы файлов должны быть заданы с помощью аргументов сборки:

  1. GPG_KEY_URL
  2. ROOTFS_URL
  3. MAVEN_URL
  4. TOMCAT_URL

URL'ы файлов с контрольными суммами и подписями (для п.1-4) рассчитываются путём добавления соответствующих суффиксов

Затем устанавливаем туда GnuPG и проверяем все файлы в следующем порядке:

  1. Сначала проверяем отпечаток ключа key.gpg (должен быть 70092656FB28DBB76C3BB42E89619023B6601234)
  2. Затем проверяем контрольные суммы файлов с расширением tar.gz
  3. Затем проверяем подписи файлов с контрольными суммами

Если всё ОК, то переходим к этапу 2

Для упрощения, можете зашить контрольные суммы в Dockerfile, хотя можете предложить и решение получше

Спойлеры

Можете подглядеть официальные образы Java-приложений, чтобы посмотреть, как это примерно происходит

Например, образ Maven

Этап 2 (сборка)

Берём Scratch, накатываем туда:

  1. Root ФС
  2. Maven (в каталог /opt/bin/maven)

Важно: Maven должен быть именно в /opt/bin/maven, а не в /opt/bin/maven/apache-maven-3.9.1

Прописываем следующие переменные окружения:

  1. PATH=/usr/lib/jvm/jdk-17.0.6-bellsoft-x86_64/bin:/opt/bin/maven/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  2. LANG=en_US.UTF-8
  3. LANGUAGE=en_US.UTF-8:en
  4. JAVA_HOME=/usr/lib/jvm/jdk-17.0.6-bellsoft-x86_64
  5. MAVEN_HOME=/opt/bin/maven

Запускаем сборку:

mvn verify

В результате должен появиться файл target/api.war

Этап 3 (публикация)

Берём Scratch, накатываем туда:

  1. Root ФС
  2. Tomcat (в каталог /opt/bin/tomcat)

Важно: Tomcat должен быть именно в /opt/bin/tomcat, а не в /opt/bin/tomcat/apache-tomcat-10.1.7

Прописываем следующие переменные окружения:

  1. PATH=/usr/lib/jvm/jdk-17.0.6-bellsoft-x86_64/bin:/opt/bin/tomcat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  2. LANG=en_US.UTF-8
  3. LANGUAGE=en_US.UTF-8:en
  4. JAVA_HOME=/usr/lib/jvm/jdk-17.0.6-bellsoft-x86_64
  5. CATALINA_HOME=/opt/bin/tomcat

В качестве CMD указать catalina.sh run

WAR закинуть в $CATALINA_HOME/webapps так, чтобы приложение было доступно по адресу: http://localhost:8080/api (тестировать методом GET) в ответ придёт:

{"status": "ok"}

Важно: должно быть именно /api (если не удаётся – см. спойлеры)

Стандартные приложения (вроде manager и остальных) нужно удалить

Спойлеры

Во многих системах есть "специальные" имена

Например, в Tomcat есть такое имя – ROOT.war

Попробуйте найти в документации, для чего оно используется

Что нужно сделать

  1. Собрать всё согласно описанию выше (по этапам)
  2. Выложить результаты последнего этапа в виде публичного образа на GHCR (GitHub Container Registry)

Рекомендуется, но не обязательно, запускать приложение не от root

Требования

  1. Всё должно быть оформлено в виде публичного репозитория на GitHub
  2. Вся сборка образов должна проходить через GitHub Actions
  3. Образ должен выкладываться в GitHub Container Registry (GHCR)

К текущему заданию дополнительно предъявляются требования:

  1. Docker Buildx Build (указывайте явно при сборке docker buildx build)
  2. Multi-Stage