Udgivelse og stabil drift

Miljøvariabler og appkonfiguration: undgå fejl i produktion

En app kan bygge uden fejl og stadig bruge testdatabasen, en forkert API-adresse eller teksten “false” som en sand værdi. Problemet er sjældent selve miljøvariablen. Det er manglen på en tydelig kontrakt for hvilke værdier appen kræver, hvornår de bliver læst, hvem der må ændre dem, og hvordan en dårlig ændring rulles tilbage.

Udgivet 3. oktober 2026 · Ca. 11 minutters læsetid

Det korte svar

Lav et register over nødvendig konfiguration, adskil offentlige værdier fra secrets, validér typer og sammenhænge før appen tager imod trafik, og bind hver ændring til et bestemt miljø og en kendt release. Test den byggede app med produktionslignende konfiguration uden produktionsdata, kontrollér live-målet efter deployment, og hav en afprøvet vej tilbage til sidste kendte konfiguration.

En variabel findes ikke bare, fordi den findes lokalt. Browser-build, serverruntime, baggrundsjob og deployment-pipeline kan læse værdier på forskellige tidspunkter og fra forskellige scopes. Bevis det for den konkrete stack.

Skeln mellem fire slags indstillinger

Alt bør ikke ligge i samme .env-fil. Placering, adgang og ændringsflow afhænger af, hvad værdien gør, og hvem der må kende den.

TypeEksempelPraktisk regel
Offentlig klientkonfigurationAPI-base-URL, offentligt projekt-idMå kunne ses i browseren, men skal stadig pege på det rigtige miljø
ServerkonfigurationRegion, timeout, kønavn, tilladt originValidér ved opstart eller deployment og giv kun relevante services adgang
SecretDatabaseadgang, API-token, privat nøgleBrug platformens secret-løsning eller identitetsbaseret adgang; læg den ikke i klienten
ForretningsdataPris, åbningstid, kundens grænseGem som validerede data med ejer og historik, når brugere skal kunne ændre værdien

Et feature flag er en særskilt driftsmekanisme med standardværdi, målgruppe og oprydning. En almindelig variabel bør ikke langsomt blive til et skjult administrationssystem uden adgangskontrol og historik.

Lav en kontrakt for hver nødvendig værdi

Et navn som API_URL fortæller ikke, om værdien er obligatorisk, offentlig eller bundet til buildet. Registrér kun metadata og ufarlige eksempler – aldrig aktive secrets.

Navn og formål
Hvilken funktion læser værdien, og hvad sker der, hvis den mangler?
Type og regler
URL, heltal, boolean, liste eller enum samt tilladt interval og indbyrdes krav.
Tidspunkt
Læsning ved build, deployment, opstart eller for hvert request – og om ændring kræver nyt build eller genstart.
Miljø og scope
Lokal, preview, test eller produktion samt frontend, backend, job eller pipeline.
Ejer og tilbagevej
Hvem godkender ændringen, hvor ses historikken, og hvilken kendt værdi kan gendannes?

En værdiløs skabelon som .env.example kan dokumentere navne og kommentarer til lokal udvikling. Produktionsværdiernes egentlige kilde kan være hostingplatformen, et konfigurationslager eller deployment-pipelinen.

Find ud af, hvornår værdien bliver låst

I en klientbygget frontend bliver mange værdier skrevet ind i de færdige filer under build. Vite erstatter frontendens miljøværdier statisk, og værdier med præfikset VITE_ bliver eksponeret i klientkoden. En ændring i hostingens miljø efter build ændrer derfor ikke nødvendigvis den allerede byggede frontend.

  • Build-time: Værdien bliver del af artefaktet. Et nyt mål kan kræve et nyt build.
  • Runtime: Serveren eller funktionen læser værdien, når processen starter eller requestet behandles.
  • Ekstern konfiguration: Appen henter værdien fra en tjeneste og skal have en plan for cache, timeout og senest kendte gode version.
  • Pipeline: GitHub variables er til ikke-følsom konfiguration og vises ikke maskeret som standard i buildoutput; secrets skal behandles særskilt.
Læs ikke miljønavnet som sikkerhedsbevis. En variabel med værdien “production” garanterer ikke, at database, storage, OAuth og mailudbyder faktisk er produktionsressourcer. Kontrollér de konkrete ressource-id'er og ufarlige mål efter deployment.

Validér før appen tager imod rigtige handlinger

Miljøvariabler er som udgangspunkt tekst. Node.js dokumenterer eksempelvis, at værdier fra .env fortolkes som tekst, også når de ligner tal eller booleans. Konvertér og validér derfor eksplicit i ét samlet lag.

  • Afvis manglende kernekonfiguration. En backend uden databaseadresse bør stoppe tydeligt frem for at acceptere trafik og fejle senere.
  • Parse typen. Teksten “false” er ikke automatisk en falsk boolean, og “30” er ikke automatisk et valideret antal sekunder.
  • Kontrollér interval og format. En URL kan være syntaktisk gyldig og stadig pege på et forkert eller usikkert mål.
  • Validér sammenhænge. Produktionsmodus, databaseprojekt, OAuth-callback og maildomæne skal tilhøre samme tilsigtede miljø.
  • Log navne og resultat – ikke værdier. En fejl må gerne sige, at en variabel er ugyldig, men må ikke udskrive tokenet eller forbindelsesstrengen.

