Search code examples
reactjstypescriptdockervitefly

Access env variables when running Vite React app using Dockerfile


I have a Vite React app which uses env variables to talk to an API:

const API_URL = import.meta.env.VITE_API_URL;

I am deploying this app to Fly.io with the following Dockerfile:

FROM node:18 as build

WORKDIR /web

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

FROM nginx:alpine

COPY --from=build /web/dist /usr/share/nginx/html

# This needs be referenced in fly.toml's internal_port
EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

I have the VITE_API_URL set in my Fly.io container's env and have checked that it exists.

However, when I deploy the app, the API_URL ends up as undefined. I think it has something to do with nginx not having access to it.

I had deployed this other Dockerfile when developing:

FROM node:18

WORKDIR /web

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 5173

CMD ["npm", "run", "dev"]

And this one had access to Fly.io's secrets/env variables. I suspect its because I'm running the Vite code directly using npm run dev. But now that I'm running it through nginx, I think I might need to do something different to access the same env variables?


Solution

  • Vite needs environment variables at build time.

    You've got two options...

    1. Add a .env.production file into your Docker build. Eg

      # .env.production
      VITE_API_URL=https://your.production.api/
      
    2. Pass a build argument to your fly deploy command and use it to set an environment variable

      fly deploy --build-arg API_URL="https://your.production.api/"
      
      # Dockerfile
      FROM node:18 as build
      WORKDIR /web
      COPY package*.json ./
      RUN npm install
      COPY . .
      
      ARG API_URL
      ENV VITE_API_URL=${API_URL}
      RUN npm run build
      

      I think you can also set build args in your fly.toml file under [build.args] if you prefer