Stwórz swój pierwszy pipeline CI/CD od zera
Stworzenie pierwszego pipeline'a CI/CD może wydawać się trudnym zadaniem, szczególnie gdy systemy produkcyjne są złożone i ryzykowne do eksperymentów. Jednak podstawowe zasady są zaskakująco proste: pipeline to po prostu zautomatyzowany proces, który instaluje zależności, uruchamia testy i buduje aplikację w czystym, powtarzalnym środowisku. Ten przewodnik przeprowadzi Cię przez fundamentalne koncepcje i praktyczne kroki potrzebne do stworzenia pipeline'a CI/CD od zera, zamieniając ręczne, podatne na błędy wdrożenia w niezawodny zautomatyzowany przepływ pracy.
Nie potrzebujesz Kubernetes ani systemu na skalę produkcyjną, aby ćwiczyć CI/CD. Zacznij od małego projektu, repozytorium Git i narzędzia CI, takiego jak GitHub Actions, GitLab CI lub Jenkins. Najważniejszym krokiem jest upewnienie się, że Twoja kompilacja jest powtarzalna lokalnie, zanim napiszesz choćby jedną linię konfiguracji pipeline'a.
Podstawa: powtarzalność jest kluczem do sukcesu
Zanim napiszesz pierwszy plik pipeline'a, Twój projekt musi budować się od zera. Jeśli nie udaje się to na świeżym klonie repozytorium, nie uda się również w CI.
Krok 1: Spraw, aby lokalna kompilacja była powtarzalna
Złota zasada to upewnienie się, że aplikacja pomyślnie buduje się od zera na lokalnej maszynie. Na przykład:
- Node.js:
npm ci && npm test && npm run build - Python:
pip install -r requirements.txt && pytest - Go:
go test ./... && go build
Krok 2: Zatwierdź pliki blokad
Pliki blokad (np. package-lock.json, go.sum lub Pipfile.lock) są niezbędne do deterministycznych kompilacji. Bez nich Twój pipeline CI może zainstalować inne wersje zależności niż te używane lokalnie, co prowadzi do nieprzewidywalnych błędów testów. W Node.js polecenie npm ci ściśle przestrzega pliku blokady, zapobiegając takiemu „dryfowi zależności”.
Pisanie pierwszego pipeline'a
Mając powtarzalną kompilację, możesz ją zautomatyzować. Podstawowy pipeline składa się z trzech etapów: budowanie, testowanie i wdrażanie.
Krok 3: Wybierz narzędzie CI/CD
Twój wybór często zależy od tego, gdzie przechowywany jest Twój kod. Oto trzy popularne opcje:
| Narzędzie | Do czego najlepiej się nadaje | Definicja pipeline'a | Opcja samodzielnego hostowania |
|---|---|---|---|
| GitHub Actions | Projekty już na GitHub, publiczne repozytoria (bezpłatnie). | .github/workflows/*.yml |
Tak (Self-hosted runners) |
| GitLab CI | Wszechstronna platforma DevOps z hostingiem Git. | .gitlab-ci.yml |
Tak (GitLab CE) |
| Jenkins | Wysoka konfigurowalność, dojrzały ekosystem, złożona logika kompilacji. | Jenkinsfile (Groovy) |
Tak (przez Java, oparty na wtyczkach) |
Krok 4: Utwórz minimalną konfigurację pipeline'a
Definicja pipeline'a to plik YAML lub Groovy w katalogu głównym repozytorium, który informuje runner CI, co ma robić.
Przykład: .gitlab-ci.yml (GitLab CI)
Ten kod definiuje pipeline, który buduje aplikację Go, zapisuje plik binarny jako artefakt, a następnie uruchamia go w następnym etapie.
default:
image: golang
stages:
- build
- run
build go:
stage: build
script:
- go build
artifacts:
paths:
- array
run go:
stage: run
script:
- ./array
Przykład: Jenkinsfile (deklaratywny pipeline)
Robi to samo, używając obrazu Docker do uruchomienia aplikacji Node.js.
pipeline {
agent { docker { image 'node:20-alpine' } }
stages {
stage('Build') {
steps { sh 'npm ci && npm run build' }
}
stage('Test') {
steps { sh 'npm run test' }
}
}
}
⚠️ Ostrzeżenie bezpieczeństwa: Nigdy nie koduj na stałe zmiennych środowiskowych, takich jak adresy URL baz danych czy klucze API, w swoim repozytorium. Używaj wbudowanego menedżera sekretów swojego narzędzia CI (zmienne GitLab CI, poświadczenia Jenkins lub sekrety GitHub Actions), aby wstrzykiwać je do zadań.
Wymiana danych między etapami
Kluczową cechą nowoczesnych pipeline'ów jest możliwość wymiany danych między zadaniami. Bez tego musiałbyś przebudowywać aplikację na każdym etapie, marnując czas i zasoby.
Krok 5: Używaj artefaktów
Artefakty to pliki lub katalogi zapisane z jednego zadania i dostępne dla kolejnych zadań. W przykładzie GitLab CI zadanie build go zapisuje plik binarny array. Zadanie run go następnie automatycznie pobiera ten plik binarny, używając go bez potrzeby ponownej kompilacji.
Automatyzacja wdrożeń (opcjonalnie)
Gdy CI działa, możesz dodać ciągłe wdrażanie. Zasada jest prosta: wdrożenia powinny być wykonywane tylko po przejściu testów.
Krok 6: Zaimplementuj podstawową strategię wdrożenia
W przypadku prostych aplikacji polecenie SSH może skopiować pliki na serwer.
Przykład: Wdrożenie za pomocą rsync
deploy:
stage: deploy
image: alpine:latest
only:
- main
script:
- apk add --no-cache openssh-client rsync
- rsync -avz --delete dist/ deploy@yourserver:/var/www/app/
Jeśli używasz kontenerów, etap wdrożenia zazwyczaj obejmuje zbudowanie obrazu Docker, wysłanie go do rejestru, a następnie użycie SSH do wykonania docker compose pull && docker compose up -d na serwerze produkcyjnym.
Praktyka i rozwiązywanie problemów
Czytanie o CI/CD to za mało. Aby naprawdę się nauczyć, musisz uruchamiać pipeline'y i celowo je psuć.
Krok 7: Celowo psuj rzeczy, aby się uczyć
To tutaj następuje prawdziwe zrozumienie. Wypróbuj następujące eksperymenty:
- Usuń deklarację zależności. Czy CI upadnie? Dlaczego?
- Usuń plik blokady. Czy dryf wersji spowoduje błąd kompilacji?
- Dodaj niestabilny test. Czy przechodzi lokalnie, ale pada w CI? To często ujawnia różnice w czystym środowisku CI.
Krok 8: Korzystaj z raportów testów i logów
CI powinien zapewniać widoczność tego, które testy upadły, które są wolne, a które niestabilne. Używaj logów nie tylko do znajdowania błędów, ale także do zrozumienia całego procesu: ile czasu zajmuje instalacja zależności? Gdzie dokładnie następuje awaria kompilacji?
Często zadawane pytania
Ile czasu zajmuje stworzenie pierwszego pipeline'a CI/CD? W przypadku prostego projektu podstawowy pipeline można uruchomić w mniej niż godzinę. W praktycznym przewodniku GitLab CI szacowany czas na podstawowy pipeline to 15 minut. Czas zwykle poświęca się na napisanie pliku konfiguracyjnego i rozwiązywanie problemów z powtarzalnością.
Czy początkujący powinien wybrać Jenkinsa, GitHub Actions czy GitLab CI? Jeśli Twój kod jest na GitHub, GitHub Actions jest naturalnym wyborem. Dla platformy „wszystko w jednym” świetnie nadaje się GitLab CI. Jenkins jest niezwykle potężny, ale ma bardziej stromą krzywą uczenia się i wymaga więcej konserwacji, dlatego częściej nadaje się do większych i bardziej złożonych konfiguracji.
Jaka jest różnica między artefaktem a pamięcią podręczną w CI/CD?
Artefakty służą do przesyłania plików między etapami (np. przekazanie skompilowanego pliku binarnego z etapu budowania do etapu wdrażania). Pamięć podręczna służy do przyspieszania kompilacji poprzez ponowne wykorzystanie plików, takich jak zależności (node_modules), między różnymi uruchomieniami pipeline'a.
Dlaczego moje testy przechodzą lokalnie, ale padają w pipeline'ie CI? To zazwyczaj oznaka dryfu środowiska. Na Twojej lokalnej maszynie mogą być inne wersje oprogramowania lub zmienne środowiskowe. Dlatego zatwierdzanie plików blokad jest tak ważne i dlatego uruchomienie projektu ze świeżego klonu lokalnie jest niezbędnym pierwszym krokiem.
Czy potrzebuję Dockera do stworzenia pipeline'a CI/CD? Ściśle mówiąc, nie, ale jest to zdecydowanie zalecane. Uruchamianie zadań wewnątrz kontenerów Docker zapewnia izolację i powtarzalność. Gwarantuje to, że każde zadanie jest wykonywane w czystym, znanym środowisku, zapobiegając wzajemnemu wpływowi zadań i zanieczyszczeniu serwera hosta.
— Editorial Team
Brak komentarzy.