CI/CD for WordPress: automatiser dine utrullinger i 2026

CI/CD for WordPress: automatiser dine utrullinger i 2026

Sist verifisert: 22. september 2026
7 min lesetid
Guide
Full-stack-utvikler

Å dra temafiler over FTP i 2026 ender vanligvis likt: én fil fra inc/ mangler, composer.lock kom fra en annen laptop, og produksjon ligger nede fordi noen overskrev wp-config.php. Continuous Integration og Continuous Deployment er ikke enterprise-teater - det er måten hver Git-endring går gjennom samme bygg, samme tester og samme vei inn på serveren.

Denne guiden gjelder WordPress med tema eller plugin i repoet (Composer, npm, eventuelt Docker), ikke nettsteder som bare lever i admin. Hvis egendefinert kode fortsatt bare finnes i database og media, flytt temaer og custom code til Git først - uten det har CI/CD ingenting å bygge.

Dokumentasjon for runners: GitHub Actions. Les også parallelt: Hardening WordPress. For kommandoer etter deploy: WP-CLI.

#Hvorfor FTP og «bare last opp» feiler i revisjoner

Tre problemer dukker opp igjen i norske nettbutikker og byråoverleveringer:

  1. Miljødrift - lokalt PHP 8.2 og Composer 2.7, VPS på PHP 8.1 uten intl. Lokal composer install «fungerer»; produksjon dør på class not found.
  2. Ingen revisjonsspor - etter en hendelse kan du ikke si hvilken commit som var live. Hostingpanelet viser en fildato, ikke en Git-SHA.
  3. Hemmeligheter på disk - SFTP-passord i FileZilla, eller en .env committed «bare et øyeblikk», er fortsatt klassisk lekkasjevei - særlig når persondata under GDPR ligger i staging-kopier.

CI/CD fikser dette mekanisk: bygg på kjent image (shivammathur/setup-php eller egen Docker), versjoner artefakt etter SHA, deploy over SSH med nøkkel i Secrets.

#Minimal pipeline: push, bygg, test, deploy

Typisk arbeidsflyt for custom-tema pluss Composer-plugins:

  1. Trigger - push til main eller merge av gjennomgått pull request. develop går ofte bare til staging.
  2. Bygg - composer install --no-dev --optimize-autoloader, npm ci, npm run build. Pin PHP og Node i workflow (php-version: '8.2', node-version: '20').
  3. Test - PHPUnit for plugins, eventuelt Playwright på checkout. Fail stopper jobben; ingen deploy.
  4. Artefakt - pakk release uten .git, uten node_modules, med vendor/ og bygd assets/dist/.
  5. Deploy - rsync/SCP til releases/<run_id>/, deretter atomisk symlink-bytte.

Kort skisse i GitHub Actions:

name: deploy-production
on:
  push:
    branches: [main]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
      - run: composer install --no-dev --optimize-autoloader
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: npm
      - run: npm ci && npm run build
      - name: rsync release
        env:
          SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
        run: |
          # skriv nøkkel, rsync til releases/$GITHUB_SHA, ln -sfn

Full symlink-script ligger i repoet som bin/release.sh - workflowen kaller bare. Samme script fungerer fra laptop når Actions er nede.

#Atomiske deploys i stedet for å overskrive filer

Å overskrive filer «på plass» under public_html betyr at noen requests i noen sekunder ser gammel functions.php og ny template. I WooCommerce under Black Friday-kampanjer kan det ødelegge handlekurvsesjoner.

Atomisk oppsett:

  • base: /var/www/site/
  • releases: /var/www/site/releases/20260920-142211/
  • shared: uploads, wp-config.php, object cache - utenfor releasen
  • current → symlink til aktiv release

Etter vellykket rsync:

ln -sfn /var/www/site/releases/20260920-142211 /var/www/site/current

Nginx root peker på .../current/public (eller tilsvarende). Byttene er umiddelbare. Slett gamle releases etter N dager, eller behold de tre siste for rollback.

WordPress-uploads må ligge utenfor releasen - ellers sletter hver deploy media eller kopierer gigabytes. Klassisk mønster: shared/uploads linket inn i wp-content/uploads i hver release.

#Staging, forhåndsvisning og strategimatrise

