Help with deploying a react + vite app on railway using docker

I am in need of help in regards to deploying a react + vite app to railway. So I have a dockerfile for my app which i've told railway the path to the dockerfile to deploy the app. The issue is that from what I've gathered, railway doesn't inject the ENV variables during the build process and vite relies on that as it takes ENV variables then replaces the values in the code during the build process. Is there a way of passing ARG variables as an alternative in railway to my dockerfile? Or what would be the solution for me to be able to use the ENV variables during the build process so that Vite has access to the ENV variables to inject into the code? Just for some context this is a bit of the code in the dockerfile that I'm referring to:
# Install doppler and provide the doppler token so the ENV variables can be statically replaced in the react+vite app.
RUN wget -q -t3 'https://packages.doppler.com/public/cli/rsa.8004D9FF50437357.key' -O /etc/apk/keys/cli@doppler-8004D9FF50437357.rsa.pub
RUN echo 'https://packages.doppler.com/public/cli/alpine/any-version/main' | tee -a /etc/apk/repositories
RUN apk add doppler

ENV DOPPLER_TOKEN=${DOPPLER_TOKEN}

COPY --from=builder /app/out/full/ ./
COPY turbo.json turbo.json
RUN yarn turbo run build --filter=webapp...
# Install doppler and provide the doppler token so the ENV variables can be statically replaced in the react+vite app.
RUN wget -q -t3 'https://packages.doppler.com/public/cli/rsa.8004D9FF50437357.key' -O /etc/apk/keys/cli@doppler-8004D9FF50437357.rsa.pub
RUN echo 'https://packages.doppler.com/public/cli/alpine/any-version/main' | tee -a /etc/apk/repositories
RUN apk add doppler

ENV DOPPLER_TOKEN=${DOPPLER_TOKEN}

COPY --from=builder /app/out/full/ ./
COPY turbo.json turbo.json
RUN yarn turbo run build --filter=webapp...
19 Replies
Percy
Percy10mo ago
Project ID: N/A
mta.coder97
mta.coder9710mo ago
n/a
Brody
Brody10mo ago
thats an incomplete dockerfile, do you mind sending the full file?
mta.coder97
mta.coder9710mo ago
Yes sure
# ---------------------------------
# BUILD STAGE
# ---------------------------------
FROM node:18-alpine AS builder

RUN apk add --no-cache libc6-compat
RUN apk update

# Set working directory
WORKDIR /app

RUN yarn global add turbo

COPY . ./

RUN turbo prune --scope=webapp --docker
# ---------------------------------

# ---------------------------------
# INSTALL STAGE
# ---------------------------------
# Add lockfile and package.json's of isolated subworkspace
FROM node:18-alpine AS installer

RUN apk add --no-cache libc6-compat
RUN apk update

WORKDIR /app

# First install the dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ ./
COPY --from=builder /app/out/yarn.lock ./yarn.lock
RUN yarn install

# Install doppler and provide the doppler token so the ENV variables can be statically replaced in the react+vite app.
RUN wget -q -t3 'https://packages.doppler.com/public/cli/rsa.8004D9FF50437357.key' -O /etc/apk/keys/cli@doppler-8004D9FF50437357.rsa.pub
RUN echo 'https://packages.doppler.com/public/cli/alpine/any-version/main' | tee -a /etc/apk/repositories
RUN apk add doppler

ENV DOPPLER_TOKEN=${DOPPLER_TOKEN}

COPY --from=builder /app/out/full/ ./
COPY turbo.json turbo.json
RUN yarn turbo run build --filter=webapp...
# ---------------------------------

# ---------------------------------
# RUNNER STAGE (NGINX)
# ---------------------------------
FROM nginx:1.25-alpine

COPY --from=installer /app/apps/webapp/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=installer /app/apps/webapp/dist /usr/share/nginx/html

EXPOSE 80
# -------------------------------------
# ---------------------------------
# BUILD STAGE
# ---------------------------------
FROM node:18-alpine AS builder

