Custom Dockerfile doesn't recognize environment variables
pulgueta
HOBBYOP

a month ago

I have separate Dockerfiles to build my API and Frontend as I achieved this approach as the most suitable for my case. The thing is, since I'm using a custom Dockerfile, I need to access the environment variables from Railway and I try adding them as ARGs and ENVs in both building and running steps, but still fails when the server is ran.

I've followed the documentation and read other threads but none seem to clarify what am I doing wrong. I'm using Bun and Turborepo set to loose

Repository: https://github.com/pulgueta/virtualpot
This is one of my Dockerfiles:

ARG BUN_VERSION=1
ARG PORT
ARG HOSTNAME
ARG FRONTEND_URL

FROM oven/bun:${BUN_VERSION} AS deps

WORKDIR /app

COPY package.json bun.lock turbo.json ./
COPY apps/api/package.json ./apps/api/package.json

RUN bun install

FROM oven/bun:${BUN_VERSION} AS builder

WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/apps/api/node_modules ./apps/api/node_modules

COPY . .

ENV PORT=$PORT
ENV HOSTNAME=$HOSTNAME
ENV FRONTEND_URL=$FRONTEND_URL

RUN bun run build --filter=@virtualpot/api

FROM oven/bun:${BUN_VERSION}-slim AS runner

WORKDIR /app

COPY --from=builder /app/apps/api/dist ./dist

ENV NODE_ENV=production
ENV PORT=$PORT
ENV HOSTNAME=$HOSTNAME
ENV FRONTEND_URL=$FRONTEND_URL

EXPOSE $PORT

CMD ["bun", "run", "dist/index.js"]
Solved$10 Bounty

Pinned Solution

Glad it worked- I'm not familiar with @t3-oss so I can't answer that piece.

That said,I do know Vite injects environment variables at build time so they are needed during the build phase of your web app

This is because they just get bundled into the build and shipped to the client slightly_smiling_face emoji

4 Replies

Ahhh, the problem is that ARG doesn't persist across different build stages. Your ARG declarations at the top aren't being passed through to the final image.

Try something like this:

ARG BUN_VERSION=1
FROM oven/bun:${BUN_VERSION} AS deps

WORKDIR /app
COPY package.json bun.lock turbo.json ./
COPY apps/api/package.json ./apps/api/package.json

RUN bun install

FROM oven/bun:${BUN_VERSION} AS builder

WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY --from=deps /app/apps/api/node_modules ./apps/api/node_modules
COPY . .

RUN bun run build --filter=@virtualpot/api

FROM oven/bun:${BUN_VERSION}-slim AS runner
WORKDIR /app
COPY --from=builder /app/apps/api/dist ./dist
ENV NODE_ENV=production

# Railway will inject PORT, HOSTNAME, FRONTEND_URL, etc at runtme
# No need to set them here; ONLY set variables that way that are needed by the build step

EXPOSE 3000

CMD ["bun", "run", "dist/index.js"]

If you actually need build time variables in a stage, you'll need to copy/paste them into each stage that needs those variables during the build.


mykal

Ahhh, the problem is that ARG doesn't persist across different build stages. Your ARG declarations at the top aren't being passed through to the final image. Try something like this:ARG BUN_VERSION=1 FROM oven/bun:${BUN_VERSION} AS deps WORKDIR /app COPY package.json bun.lock turbo.json ./ COPY apps/api/package.json ./apps/api/package.json RUN bun install FROM oven/bun:${BUN_VERSION} AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY --from=deps /app/apps/api/node_modules ./apps/api/node_modules COPY . . RUN bun run build --filter=@virtualpot/api FROM oven/bun:${BUN_VERSION}-slim AS runner WORKDIR /app COPY --from=builder /app/apps/api/dist ./dist ENV NODE_ENV=production # Railway will inject PORT, HOSTNAME, FRONTEND_URL, etc at runtme # No need to set them here; ONLY set variables that way that are needed by the build step EXPOSE 3000 CMD ["bun", "run", "dist/index.js"]If you actually need build time variables in a stage, you'll need to copy/paste them into each stage that needs those variables during the build.

pulgueta
HOBBYOP

a month ago

Holy, that worked, thanks! Sadly, it didn't work out for my TanStack Start app, I have both commands as suggested in many places:

"build": "bun --bun vite build",
"start": "bun run .output/server/index.mjs"
ARG BUN_VERSION=1-alpine

FROM oven/bun:${BUN_VERSION} AS builder

# ...previous steps

RUN bun run build

FROM oven/bun:${BUN_VERSION} AS runner

WORKDIR /app

COPY --from=builder /app/apps/web/.output /app/.output

ENV NODE_ENV=production

CMD ["bun", "run", ".output/server/index.mjs"]

Dockerfile is pretty much almost the same, the VITE_API_URL is set but the @t3-oss/env-core package throws an error when I enter the page saying it's missing the environment variables. Do these need to be used at build time?


pulgueta

Holy, that worked, thanks! Sadly, it didn't work out for my TanStack Start app, I have both commands as suggested in many places:"build": "bun --bun vite build", "start": "bun run .output/server/index.mjs"ARG BUN_VERSION=1-alpine FROM oven/bun:${BUN_VERSION} AS builder # ...previous steps RUN bun run build FROM oven/bun:${BUN_VERSION} AS runner WORKDIR /app COPY --from=builder /app/apps/web/.output /app/.output ENV NODE_ENV=production CMD ["bun", "run", ".output/server/index.mjs"]Dockerfile is pretty much almost the same, the VITE_API_URL is set but the @t3-oss/env-core package throws an error when I enter the page saying it's missing the environment variables. Do these need to be used at build time?

Glad it worked- I'm not familiar with @t3-oss so I can't answer that piece.

That said,I do know Vite injects environment variables at build time so they are needed during the build phase of your web app

This is because they just get bundled into the build and shipped to the client slightly_smiling_face emoji


mykal

Glad it worked- I'm not familiar with @t3-oss so I can't answer that piece.That said,I do know Vite injects environment variables at build time so they are needed during the build phase of your web appThis is because they just get bundled into the build and shipped to the client

pulgueta
HOBBYOP

a month ago

It definitely worked! It's now just a matter of networking to stick all the pieces together. Thanks a lot!


Status changed to Solved brody about 1 month ago


Loading...