Firebase tilbyder parameterstyret konfiguration, som kan typekontrolleres og blokere deployment ved manglende eller ugyldige værdier. Andre stacks kræver deres eget valideringslag. Brug mekanismen, der passer til projektet; princippet er et bevis før drift.

Vælg en sikker fejltilstand

En standardværdi er kode, der vælger adfærd under usikkerhed. Den må derfor vurderes efter konsekvens – ikke efter hvad der får appen til at starte hurtigst.

Stop tydeligt

Bruges når ukendt database, tenant, betalingsmål eller adgangsregel kan give datalæk, tab eller forkerte handlinger.

Slå en afgrænset funktion fra

Kan være forsvarligt for en valgfri integration, hvis resten af appen virker sikkert, og fraværet er synligt og overvåget.

  • Fallback må aldrig være en hardkodet produktionsadresse i udvikling eller preview.
  • En ukendt adgangs- eller sikkerhedsindstilling bør ikke åbne bredere adgang.
  • En deaktiveret funktion skal give brugeren ærlig status og ikke lade som om arbejdet blev gemt.
  • Health checks skal kunne vise, at konfigurationen er gyldig, uden at afsløre de konkrete værdier.

Behandl en konfigurationsændring som en release

En ændret timeout, origin eller API-adresse kan påvirke driften uden en eneste ny kodelinje. Ændringen skal derfor have ejer, review, test, historik og rollback på linje med en almindelig release.

  1. Afgræns diffen. Vis hvilke navne og scopes der ændres uden at kopiere secret-værdier ind i ticket eller log.
  2. Validér i et isoleret miljø. Kør startup-kontrol og den funktion, som bruger indstillingen.
  3. Udgiv kontrolleret. Undgå samtidige kode- og konfigurationsændringer, hvis de ikke behøver at være koblet.
  4. Kør et live smoke test. Bekræft miljø-id, build-id og ufarlige integrationer samt relevante fejl- og driftsmålinger.
  5. Bevar en kendt god version. Cloud Run binder konfiguration til revisionsversioner, mens Azure App Configuration kan bruge uforanderlige snapshots; andre platforme har andre modeller.

Et rollback af kode gendanner ikke nødvendigvis konfiguration. Skriv derfor ned, om rollback betyder genudgivelse af et artefakt, valg af en tidligere revision, skift af snapshot eller manuel gendannelse af konkrete indstillinger.

Typiske fejl

  • “false” behandles som sand: Tekstværdien bliver aldrig konverteret til en rigtig boolean.
  • VITE_SECRET ser privat ud: Præfikset lægger værdien i browserens build, hvor brugeren kan læse den.
  • Preview bruger produktion: En manglende værdi falder tilbage til en hardkodet database- eller API-adresse.
  • Portalen er dokumentationen: Ingen kan se nødvendige navne, scope, ejer eller ændringsårsag uden bred administratoradgang.
  • Alle variabler deles globalt: Et job eller repository får værdier, som det aldrig bruger.
  • Ændring antages at være live: Værdien var bundet ved build eller opstart og kræver nyt build, revision eller genstart.
  • Hele miljøet logges: Fejlsøgning kopierer secrets, tokens og forbindelsesstrenge til logs.

Tjekliste før medarbejdere eller kunder bruger appen

  • ☐ Nødvendige værdier er registreret med formål, type, scope, ejer og læsetidspunkt.
  • ☐ Offentlig klientkonfiguration, serverkonfiguration, secrets og forretningsdata er adskilt.
  • ☐ Frontendværdier er kontrolleret i det byggede artefakt og indeholder ingen secrets.
  • ☐ Obligatoriske værdier og indbyrdes miljøkrav valideres før rigtig trafik.
  • ☐ Tal, booleans, URL'er, lister og intervaller bliver konverteret og valideret eksplicit.
  • ☐ Manglende eller ugyldig konfiguration giver en bevidst, sikker fejltilstand.
  • ☐ Lokal, preview, test og produktion peger på deres egne ressourcer og data.
  • ☐ Pipeline, frontend, backend og jobs får kun de værdier, de faktisk behøver.
  • ☐ En ændring kan spores uden at udskrive følsomme værdier.
  • ☐ Live smoke test bekræfter miljø, release og kritiske integrationer.
  • ☐ Sidste kendte gode konfiguration kan gendannes uafhængigt af kode-rollback.
  • ☐ Runbooken forklarer ændring, verifikation og tilbagevej for den valgte platform.

Relaterede guides

Officielle kilder

Konfiguration læses og versionsstyres forskelligt på tværs af frontendværktøjer, serverruntimes og cloudplatforme. Fakta og eksempler her er verificeret mod aktuelle officielle kilder. Kontrollér altid den valgte stacks dokumentation og den faktiske live-konfiguration før en produktionsændring.