RUN apk add --no-cache libc6-compat
RUN apk update

# Set working directory
WORKDIR /app

RUN yarn global add turbo

COPY . ./

RUN turbo prune --scope=webapp --docker
# ---------------------------------

# ---------------------------------
# INSTALL STAGE
# ---------------------------------
# Add lockfile and package.json's of isolated subworkspace
FROM node:18-alpine AS installer

RUN apk add --no-cache libc6-compat
RUN apk update

WORKDIR /app

# First install the dependencies (as they change less often)
COPY .gitignore .gitignore
COPY --from=builder /app/out/json/ ./
COPY --from=builder /app/out/yarn.lock ./yarn.lock
RUN yarn install

# Install doppler and provide the doppler token so the ENV variables can be statically replaced in the react+vite app.
RUN wget -q -t3 'https://packages.doppler.com/public/cli/rsa.8004D9FF50437357.key' -O /etc/apk/keys/cli@doppler-8004D9FF50437357.rsa.pub
RUN echo 'https://packages.doppler.com/public/cli/alpine/any-version/main' | tee -a /etc/apk/repositories
RUN apk add doppler

ENV DOPPLER_TOKEN=${DOPPLER_TOKEN}

COPY --from=builder /app/out/full/ ./
COPY turbo.json turbo.json
RUN yarn turbo run build --filter=webapp...
# ---------------------------------

# ---------------------------------
# RUNNER STAGE (NGINX)
# ---------------------------------
FROM nginx:1.25-alpine

COPY --from=installer /app/apps/webapp/nginx/nginx.conf /etc/nginx/conf.d/default.conf
COPY --from=installer /app/apps/webapp/dist /usr/share/nginx/html

EXPOSE 80
# -------------------------------------
I am using turborepo thats why i need to prune the webapp project and build it in this way as it has dependencies with another package in the monorepo just a note this dockerfile builds perfectly fine and it works locally when i pass it a env_file to the docker-compose process etc
Brody
Brody10mo ago
okay so for example if you needed the DATABASE_URL variable during build all you need to do is define it with the ARG keyword in the same image layer that will be using that variable, like so
FROM node:18-alpine AS installer

ARG DATABASE_URL
FROM node:18-alpine AS installer

ARG DATABASE_URL
mta.coder97
mta.coder9710mo ago
Will this work on railway?
Brody
Brody10mo ago
yes
mta.coder97
mta.coder9710mo ago
ok one sec let me try that
mta.coder97
mta.coder9710mo ago
This is where i've declared my ENV variables
Brody
Brody10mo ago
ARG DOPPLER_TOKEN
ARG DOPPLER_TOKEN
instead of
ENV DOPPLER_TOKEN=${DOPPLER_TOKEN}
ENV DOPPLER_TOKEN=${DOPPLER_TOKEN}
mta.coder97
mta.coder9710mo ago
Okay so the deployment was successful this time I just realised that my build command was the issue. I had this command for the npm run build script: doppler run -- tsc && vite build the issue was that the doppler variables were not being injected into the vite build process, it seems like it was being injected during the tsc command process after i switched it to: tsc && doppler run -- vite build it started working however on railway i'm getting a server error when i try to open the webapp its being hosted via nginx
Brody
Brody10mo ago
have nginx listen on 8080 and then set a railway service variable PORT = 8080
mta.coder97
mta.coder9710mo ago
just saw that the port ENV variable was missing
Brody
Brody10mo ago
its only needed if your app doesnt listen on $PORT by default, since railway will generate one for your app internally
mta.coder97
mta.coder9710mo ago
ahh i see deployment in progress right now i set nginx to listen on 3000 since my react app listens on 3000 so lets see if this works
Brody
Brody10mo ago
as long as you set PORT to 3000
mta.coder97
mta.coder9710mo ago
and look at that! The app is live on Railway 🥳
mta.coder97
mta.coder9710mo ago
Thank you so much @Brody , really appreciate the very quick responses and help 👍
Brody
Brody10mo ago
no problem 🙂