I 2026 er feature branch → PR → staging → main/produksjon ikke valgfritt for butikker og lead-sider. Staging bør ha:

  • samme PHP-versjon og utvidelser som produksjon
  • databasekopi (anonymisert når persondata er i spill under GDPR)
  • betalinghemmeligheter kun i sandbox

Preview-URL per PR hjelper redesign og CSS mer enn skjemamigrasjoner - de trenger fortsatt staging med ekte dump.

StrategiRisikoVedlikeholdNår det passer
Manuell FTPSvært høyBillig start, dyre bruddBare sandbox / læring
Git-hook på serverMiddelsLavLite portfolio, én utvikler
CI + atomisk rsyncLavMiddelsBedrift, WooCommerce, byrå
Blue/green eller to VPSMinimalHøyHøy trafikk, SLA, betalinger

Blue/green (to fulle miljøer, load balancer-bytte) lønner sjelden under hundrevis av samtidige sesjoner. De fleste norske nettbutikker klarer seg med atomisk symlink pluss mappe-rollback - typisk på Hetzner, Linode eller managed med SSH. Vipps-sandbox i staging og ekte Vipps-nøkler bare i produksjons-Secrets er et mønster som sparer mange feilaktige testkjøp.

#Hemmeligheter, WP-CLI og database

Aldri commit:

  • SSH-nøkler
  • databasepassord
  • AUTH_KEY / SECURE_AUTH_KEY fra wp-config.php
  • API-tokens for betalingsgateways (Vipps, Klarna, Stripe)

I GitHub: Settings → Secrets and variables → Actions. Injiser som env i deploy-steget. På serveren ligger wp-config.php under shared/ og er ikke del av CI-artefakten.

WP-CLI etter symlink-bytte:

  • wp cache flush ved object cache
  • wp rewrite flush etter CPT-endringer
  • wp plugin list som smoke-linje i loggen

Planlegg databasmigrasjoner adskilt fra fil-deploy. Symlink-rollback angrer ikke ALTER TABLE. Ved destruktive migrasjoner: backup først (wp db export på staging og produksjon), deretter migrasjon, deretter trafikk til kode som trenger skjemaet - eller feature-flag i PHP.

PHP-avhengigheter: Composer install - i CI alltid --no-dev for produksjon og låst composer.lock.

#Hva som vanligvis knuser den første WordPress-pipelinen

Fra VPS-arbeid (Hetzner, DigitalOcean, OVH) og managed med SSH:

  • .gitignore spiser vendor/ - produksjon får tema uten autoloader. Enten bygg vendor på runneren og legg den i artefakten, eller kjør Composer på serveren etter rsync (da trenger serveren Composer og Packagist-tilgang).
  • Feil stier - scriptet antar /var/www/html, hosten bruker /home/user/domains/.... Pin stier i Secrets per miljø.
  • Opcache holder gammel kode - etter ln -sfn, reload PHP-FPM eller kall opcache_reset via WP-CLI/mu-plugin bare for deploy-brukeren.
  • Cron og køer - WooCommerce Action Scheduler kan kjøre jobber på gammel kode i noen minutter; etter store releases, se litt på failed jobs.

Smoke-test etter deploy (curl fra runner eller egen jobb):

  • forsiden HTTP 200
  • /wp-login.php 200
  • én kritisk produkt- eller skjemalanding
  • valgfri HEAD til CDN hvis assets er content-hashed

Hvis smoke feiler, er automatisk symlink-rollback billigere enn kundeoppringing kl. 23:00.

#Blokk-temaer, must-use-plugins og Git-unntak

Ikke hele WordPress passer i samme pipeline. Innhold i databasen (innlegg, ACF-feltgrupper uten JSON-eksport, Elementor-CSS) lever fortsatt utenfor releasen. CI/CD beskytter kode; det erstatter ikke databasebackup.

Praktiske skiller:

  • Klassisk eller hybrid-tema med Vite - fullt CI-bygg, artefakt med style.css + dist/.
  • Blokk-tema (FSE) - hold theme.json og HTML-maler i Git; endringer fra Site Editor tilbake via PR, ellers divergerer produksjon og Git etter første «Lagre».
  • Must-use-plugins - rulles ut med releasen; oppdater dem ikke fra admin. Bra sted for deploy-healthchecks og å slå av file editor.
  • Plugins fra wordpress.org - pin versjoner via Composer (wpackagist) eller oppdater i en gjennomgått jobb. Å blande «Update i admin» med «CI overskrev plugins/» gir et tilfeldig plugin-tre.

