eduardweb.
DevOps & VPSIntermediar#nextjs#devops#pm2#vps#github-actions

GitHub Actions pentru Next.js: Pipeline complet de la lint la deploy pe VPS

De Mihai Popescu, 29 iun. 2026 · 17 vizualizări · 2 like-uri

Postat 29 iun. 2026
yaml
name: CI/CD Pipeline

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install pnpm
        uses: pnpm/action-setup@v3
        with:
          version: 8

      - name: Get pnpm store directory
        shell: bash
        run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV

      - uses: actions/cache@v4
        with:
          path: |
            ${{ env.STORE_PATH }}
            ${{ github.workspace }}/.next/cache
          key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }}
          restore-keys: |
            ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-

      - name: Install dependencies
        run: pnpm install --frozen-lockfile

      - name: Lint and Test
        run: |
          pnpm lint
          pnpm test

      - name: Build project
        run: pnpm build

      - name: Compress build files
        run: tar -czf release.tar.gz .next public package.json pnpm-lock.yaml next.config.js

      - name: Copy files to VPS via SSH
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          source: "release.tar.gz"
          target: "/var/www/my-app"

      - name: Deploy and Reload on VPS
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            cd /var/www/my-app
            tar -xzf release.tar.gz
            pnpm install --prod --frozen-lockfile
            pm2 reload my-next-app || pm2 start npm --name "my-next-app" -- start
            rm release.tar.gz

Să fim serioși, Vercel e genial până când începe să te coste peste 100 de dolari pe lună din cauza traficului sau a limitelor de execuție pe serverless functions. Am mutat recent o aplicație Next.js cu 15.000 de utilizatori unici pe lună de pe Vercel pe un VPS de 6 euro de la Hetzner. Pipeline-ul de CI/CD pe care l-am configurat ne salvează zilnic timp și nervi. În postarea asta vă arăt cum am legat totul: lint, teste, build și deploy automat direct pe VPS prin SSH.

De ce VPS și unde e capcana?

Să treci de la Vercel la VPS vine cu un trade-off major. Pe Vercel ai zero-configuration și edge routing nativ. Pe un VPS curat trebuie să te ocupi singur de reverse proxy (Nginx sau Caddy), de SSL (Certbot) și de menținerea procesului Node în viață folosind PM2.

Dar din punct de vedere financiar și al controlului, diferența e uriașă. Am trecut de la costuri variabile și destul de mari la o factură fixă de câțiva euro. Pentru a păstra aceeași experiență simplă de "push to deploy", avem nevoie de un pipeline solid în GitHub Actions.

Optimizarea build-ului: Cum am economisit 40% din timp

Cea mai mare greșeală pe care o văd în workflow-urile de CI/CD este lipsa cache-ului. Next.js folosește un cache intern foarte agresiv în .next/cache pentru pagini și imagini compilate. Dacă nu salvezi acest folder între rulările din GitHub Actions, fiecare build va fi un "cold build", iar timpul tău de rulare va depăși 6 minute.

Folosind actions/cache împreună cu cache-ul nativ pentru managerul de pachete (pnpm în cazul meu), am redus timpul de build de la 5 minute și jumătate la doar 2 minute și 10 secunde. La 20 de deploy-uri pe săptămână, asta înseamnă ore bune de CI economisite lunar.

Strategia de deploy: Build local în CI sau build direct pe server?

Aici ai două variante mari. Prima: trimiți codul sursă pe VPS și rulezi next build direct acolo. A doua: faci build-ul în GitHub Actions, arhivezi folderul .next și fișierele necesare, le trimiți pe VPS și doar le dezarhivezi.

Eu o recomand clar pe a doua. Dacă rulezi next build pe un VPS ieftin cu 1-2 GB de RAM, procesul de compilare o să îți mănânce toate resursele de CPU și memorie. Site-ul tău va fi complet inaccesibil (freeze total) timp de un minut sau două în timpul build-ului. Făcând build-ul în GitHub Actions, serverul tău doar primește fișierele gata compilate și le înlocuiește instant.

Cum funcționează deploy-ul pe server

Pe VPS, folosesc PM2 pentru a rula procesul de Node.js. Când arhiva gata construită ajunge pe server prin SCP, o dezarhivăm într-un folder temporar, rulăm un script de swap rapid și dăm un pm2 reload. Folosirea comenzii reload în loc de restart asigură zero-downtime real, deoarece PM2 reîncarcă procesele pe rând, fără să oprească complet serverul web.

Cum faceți voi deploy-ul la Next.js când vreți să evitați prețurile de Vercel? Mergeți pe Docker sau direct pe OS cu PM2?

Răspunsuri 0

Se încarcă răspunsurile…

Loghează-te pentru a răspunde

Doar membrii comunității pot lăsa comentarii.