React app + caddy + Docker only getting 502 error

jonasglien
FREE

4 months ago

Hello,

So I´ve got a React app im trying to get deployed here via a Dockerfile. I´m following Railways instructions: https://docs.railway.com/guides/react#use-a-dockerfile. This exact Dockerfile and Caddyfile is in apps root directory.

Everything turns green in the dashboard. It is working when I run the container locally. But I never seem to get past the 502 error in my public facing HTTP address. I´ve tried changing the PORT variable as well. 80, 8080, 3000. Nothing works.

Ive also tried some other suggestions for the Caddyfile. Like:

:{$PORT} {

# access logs

log {

format json # set access log format to json mode

}

# health check for railway

rewrite /health /*

# enable gzipping responses

encode gzip

handle {

reverse_proxy <RAILWAY_SERVICE_NAME>:3000

}

}

This also doesnt work. I´m at a loss. Could someone please help?

$10 Bounty

8 Replies

jonasglien
FREE

4 months ago

I also would like to add that I´ve read https://docs.railway.com/reference/errors/application-failed-to-respond without it aiding me much further. This is also the response i get from my HTTP GET request:

httpStatus:502

upstreamProto:"HTTP/1.1"

downstreamProto:"HTTP/2.0"

responseDetails:"failed to forward request to upstream: connection refused"


idiegea21
HOBBY

4 months ago

I think your React app is deploying successfully on Railway, but still shows the error because the internal app server isn’t responding as expected. Possiblt because:

  • Your app isn't listening on 0.0.0.0:$PORT, which Railway requires.

  • Your Caddyfile may be misrouting traffic—reverse_proxy localhost:3000 is usually correct, not .

  • The Dockerfile must EXPOSE the right port and launch the server properly (e.g. with serve).

Basically: green in the dashboard does not mean your app will be accessible unless the server is listening on the right interface and port.


jonasglien
FREE

4 months ago

Thank you for your reply idiegea21. I´ve gotten a bit further, as in I get a 200 response, but only an empty HTML. I.e. my app isn´t getting served. Let me paste my Dockerfile and Caddyfile, which hopefully will show what might be missing.

------------- DOCKERFILE ---------------

# Use the Node alpine official image

# https://hub.docker.com/_/node

FROM node:lts-alpine AS build

# Set config

ENV NPM_CONFIG_UPDATE_NOTIFIER=false

ENV NPM_CONFIG_FUND=false

# Create and change to the app directory.

WORKDIR /app

# Copy the files to the container image

COPY package*.json./

# Remove package-lock.json and install packages to fix rollup optional deps issue

RUN rm-fpackage-lock.json&&npminstall

# Copy local code to the container image.

COPY ../

# Build the app.

RUN npmrunbuild

EXPOSE 3000

# Use the Caddy image

FROM caddy AS production

# Create and change to the app directory.

WORKDIR /app

# Copy Caddyfile to the container image.

COPY Caddyfile./

# Copy local code to the container image.

RUN caddyfmtCaddyfile--overwrite

# Copy files to the container image.

COPY --from=build /app/dist./dist

EXPOSE 80

# Use Caddy to run/serve the app

CMD ["caddy", "run", "--config", "Caddyfile", "--adapter", "caddyfile"]

------------- CADDYFILE ---------------

# global options

{

admin off # theres no need for the admin api in railway's environment

persist_config off # storage isn't persistent anyway

auto_https off # railway handles https for us, this would cause issues if left enabled

# runtime logs

log {

format json # set runtime log format to json mode

}

# server options

servers {

trusted_proxies static private_ranges 100.0.0.0/8 # trust railway's proxy

}

}

# site block, listens on all interfaces on the PORT environment variable

0.0.0.0:{$PORT:3000} {

# access logs

log {

format json # set access log format to json mode

}

# health check for railway

rewrite /health /*

# serve from the 'dist' folder (Vite builds into the 'dist' folder)

root * dist

# enable gzipping responses

encode gzip

# serve files from 'dist'

file_server

# if path doesn't exist, redirect it to 'index.html' for client side routing

try_files {path} /index.html

}


jonasglien
FREE

4 months ago

I also added "reverse_proxy localhost:3000" under "0.0.0.0:{$PORT:3000} {", but still get an empty html.


idiegea21
HOBBY

4 months ago

Uhmmm
I think the are some issues in the Docker and Caddy file

let's start with the docker file, (problems in the COPY and RUN commands
# STAGE 1: Build React app

FROM node:lts-alpine AS build

ENV NPM_CONFIG_UPDATE_NOTIFIER=false

ENV NPM_CONFIG_FUND=false

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . . # This line was broken in original Dockerfile

RUN npm run build # This builds to /app/dist

# STAGE 2: Serve with Caddy

FROM caddy:alpine

WORKDIR /app

COPY Caddyfile ./Caddyfile

# Use caddy fmt properly (optional though)

RUN caddy fmt Caddyfile --overwrite

COPY --from=build /app/dist ./dist

EXPOSE 3000

CMD ["caddy", "run", "--config", "Caddyfile", "--adapter", "caddyfile"]

Then for the Caddy File, the current one is almost correct but you should nt include reverse_proxy localhost:3000 if you’re just serving static files. Remove it, it’s only for backend servers like Node.js Express.

then you can verify locally by checking
docker build -t test-app .

docker run -p 3000:3000 test-app

Then open http://localhost:3000. if it works here, it should work in Railway too.


jonasglien
FREE

4 months ago

Thank you again for your reply. Sadly, it is still not working.

I´ve copied your suggestions verbatim.

My app runs succesfully via docker at localhost:3000. But not on Railway.

I´ve opened my github repo in hopes of it might reveal something: https://github.com/Jonasglien/hatpro

Hoping we manage to figure this out, as I was looking forward to using this platform as my hosting platform!

Best regards, Jonas


jonasglien

Thank you again for your reply. Sadly, it is still not working.I´ve copied your suggestions verbatim. My app runs succesfully via docker at localhost:3000. But not on Railway.I´ve opened my github repo in hopes of it might reveal something: https://github.com/Jonasglien/hatproHoping we manage to figure this out, as I was looking forward to using this platform as my hosting platform!Best regards, Jonas

sim
FREE

4 months ago

Can you tell more about the most recent problem. Is it still the 502s?


sim
FREE

4 months ago