Byrå-stacks i Norden blander ofte custom-tema, WooCommerce fra wpackagist og to premium-zip via Composer path repository. Pipelinen må kjenne alle tre kilder, ellers skiller staging og produksjon seg med én zip fra for et halvt år siden.

#Sjekkliste før første Actions-deploy

Før du kobler main til produksjon, gå gjennom listen én gang - den sparer en helg:

  1. Privat repo, eller bekreft historikk uten hemmeligheter (git log -p viser ingen gamle .env).
  2. Branch protection: obligatorisk PR, grønn test-workflow.
  3. Separate Secrets: DEPLOY_HOST_STAGING, DEPLOY_HOST_PROD, egne SSH-nøkler.
  4. Staging matcher produksjonens PHP (ikke «vi kjører 8.3, kunden har 8.1»).
  5. Databasebackup før første atomiske bytte - selv når kode-rollback er klar.
  6. Oppetidsovervåking (UptimeRobot, Better Stack e.l.) med SMS/Slack på produksjons-URL.
  7. Én-siders runbook: hvordan ln -sfn manuelt til forrige release, hvem har servertilgang.

Først da: auto-deploy fra main. Fram til da holder «bygg + test» på PR-er og manuell workflow_dispatch til staging.

#Oppsummering

CI/CD for WordPress er ikke «magisk YAML». Det er en gjentakbar kontrakt: samme PHP, samme lockfile, samme artefakt, bytte uten vindu med halvveis opplastede filer. Start med Git og staging, legg til Actions for Composer/npm-bygg, avslutt med atomisk current og smoke-test. FTP blir nødverktøy, ikke prosess.

Trenger du en WordPress-utvikler som holder pipelinen sammen med temakoden for butikk eller lead-side, jobber WPPoland på ekte stack - ikke lysark.

Neste steg

Gjør artikkelen om til faktisk implementering

Denne blokken styrker intern lenking og sender leseren videre til de mest relevante tjenestene og innholdet.

Vil du få dette implementert på nettstedet ditt?

Hvis du vil gjøre kunnskapen i artikkelen om til konkrete forbedringer, redesign eller en tydelig leveranseplan, kan jeg ta det videre.

Relevant klynge

Utforsk andre WordPress-tjenester og kunnskapsbase

Styrk virksomheten din med profesjonell teknisk støtte innen kjerneområdene i WordPress-økosystemet.

Artikkel-FAQ

Ofte stilte spørsmål

Praktiske svar for å bruke temaet i faktisk arbeid.

SEO-readyGEO-readyAEO-ready5 Q&A
Gir CI/CD mening for en solo-frilanser?#
Ja. Aleneutviklere taper mest på en glemt PHP-fil eller et composer.lock bygget på en annen PHP-versjon. Pipelinen tvinger samme bygg på hver commit og etterlater en reviderbar logg over hvilken SHA som gikk live.
Hva er zero-downtime-deployment i WordPress?#
Ny kode lander i releases/. Først etter vellykket rsync og eventuelt wp cache flush bytter du symlinken current. PHP-FPM eller Nginx serverer via current, så byttet tar millisekunder og trenger ikke vedlikeholdsmodus.
Trenger jeg VPS for CI/CD?#
VPS eller containere gir full kontroll (SSH, symlinker, WP-CLI). På managed hosting står ofte en deploy-API eller SFTP med nøkkel i Secrets igjen - fortsatt bedre enn manuell FileZilla, selv uten ekte blue/green.
Hva gjør jeg hvis deployen feiler?#
Behold N tidligere release-mapper. Hvis smoke-testen returnerer 500 eller vendor/ mangler, pek symlinken tilbake på forrige release. Planlegg databasmigrasjoner separat - kode-rollback angre ikke ALTER TABLE.
Hvor skal temaer med Vite eller webpack bygges?#
På CI-runneren: checkout, sett opp Node, npm ci, npm run build, pakk deretter dist/ inn i artefakten sammen med PHP. Send ikke node_modules eller TypeScript-kilder til produksjon - bare kompilert CSS/JS.

Trenger du FAQ tilpasset bransje og marked? Vi lager en versjon som støtter dine forretningsmål.

Ta kontakt

Relaterte artikler