Можно ли использовать Testcontainers с Podman в тестах Java? По состоянию на март 2022 года библиотека Testcontainers не определяет установленный Podman как допустимую среду Docker.
Может ли Podman заменить Docker как на MacOS с Apple Silicon (локальная среда разработки), так и на Linux x86_64 (среда CI/CD)?
Можно использовать Podman с тестовыми контейнерами в проектах Java, которые используют Gradle в Linux и MacOS (как x86_64, так и Apple Silicon).
Библиотека Testcontainers взаимодействует с Podman с помощью файла сокета.
Запустите службу Podman для обычного пользователя (без root) и заставьте его слушать сокет:
systemctl --user enable --now podman.socket
Проверьте статус службы Podman:
systemctl --user status podman.socket
Проверьте, существует ли файл сокета:
ls -la /run/user/$UID/podman/podman.sock
Файл сокета Podman /run/user/1000/podman/podman.sock
можно найти внутри виртуальной машины Linux, управляемой Podman. Локальный сокет в MacOS можно перенаправить на удаленный сокет на виртуальной машине, управляемой Podman, с помощью туннелирования SSH.
Порт виртуальной машины, управляемой Podman, можно найти с помощью команды podman system connection list --format=json
.
Установите jq для разбора JSON:
brew install jq
Создайте псевдоним оболочки для переадресации локального сокета /tmp/podman.sock
на удаленный сокет /run/user/1000/podman/podman.sock
:
echo "alias podman-sock=\"rm -f /tmp/podman.sock && ssh -i ~/.ssh/podman-machine-default -p \$(podman system connection list --format=json | jq '.[0].URI' | sed -E 's|.+://.+@.+:([[:digit:]]+)/.+|\1|') -L'/tmp/podman.sock:/run/user/1000/podman/podman.sock' -N core@localhost\"" >> ~/.zprofile
source ~/.zprofile
Откройте туннель SSH:
podman-sock
Перед выполнением тестов с помощью Testcontainers убедитесь, что туннель SSH открыт.
build.gradle
test {
OperatingSystem os = DefaultNativePlatform.currentOperatingSystem;
if (os.isLinux()) {
def uid = ["id", "-u"].execute().text.trim()
environment "DOCKER_HOST", "unix:///run/user/$uid/podman/podman.sock"
} else if (os.isMacOsX()) {
environment "DOCKER_HOST", "unix:///tmp/podman.sock"
}
environment "TESTCONTAINERS_RYUK_DISABLED", "true"
}
Установите переменную среды DOCKER_HOST
в файл сокета Podman в зависимости от операционной системы.
Отключите Ryuk с помощью переменной окружения TESTCONTAINERS_RYUK_DISABLED
.
Moby Ryuk helps you to remove containers/networks/volumes/images by given filter after specified delay.
Ryuk — это технология для Docker, которая не поддерживает Podman. См. тестконтейнеры/моби-рюк#23
Библиотека Testcontainers использует Ruyk для удаления контейнеров. Вместо того, чтобы полагаться на Ryuk для неявного удаления контейнеров, мы будем удалять контейнеры явно с помощью ловушки отключения JVM:
Runtime.getRuntime().addShutdownHook(new Thread(container::stop));
В качестве альтернативы настройке Testcontainers в скрипте сборки Gradle вы можете передать переменные среды в Gradle.
DOCKER_HOST = "unix:///run/user/$UID/podman/podman.sock" \
TESTCONTAINERS_RYUK_DISABLED = "true" \
./gradlew clean build -i
DOCKER_HOST = "unix:///tmp/podman.sock" \
TESTCONTAINERS_RYUK_DISABLED = "true" \
./gradlew clean build -i
См. полный пример https://github.com/evgeniy-khist/podman-testcontainers
Для Linux это определенно работает, хотя официальная документация testcontainers не очень ясна.
# Enable socket
systemctl --user enable podman.socket --now
# Export env var expected by Testcontainers
export DOCKER_HOST=unix:///run/user/${UID}/podman/podman.sock
export TESTCONTAINERS_RYUK_DISABLED=true
Источники: