LogoTRUONG PHAM
Home
Projects
Blogs
YouTube
Contact

Newsletter

Stay updated with technical artifacts and engineering insights.

LogoTRUONG PHAM

Building scalable software and sharing insights on technology & life.

Sitemap

  • Home
  • Projects
  • Blogs
  • YouTube
  • Contact

Connect

  • GitHub
  • LinkedIn
  • Email
  • YouTube

© 2024 TRUONG PHAM. © All rights reserved.

Privacy PolicyTerms of Service
Back
Blog #44: CI/CD and Environment Variables that 'Disappear' Without a Trace
50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

Blog #44: CI/CD and Environment Variables that 'Disappear' Without a Trace

When it runs smoothly on your machine but crashes on CI/CD due to missing environment variables.

TP
Truong PhamSoftware Engineer
PublishedAugust 20, 2024

To me in those first times as an accidental DevOps,

Do you still remember the feeling of seeing the build screen on Jenkins or GitHub Actions turning a deadly shade of red? You shouted: "Hey, it runs normally on my machine!". You spent 3 hours committing repeatedly just to... log out environment variables to see why the API URL kept being undefined.

At that time, you saw CI/CD as a mystical world where your code suddenly became "stupid" and forgot all its configurations.

The Problem: Frontend Build Time vs Runtime

Simply put: Environment variables in the Frontend (like REACT_APP_API_URL or VITE_API_URL) are usually embedded directly into the code at Build time. If you forget to configure them during the build on the CI/CD server, the result is that your source code will contain empty values.

Current Perspective: Lack of Documentation and Process

Now I understand that CI/CD errors usually aren't in the code, but in the inconsistency between environments. A common junior mistake is creating a .env file locally but failing to update the .env.example file or documentation for the DevOps team.

# Junior mistake: Not declaring template variables
# Empty .env.example file
# Build script defaults to believing the variable always exists
npm run build

Why does it cause problems? Because in an automated process, the build server doesn't have access to your personal computer to get the .env file. It needs to be provided through the repo's Settings or Secret Management.

Comparison of Solutions:

  • Quick fix: Commit the .env file directly to Git (Never, ever do this for security reasons!). Or manually type environment variables into the server every time a build fails.
  • Sustainable way:
    1. Always have a comprehensive .env.example file with all keys (no values).
    2. Use a validation script to check environment variables at the start of the build. If a critical variable is missing, fail the build immediately with a clear message: "MISSING API_URL VARIABLE".
    3. Harmonize variable naming across environments (Staging, UAT, Production).
// Simple validation script in build process
const requiredEnv = ['VITE_API_URL', 'VITE_STRIPE_KEY'];
requiredEnv.forEach(key => {
  if (!process.env[key]) {
    console.error(`Error: Missing environment variable ${key}`);
    process.exit(1);
  }
});

Practical Lesson

Your code doesn't just live in the src folder. It lives in an entire ecosystem of build and deployment tools. Get into the habit of viewing the CI/CD process as part of your programming job, rather than something someone else does.

A good project is one where anyone new can successfully build after copying the .env.example file.


Notes on the transparency of configurations.

Series • Part 44 of 50

50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

NextBlog #45: The Brutal Difference Between Staging and Production
Blog #43: CORS Isn't Always the Backend's Fault
39Blog #39: The 'Will Fix Later' Promise and the Compound Interest of Technical Debt40Blog #40: Don't try to be smart – Write code for humans, not for machines41Blog #41: The 2 AM Panic and Infinite Question Marks42Blog #42: When the Backend Changes the Schema and the Fragility of the Frontend43Blog #43: CORS Isn't Always the Backend's Fault44Blog #44: CI/CD and Environment Variables that 'Disappear' Without a TraceReading45Blog #45: The Brutal Difference Between Staging and Production46Blog #46: Feature Flag – The 'Lifebuoy' for Risky Releases47Blog #47: Long-term Tab Crash – What happens when Users never close their Tabs?48Blog #48: Slow AI UX Fail – When User Experience can't wait for Artificial Intelligence49Blog #49: Surviving Black Box API – When you have to live with 'Instability'
TP

Written by Truong Pham

Software Engineer passionate about building high-performance systems and meaningful experiences.

Read more articles