Denne guiden beskriver dynamisk hosting på VPS for Norscode-nettsider, med deploy-bruker, Nginx for flere domener, DNS-oppsett, GitHub Actions, HTTPS med Let's Encrypt og en konkret produksjonssjekkliste.
Deploy er ikke bare det øyeblikket ny kode havner på en server. Det er hele overgangen fra lokal eller CI-verifisert kode til faktisk trafikk i produksjon. Når deploy-flyten er tydelig, blir release mindre stressende, rollback raskere og driftsfeil lettere å forstå. Når deploy-flyten er uklar, blir selv små endringer mer risikable enn de trenger å være.
Målet med en god deploy-prosess er forutsigbarhet. Teamet bør vite hva som bygges, hva som blir lastet opp, hvordan ny release aktiveres, hvordan den verifiseres og hvordan man går tilbake hvis noe oppfører seg feil. Hvis noen av disse stegene er uklare, blir produksjonssetting mer personavhengig og vanskeligere å stole på.
Det betyr også at deploy og drift henger tett sammen. En release er ikke ferdig når filene ligger på serveren. Den er ferdig når tjenesten svarer riktig, helse-endepunkter er grønne, kritiske flyter virker, og teamet vet hvordan de vil reagere hvis noe ser galt ut i minuttene etterpå.
Bruk to ulike brukere på serveren: en deploy-bruker for SSH og opplasting, og en låst systembruker som faktisk kjører applikasjonen.
Brukes av GitHub Actions eller manuell deploy via SSH. Den skal eie release-mappene og kunne restarte tjenesten via sudo.
sudo adduser deploy
sudo usermod -aG sudo deploy
Brukeren norscode kjører selve appen uten shell og uten innloggingsrettigheter.
sudo useradd --system --home /opt/norscode --shell /usr/sbin/nologin norscode
Dette skillet er nyttig fordi deploy-arbeid og drift av selve prosessen er to ulike ansvar. Deploy-brukeren trenger nok tilgang til å levere nye releases og peke current til riktig katalog. Service-brukeren trenger bare å kjøre applikasjonen. Jo tydeligere dette skillet er, jo mindre blir skaden hvis én del av kjeden får for brede rettigheter.
Nginx bør terminere trafikken på 80 og 443, redirecte til HTTPS og videresende til applikasjonen på intern port. Ett oppsett kan håndtere hoveddomene, www og ekstra aliaser.
server_name norscode.no www.norscode.no app.norscode.no api.norscode.no;
Tips: hold all proxy-logikk i én site-fil så det er enkelt å se hvilke domener som faktisk peker på samme applikasjon.
Nginx blir ofte den første linjen i både tilgjengelighet og feilsøking. Hvis proxy-oppsettet er ryddig, er det lettere å se om problemet ligger i sertifikat, routing, upstream-port eller selve applikasjonen. Hvis oppsettet er spredt eller uoversiktlig, blir enkle nettverksfeil fort tyngre å avklare.
A-record for hoveddomene til VPS-IP.A-record for www og eventuelle subdomener.certbot.dig norscode.no
dig www.norscode.no
DNS virker enkelt når alt er satt opp, men er ofte en kilde til forvirring under første release eller ved flytting av miljø. Feil IP, gammel cache eller inkonsistente records kan få det til å se ut som appen er nede, selv om problemet egentlig ligger i ruten fram til serveren.
Derfor er det lurt å behandle DNS som en del av deploy-verifiseringen, ikke bare som en engangsjobb. Sjekk at domenet faktisk peker dit du forventer før du går videre til HTTPS og health-verifisering.
Det følger med to workflows: én for enkelt-repo og én for monorepo. Begge laster opp ny release med rsync, peker current til riktig katalog og restarter systemd-tjenesten.
Bruk .github/workflows/deploy.yml når hele repoet er nettstedet som skal deployes.
Bruk .github/workflows/deploy-monorepo.yml når nettstedet ligger i en undermappe og bare skal deployes når den delen endres.
WEBSITE_SSH_HOST
WEBSITE_SSH_PORT
WEBSITE_SSH_USER
WEBSITE_SSH_PRIVATE_KEY
CI-basert deploy er verdifull fordi den gjør release-rekkefølgen repeterbar. I stedet for manuelle steg som lett blir glemt, får du en fast flyt for opplasting, aktivering og restart. Det gjør også at teamet lettere kan se hvilken versjon som faktisk ble rullet ut og når det skjedde.
Jo mer av deploy-flyten som er eksplisitt i workflowen, jo mindre personavhengig blir den. Det er en stor fordel når flere jobber i samme repo, eller når man må gjøre raske hotfixer uten å være avhengig av én bestemt person sin hukommelse.
Når DNS peker til riktig server kan du aktivere sertifikater direkte gjennom Nginx-oppsettet. Installeringsscriptet støtter både hoveddomene, www og ekstra domener.
sudo DOMAIN=norscode.no \
WWW_DOMAIN=www.norscode.no \
ADDITIONAL_SERVER_NAMES="app.norscode.no api.norscode.no" \
ENABLE_SSL=1 \
bash install.sh
HTTPS er en del av både sikkerhet og driftskvalitet. Et sertifikat som ikke utstedes, ikke fornyes eller er knyttet til feil domene, vil ofte være det første brukeren merker. Derfor bør sertifikathåndtering være en normal del av miljøoppsettet, ikke noe som “ordnes senere”.
En deploy bør alltid ha en kort og konkret verifiseringsrunde etter at ny release er aktivert.
/healthz svarerDette steget er viktig fordi mange release-feil først blir synlige etter at prosessen faktisk kjører med ekte konfigurasjon og ekte proxy-lag. En rask verifisering rett etter deploy reduserer tiden fra feil til oppdagelse betraktelig.
systemctl status norscode-website først.journalctl -u norscode-website -n 200 --no-pager.nginx -t.Det er nyttig å feilsøke i lag. Først: kjører prosessen? Deretter: svarer lokal port? Deretter: fungerer proxy? Til slutt: peker DNS og HTTPS riktig? Når du holder denne rekkefølgen, unngår du å feilsøke i feil ende av kjeden.
En god deploy-prosess er ikke komplett uten en enkel vei tilbake. Hvis ny release ser feil ut, bør teamet raskt kunne peke tilbake til forrige versjon uten å improvisere midt i en hendelse.
Det er derfor nyttig å tenke i releases, ikke bare i filer som overskrives. Når hver release ligger i egen katalog og current peker på aktiv versjon, blir rollback ofte et lite og kontrollerbart steg i stedet for et manuelt gjenopprettingsprosjekt.
/healthz svarer både lokalt og via HTTPS.current til forrige release.Denne sjekklisten er verdifull fordi den flytter deploy fra “det så greit ut” til “vi har faktisk bekreftet de viktigste tingene”. Over tid kan listen utvides med egne krav, for eksempel integrasjoner, cache-varming, backup-kontroll eller staging-signoff.
De fleste deploy-problemer handler ikke om at koden er helt ødelagt. De handler om overganger mellom bygg, miljø, proxy, hemmeligheter og drift. Derfor er det så nyttig å ha en fast deploy-modell som dekker hele kjeden.
Når basisdeployen sitter, er neste naturlige steg bedre observability, tydeligere release-notater og eventuelt staging-miljø med samme Nginx- og DNS-prinsipper.