GitLab Runner: Budowanie obrazów Docker
Efektywne budowanie i wysyłanie obrazów Docker z pipeline’ów GitLab CI/CD przy użyciu runnerów Stackhero oraz Docker-in-Docker
👋 Witamy w dokumentacji Stackhero!
Stackhero oferuje łatwe w użyciu rozwiązanie GitLab Runner cloud, zaprojektowane do wydajnej obsługi zadań GitLab CI/CD. Oto, czego możesz się spodziewać:
- Nielimitowane minuty CI/CD: brak rozliczania za minuty, więc Twoje pipeline'y mogą działać zawsze, gdy tego potrzebujesz.
- Wiele równoczesnych zadań: uruchamiaj kilka jobów jednocześnie, aby przyspieszyć cały pipeline.
- Docker executor z obsługą Docker-in-Docker: usprawnij budowanie i wysyłanie swoich obrazów kontenerów.
- Kompatybilny zarówno z GitLab.com, jak i każdą samodzielnie zarządzaną instancją GitLab.
- Prywatna, dedykowana maszyna wirtualna (VM) oparta na szybkich dyskach NVMe/SSD, zapewniająca stabilne i niezawodne buildy.
- Dostępny w regionach 🇪🇺 Europa oraz 🇺🇸 USA.
Oszczędzaj czas: możesz podłączyć swojego pierwszego GitLab Runnera i uruchomić pipeline'y w zaledwie kilka minut!
Wprowadzenie
W przypadku Stackhero GitLab Runner, każde zadanie uruchamiane jest w świeżym kontenerze z wykorzystaniem egzekutora Docker. Możesz budować własne obrazy Docker bezpośrednio w swoim pipeline, włączając Docker-in-Docker (DinD). Taka konfiguracja uruchamia demona Docker równolegle z Twoim zadaniem, dzięki czemu możesz wykonywać polecenia docker build oraz docker push w ramach procesu CI/CD.
Każde uruchomienie korzysta z nielimitowanych minut CI/CD: możesz budować tak często, jak potrzebujesz, bez obaw o limity wykorzystania. Twój cache buildów przechowywany jest na dedykowanym dysku runnera, co pozwala na ponowne wykorzystanie wcześniejszych warstw podczas kolejnych buildów. Znacząco skraca to czas budowania i przyspiesza realizację pipeline’ów.
Budowanie obrazu Docker z Docker-in-Docker
Możesz dodać poniższy przykładowy plik .gitlab-ci.yml do swojego repozytorium. Ta konfiguracja buduje Dockerfile znajdujący się w katalogu głównym projektu:
build-image:
stage: build
image: docker:29
services:
- docker:29-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker info
script:
# Zamień "my-image" na wybraną nazwę:
- docker build -t my-image .
# Opcjonalnie, uruchom szybki test na zbudowanym obrazie:
# - docker run --rm my-image /path/to/tests
W tym przykładzie używamy obrazu Docker w wersji 29. Możesz użyć nowszej wersji, jeśli jest dostępna. Najnowsze tagi znajdziesz na oficjalnej stronie obrazu Docker.
W tej konfiguracji, usługa docker:29-dind uruchamia demona Docker. Ustawienie DOCKER_TLS_CERTDIR: "/certs" umożliwia bezpieczne połączenie TLS pomiędzy zadaniem a demonem Docker.
Wysyłanie do rejestru kontenerów GitLab
GitLab udostępnia predefiniowane zmienne (CI_REGISTRY, CI_REGISTRY_USER, CI_REGISTRY_PASSWORD, CI_REGISTRY_IMAGE), dzięki którym pipeline może się uwierzytelnić i bezpiecznie wysyłać obrazy do rejestru kontenerów projektu. Nie są wymagane żadne dodatkowe sekrety.
Oto przykładowe zadanie, które buduje i wysyła Twój obraz:
build-and-push:
stage: build
image: docker:29
services:
- docker:29-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
script:
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
# Jeśli jesteś na domyślnej gałęzi, możesz również oznaczyć i wysłać "latest":
- |
if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then
docker tag "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" "$CI_REGISTRY_IMAGE:latest"
docker push "$CI_REGISTRY_IMAGE:latest"
fi
Aby wysyłać obrazy do innego rejestru (np. Docker Hub lub prywatnego rejestru), możesz przechowywać dane uwierzytelniające jako zmienne CI/CD i używać ich z docker login w ten sam sposób.
Przyspieszanie powtarzalnych buildów
Dysk runnera jest zachowywany pomiędzy pipeline’ami, co pozwala na ponowne wykorzystanie warstw obrazu jako cache buildów. Dzięki temu kolejne buildy mogą być znacznie szybsze. Przykładowa konfiguracja:
build-cached:
stage: build
image: docker:29
services:
- docker:29-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
before_script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
script:
# Pobierz najnowszy obraz, aby zainicjować cache (jeśli istnieje):
- docker pull "$CI_REGISTRY_IMAGE:latest" || true
- docker build --cache-from "$CI_REGISTRY_IMAGE:latest" -t "$CI_REGISTRY_IMAGE:latest" .
- docker push "$CI_REGISTRY_IMAGE:latest"
Takie podejście pozwala wykorzystać cache warstw Docker, dzięki czemu przebudowywane są tylko nowe lub zmienione warstwy.
Uruchamianie zadań równolegle
Twój plan określa, ile zadań może być uruchamianych jednocześnie. Zadania w tej samej fazie startują równolegle, do limitu współbieżności. Oznacza to, że kilka niezależnych zadań może być wykonywanych w tym samym czasie i zakończą się, gdy najwolniejsze z nich się skończy, zamiast czekać na zakończenie każdego po kolei.
Przykład:
stages:
- test
unit:
stage: test
image: node:22
script: npm run test:unit
integration:
stage: test
image: node:22
script: npm run test:integration
e2e:
stage: test
image: node:22
script: npm run test:e2e
Jeśli ustawisz współbieżność na 1 lub więcej, zadania unit, integration i e2e będą uruchamiane równolegle.
Więcej informacji na temat budowania obrazów Docker w pipeline’ach GitLab CI/CD znajdziesz w oficjalnej dokumentacji GitLab dotyczącej używania Docker build.