
Grzegorz Kalmus
Autor
CI/CD (Continuous Integration / Continuous Deployment) to dziś jeden z filarów nowoczesnego wytwarzania oprogramowania. Jeśli tworzysz stronę internetową lub aplikację webową i wciąż wdrażasz zmiany ręcznie – przez FTP, SSH czy ręczne kopiowanie plików – tracisz czas, narażasz się na błędy i spowalniasz rozwój projektu. W tym artykule wyjaśniamy, czym jest CI/CD, dlaczego warto je wdrożyć oraz jak krok po kroku skonfigurować automatyczne wdrożenia dla projektu Next.js z użyciem GitHub Actions.
Czym jest CI/CD?
CI (Continuous Integration) to praktyka automatycznego sprawdzania każdej zmiany kodu – uruchamiania testów, linterów i buildów za każdym razem, gdy deweloper pushuje kod do repozytorium. Dzięki temu błędy są wykrywane natychmiast, zanim trafią na produkcję.
CD (Continuous Deployment lub Continuous Delivery) idzie krok dalej – automatycznie wdraża kod na serwer po przejściu wszystkich testów. W modelu Continuous Delivery wdrożenie wymaga ręcznego zatwierdzenia, w Continuous Deployment odbywa się w pełni automatycznie.
Korzyści? Według raportu DORA (DevOps Research and Assessment) zespoły stosujące CI/CD wdrażają kod 46 razy częściej i mają 5 razy krótszy czas wdrożenia niż zespoły bez automatyzacji. Błędy produkcyjne zdarzają się rzadziej, a przywracanie systemu do sprawności jest 2 razy szybsze.
Dlaczego GitHub Actions?
GitHub Actions to wbudowana platforma CI/CD bezpośrednio w GitHub. Nie potrzebujesz zewnętrznych narzędzi, oddzielnych kont ani integracji – wszystko działa w tym samym miejscu, gdzie trzymasz swój kod.
- Darmowy tier: 2000 minut miesięcznie dla repozytoriów publicznych i prywatnych na kontach darmowych
- Integracja z GitHub: automatyczne wyzwalanie przy push, pull request, merge
- Marketplace: tysiące gotowych akcji (deploy na Vercel, wysyłka powiadomień, skanowanie bezpieczeństwa)
- Macierze buildów: testowanie na wielu wersjach Node.js jednocześnie
- Self-hosted runners: możliwość uruchomienia na własnym serwerze, bez limitu minut
Dokumentacja GitHub Actions jest dostępna pod adresem docs.github.com/en/actions i zawiera setki gotowych przykładów dla każdego popularnego frameworka.
Podstawy: workflow, jobs i steps
Konfiguracja GitHub Actions opiera się na plikach YAML umieszczonych w katalogu .github/workflows/. Każdy plik to jeden workflow. Workflow składa się z:
- Trigger (on:) – zdarzenie wyzwalające workflow (push, pull_request, schedule)
- Jobs – grupy zadań uruchamianych na danym runnerze (np. ubuntu-latest)
- Steps – kolejne kroki wewnątrz joba: mogą to być komendy shell lub gotowe akcje z Marketplace
Jobs domyślnie uruchamiają się równolegle. Jeśli chcesz, żeby deploy odbył się po testach, musisz użyć słowa kluczowego needs.
Praktyczny workflow: lint – test – build – deploy
Poniżej kompletny przykład workflow dla projektu Next.js. Wklej go jako .github/workflows/deploy.yml:
name: CI/CD - Deploy to Production
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
ci:
name: Lint, Test & Build
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run ESLint
run: npm run lint
- name: Run tests
run: npm test -- --passWithNoTests
- name: Build Next.js
run: npm run build
env:
NODE_ENV: production
deploy:
name: Deploy to VPS
runs-on: ubuntu-latest
needs: ci
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install & Build
run: |
npm ci
npm run build
env:
NODE_ENV: production
- name: Deploy via rsync
uses: burnett01/rsync-deployments@6.0.0
with:
switches: -avzr --delete --exclude='.git' --exclude='node_modules'
path: .next/
remote_path: /var/www/mysite/.next/
remote_host: ${{ secrets.VPS_HOST }}
remote_user: ${{ secrets.VPS_USER }}
remote_key: ${{ secrets.VPS_SSH_KEY }}
- name: Restart PM2
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.VPS_HOST }}
username: ${{ secrets.VPS_USER }}
key: ${{ secrets.VPS_SSH_KEY }}
script: pm2 restart mysite
Wdrażanie na VPS przez SSH i rsync
Jeśli hostujesz stronę na własnym serwerze VPS (tak jak robimy przy tworzeniu stron internetowych na zamówienie), rsync przez SSH to najefektywniejsza metoda wdrożenia. Synchronizuje tylko zmienione pliki, co znacznie skraca czas deployu.
Kluczowe kroki konfiguracji:
- Wygeneruj dedykowaną parę kluczy SSH:
ssh-keygen -t ed25519 -C "github-actions" - Klucz publiczny dodaj do
~/.ssh/authorized_keysna serwerze - Klucz prywatny zapisz jako GitHub Secret:
VPS_SSH_KEY - Dodaj sekrety
VPS_HOST(adres IP lub domena) iVPS_USER(nazwa użytkownika)
Sekrety w GitHub Actions to zaszyfrowane zmienne środowiskowe – nigdy nie pojawiają się w logach ani w kodzie. Dodajesz je w Settings > Secrets and variables > Actions w repozytorium.
Wdrażanie na Vercel
Dla projektów Next.js Vercel oferuje natywną integrację z GitHub – po połączeniu repozytoriów każdy push automatycznie wyzwala deploy. Bez żadnej konfiguracji YAML. Szczegóły w dokumentacji Vercel Deployments.
Jeśli jednak chcesz mieć pełną kontrolę lub wdrażać na Vercel z własnego workflow:
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.ORG_ID }}
vercel-project-id: ${{ secrets.PROJECT_ID }}
vercel-args: '--prod'
Zmienne środowiskowe i sekrety
Aplikacje Next.js często wymagają zmiennych środowiskowych – kluczy API, connection strings do bazy danych, kluczy Stripe. Nigdy nie trzymaj ich w kodzie. GitHub Actions daje do dyspozycji kilka poziomów sekretów:
- Repository secrets – dostępne dla jednego repozytorium
- Environment secrets – osobne zestawy dla staging/production
- Organization secrets – współdzielone między repozytoriami w organizacji
W kroku buildu przekaż je przez env::
- name: Build
run: npm run build
env:
NEXT_PUBLIC_API_URL: ${{ secrets.API_URL }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
Branch protection rules i preview deployments
Jedną z największych zalet CI/CD jest możliwość wymuszenia jakości kodu przed mergem do głównej gałęzi. W Settings > Branches > Branch protection rules możesz wymagać, żeby wszystkie checksy CI przeszły zanim ktokolwiek będzie mógł zmergować Pull Request.
Preview deployments to automatyczne wdrożenia każdego Pull Requesta na tymczasowy URL. Zamiast opisywać recenzentowi, jak lokalnie uruchomić zmiany, dajesz mu gotowy link. Vercel i Netlify robią to natywnie. Na własnym VPS możesz to zrealizować przez dynamiczne porty i Nginx.
Cache node_modules – przyspiesz buildy
Instalacja zależności to jedna z najwolniejszych operacji w pipeline. Akcja actions/setup-node@v4 z parametrem cache: 'npm' automatycznie cachuje folder ~/.npm między uruchomieniami. Dla projektu z setkami zależności to różnica między 5-minutowym a 1-minutowym buildem.
Możesz też ręcznie cachować katalog .next/cache:
- name: Cache Next.js build
uses: actions/cache@v4
with:
path: .next/cache
key: nextjs-${{ hashFiles('package-lock.json') }}-${{ hashFiles('**/*.ts','**/*.tsx') }}
Powiadomienia o błędach – Slack i email
Gdy deployment się nie powiedzie, chcesz wiedzieć o tym natychmiast. GitHub Actions pozwala dodać krok uruchamiany tylko przy niepowodzeniu (if: failure()):
- name: Notify Slack on failure
if: failure()
uses: slackapi/slack-github-action@v1.27.0
with:
channel-id: 'deployments'
slack-message: "Deployment FAILED on ${{ github.repository }} - ${{ github.sha }}"
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
Alternatywnie możesz używać powiadomień email przez SendGrid lub prostego webhooka.
Alternatywy dla GitHub Actions
GitHub Actions to popularny wybór, ale nie jedyny:
- GitLab CI/CD – wbudowane w GitLab, bardziej rozbudowane zarządzanie środowiskami, darmowe 400 minut/miesiąc w cloud
- Jenkins – open source, self-hosted, nieograniczone buildy, ale wymaga administracji serwerem
- CircleCI – dobra integracja z Docker, darmowy tier 6000 minut/miesiąc
- Bitbucket Pipelines – jeśli trzymasz kod na Bitbucket, natywna integracja z Jira
Dla małych agencji i freelancerów GitHub Actions w połączeniu z darmowym tierem (2000 minut/miesiąc) to zwykle więcej niż wystarczające. Przy wielu projektach warto rozważyć self-hosted runner na VPS, który uruchamia buildy bez limitu minut.
Wersjonowanie semantyczne w CI/CD
Dobrą praktyką jest tagowanie każdego wdrożenia produkcyjnego według Semantic Versioning (semver.org). Format MAJOR.MINOR.PATCH pozwala szybko zrozumieć zakres zmiany i ułatwia rollback do poprzedniej wersji.
W GitHub Actions możesz automatycznie tworzyć tagi i GitHub Releases przy każdym mergu do main:
- name: Create Release
uses: googleapis/release-please-action@v4
with:
release-type: node
Podsumowanie – czy CI/CD jest dla ciebie?
Jeśli zarządzasz stroną internetową lub aplikacją, która jest regularnie aktualizowana – odpowiedź brzmi: zdecydowanie tak. Nawet prosta konfiguracja lint + build + deploy przez rsync skróci czas wdrożeń z 15-30 minut do 2-3 minut i wyeliminuje błędy wynikające z ręcznej pracy.
Koszty? Dla projektów na GitHub darmowy tier 2000 minut/miesiąc pozwoli obsłużyć kilkanaście wdrożeń dziennie bez żadnych opłat. Self-hosted runner na VPS za kilkadziesiąt złotych miesięcznie to rozwiązanie bez limitu minut dla bardziej intensywnych projektów.
Chcesz, żebyśmy skonfigurowali CI/CD dla twojego projektu? Skontaktuj się z nami – pomożemy zaprojektować cały pipeline dopasowany do twojego stack’u i wymagań.

