Continuous Integration i Continuous Delivery to nieodłączne elementy nowoczesnego developmentu. Dzięki nim automatyzujesz testowanie, budowanie i wdrażanie swoich aplikacji – zyskując czas, jakość i pewność, że Twoja aplikacja działa, jak należy.
👉 Jeśli chcesz lepiej zrozumieć samą koncepcję CI/CD, sprawdź mój wcześniejszy artykuł:
Continuous Integration i Continuous Delivery – wprowadzenie
Tutaj natomiast przejdziemy do konkretów – zbudujemy kompletny pipeline CI/CD w GitLabie dla aplikacji Java opartej na Spring Boot. Dowiesz się, jak:
- zbudować projekt (Maven/Gradle),
- uruchomić testy jednostkowe i integracyjne,
- przeprowadzić statyczną analizę kodu,
- zbudować obraz Dockera,
- wypchnąć go do GitLab Container Registry,
- automatycznie wdrożyć aplikację na serwer.
🛠️ Krok 1: Stwórz prostą aplikację Spring Boot
Nie musimy komplikować – wystarczy prosty endpoint:
@RestController
public class HelloController {
@GetMapping("/hello")
public String getHello() {
return "hello";
}
}
Dodaj też przykładowy test jednostkowy, na potrzeby scenariusza CI/CD:
@SpringBootTest
class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void helloShouldReturnDefaultMessage() throws Exception {
mockMvc.perform(get("/hello"))
.andExpect(status().isOk())
.andExpect(content().string("hello"));
}
}
🏗️ Krok 2: Konfiguracja Pipelin’u .gitlab-ci.yml
W katalogu głównym projektu utwórz plik .gitlab-ci.yml. Na samym początku tego pliku określ, z jakiego obrazu Dockerowego chcesz korzystać w jobach CI/CD – dla projektów Maven najczęściej wybieramy oficjalny obraz:
image: maven:3.9.4-eclipse-temurin-17
👉 To bardzo ważne – ten obraz zapewnia środowisko z zainstalowanym Mavenem i Javą 17. Dzięki temu wszystkie komendy mvn będą działać poprawnie.
Następnie definiujemy etapy (stages):
stages: - build - test - analyze - package - deploy
🚀 Krok 3: Budowanie i testowanie
before_script:
- chmod +x mvnw # Jeśli używasz mvnw, który znajduje się w repo (zamiast tego z obrazu) musisz dodać te uprawnienia
build:
stage: build
script:
- ./mvnw clean compile
test:
stage: test
script:
- ./mvnw test
🔍 Krok 4: Analiza kodu
Aby statyczna analiza kodu działała, musisz dodać do pom.xml plugin SpotBugs (lub inny).
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.3.0</version>
<configuration>
<failOnError>false</failOnError>
</configuration>
</plugin>
Następnie w .gitlab-ci.yml dodajesz:
analyze:
stage: analyze
script:
- ./mvnw com.github.spotbugs:spotbugs-maven-plugin:4.7.3.0:check
🐳 Krok 5: Budowanie Dockera i publikacja
W tym etapie chcemy zbudować obraz Dockera z naszą aplikacją Java i wysłać go do GitLab Container Registry, czyli prywatnego rejestru obrazów dostępnego w Twoim projekcie GitLab.
👉 Ale uwaga! Do budowania i pushowania obrazów Dockerowych potrzebujemy specjalnego środowiska – nie wystarczy już zwykły image z Mavenem. Tutaj konieczne jest uruchomienie Docker-in-Docker (DinD) – czyli środowiska, które pozwoli GitLabowi uruchamiać polecenia docker build, docker push itp.
Dlatego w tym etapie:
- używamy obrazu
docker:latest, który zawiera klienta Dockera, - uruchamiamy usługę pomocniczą
docker:dind, która daje dostęp do samego demona Dockera wewnątrz kontenera.
Oto gotowy przykład konfiguracji joba:
package:
stage: package
image: docker:latest # Obraz z klientem Docker
services:
- docker:dind # Demon Docker w kontenerze
script:
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
🌐 Krok 6: Automatyczny deploy
Etap wdrożenia zależy od tego, na jakie środowisko publikujesz aplikację. Inaczej będzie wyglądać deploy do AWS, inaczej na serwer z Kubernetesem, a jeszcze inaczej – na klasyczny VPS z Linuksem i Dockerem.
Na koniec naszego pipeline’u automatycznie wdrażamy aplikację na zdalny serwer VPS. W tym przykładzie używamy klasycznego połączenia SSH z wykorzystaniem sshpass, a sam deploy realizujemy za pomocą docker-compose.
deploy:
stage: deploy
image: alpine:latest
before_script:
- apk add --no-cache openssh sshpass
script:
- sshpass -p "$DEPLOY_SERVER_PASSWORD" ssh -o StrictHostKeyChecking=no root@123.123.123.123 "
docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com &&
docker pull registry.gitlab.com/my-group/my-project:$CI_COMMIT_SHORT_SHA &&
IMAGE_TAG=$CI_COMMIT_SHORT_SHA docker-compose -f /root/myapp/docker-compose.yml up -d"
⚠️ Uwaga: W powyższym przykładzie dane wrażliwe (klucz prywatny SSH i adres IP serwera) zostały wpisane jawnie tylko w celach demonstracyjnych. W prawdziwym projekcie zawsze przechowuj takie informacje jako zmienne środowiskowe w ustawieniach GitLaba (CI/CD → Variables), aby uniknąć przypadkowego wycieku danych i zadbać o bezpieczeństwo.
✅ Podsumowanie
I gotowe! Masz w pełni funkcjonalny pipeline CI/CD dla aplikacji Java w GitLabie. Budujesz, testujesz, analizujesz, pakujesz w kontener i… automatycznie wdrażasz!
Finalny plik .gitlab-ci.yml
image: maven:3.9.4-eclipse-temurin-17
stages:
- build
- test
- analyze
- package
- deploy
before_script:
- chmod +x mvnw
build:
stage: build
script:
- ./mvnw clean compile
test:
stage: test
script:
- ./mvnw test
analyze:
stage: analyze
script:
- ./mvnw com.github.spotbugs:spotbugs-maven-plugin:4.7.3.0:check
package:
stage: package
image: docker:latest
services:
- docker:dind
script:
- docker login -u "gitlab-ci-token" -p "$CI_JOB_TOKEN" $CI_REGISTRY
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
deploy:
stage: deploy
image: alpine:latest
only:
- main
before_script:
- apk add --no-cache openssh sshpass
script:
- sshpass -p "$DEPLOY_SERVER_PASSWORD" ssh -o StrictHostKeyChecking=no root@123.123.123.123 "
docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.gitlab.com &&
docker pull registry.gitlab.com/my-group/my-project:$CI_COMMIT_SHORT_SHA &&
IMAGE_TAG=$CI_COMMIT_SHORT_SHA docker-compose -f /root/myapp/docker-compose.yml up -d
"
🎓 Moje szkolenie
Chcesz zobaczyć live coding, praktyczne przykłady i jeszcze więcej detali CI/CD?
Dołącz do mojego szkolenia CI/CD dla Java Developerów, które poprowadzę już w maju – zarezerwuj miejsce i wynieś swój dev workflow na wyższy poziom!
Zobacz listę szkoleń


