Caddy as separate service

ProjectID: e649edf0-e7e9-4b6d-8516-8155a5adf4a2 I have two services, a frontend react service and a golang backend service. I want to have caddy serve the frontend build and have a reverse proxy to the backend. Is there any documentation on doing this? I saw this template for caddy https://railway.app/template/TETV8z, but it serves the static site from within the caddy service.
Solution:
then this is the template you want, be sure to read the overview! https://railway.app/template/7uDSyj...
Jump to solution
77 Replies
Percy
Percy9mo ago
Project ID: e649edf0-e7e9-4b6d-8516-8155a5adf4a2
Brody
Brody9mo ago
so your end goal would be to serve the frontend and backend through a single service?
mrCunningham
mrCunningham9mo ago
my end goal would be directing traffic to the correct service
Brody
Brody9mo ago
well yes thats a given, but at a higher level, are you wanting to be able to access the frontend and backend from the same domain? like this? Frontend - Vue 3: https://mysite.up.railway.app/ Backend - Go Mux: https://mysite.up.railway.app/api/
mrCunningham
mrCunningham9mo ago
Sorry, yes that is the goal
Solution
Brody
Brody9mo ago
then this is the template you want, be sure to read the overview! https://railway.app/template/7uDSyj
mrCunningham
mrCunningham9mo ago
👍
Brody
Brody9mo ago
let me know if you need any extra help getting it configured!
mrCunningham
mrCunningham9mo ago
in the example app for that caddy template, it uses a vue 3 repo. the repo itself is using caddy. I have the same setup for my react frontend application. is that correct? i was also hoping to access the backend via a specified port instead of through the /api/ routing so it would be configured as frontend: https://mysite.up.railway.app/ backend: https://mysite.up.railway.app:4445/
Brody
Brody9mo ago
railway only allows you expose a single http port 443, so you do need to access the backend from a route like the api route shows
mrCunningham
mrCunningham9mo ago
alright. so i have my environment setup as BACKEND_HOST=${{quotes.RAILWAY_PRIVATE_DOMAIN}}:${{quotes.PORT}} FRONTEND_HOST=${{quotes-frontend.RAILWAY_PRIVATE_DOMAIN}}:${{quotes-frontend.PORT}} this should allow me to access the frontend if its setup using this template https://github.com/brody192/vite-react-template ?
GitHub
GitHub - brody192/vite-react-template
Contribute to brody192/vite-react-template development by creating an account on GitHub.
Brody
Brody9mo ago
that's correct
mrCunningham
mrCunningham9mo ago
would i need to disable the domains on those services? right now with that setup, the caddy domain that was generated by railway throws a 502 error
Brody
Brody9mo ago
show me your caddyfile please?
mrCunningham
mrCunningham9mo ago
{ # 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 log { # runtime logs format console # set runtime log format to console mode } servers { # server options trusted_proxies static private_ranges # trust railway's proxy } } :{$PORT} { # site block, listens on the $PORT environment variable, automatically assigned by railway log { # access logs format console # set access log format to console mode } reverse_proxy {$FRONTEND_HOST} # proxy all requests for /* to the frontend, configure this variable in the service settings # the handle_path directive will strip /api/ from the path before proxying # this is needed if your backend's api routes don't start with /api/ # change paths as needed handle_path /api/* { # this strips the /api/ prefix from the uri sent to the proxy address reverse_proxy {$BACKEND_HOST} # proxy all requests for /api/* to the backend, configure this variable in the service settings } # if your backend's api routes do start with /api/ then you wouldn't want to strip the path prefix # if so, comment out the above handle_path block, and uncomment this reverse_proxy directive # change paths as needed # reverse_proxy {$BACKEND_HOST} # configure this variable in the service settings }
Brody
Brody9mo ago
okay doesn't look like anything changed at all, can you show me a full browser screenshot with the raw environment variables editor open for the proxy service?
mrCunningham
mrCunningham9mo ago
No description
Brody
Brody9mo ago
okay and now just a screenshot of the project without anything open
mrCunningham
mrCunningham9mo ago
No description
Brody
Brody9mo ago
show me the variables for the frontend and backend services please
mrCunningham
mrCunningham9mo ago
No description
mrCunningham
mrCunningham9mo ago
the backend has quite a few, is there something specific you are looking for?
Brody
Brody9mo ago
fair, does it have a PORT variable too?
mrCunningham
mrCunningham9mo ago
yes
Brody
Brody9mo ago
good, send me the domains for all 3 of those services please
mrCunningham
mrCunningham9mo ago
No description
Brody
Brody9mo ago
preferable in clickable link format
Brody
Brody9mo ago
i see the 502 error, but im not seeing anything wrong with how you’ve set it up the proxy service will do access logs, use this to send me the deployment logs for the proxy https://bookmarklets.up.railway.app/log-downloader/
Brody
Brody9mo ago
share your frontend repo?
mrCunningham
mrCunningham9mo ago
its a monorepo private app for my company
Brody
Brody9mo ago
fair, isolated or shared monorepo?
mrCunningham
mrCunningham9mo ago
i copied the Caddyfile and nixpacks.toml from your vite-react-railway template isolated i believe, backend in backend folder and frontend in frontend folder
Brody
Brody9mo ago
send me the build table at the top of the build logs for the frontend
mrCunningham
mrCunningham9mo ago
No description
Brody
Brody9mo ago
still looks good this is really odd
mrCunningham
mrCunningham9mo ago
yeah its throwing me for a loop
Brody
Brody9mo ago
what are the values for both PORT variables of the frontend and backend?
mrCunningham
mrCunningham9mo ago
frontend: 3000 backend: 4445
Brody
Brody9mo ago
okay then I see the issues
Brody
Brody9mo ago
for some reason caddy is trying to proxy the requests on port 80
No description
mrCunningham
mrCunningham9mo ago
thoughts on how to fix that?
Brody
Brody9mo ago
im looking back at your screenshots now change your proxy start command to printenv then give me the values printed for FRONTEND_HOST and BACKEND_HOST actually, just download the log for printenv, the environment variables for the proxy service wouldn't contain anything sensitive note, it will likely get stuck in deploying, but the logs are still printed
mrCunningham
mrCunningham9mo ago
where is the proxy start command specified?
Brody
Brody9mo ago
No description
mrCunningham
mrCunningham9mo ago
haha okay
Brody
Brody9mo ago
still good
FRONTEND_HOST=quotes-frontend.railway.internal:3000
BACKEND_HOST=quotes.railway.internal:4445
FRONTEND_HOST=quotes-frontend.railway.internal:3000
BACKEND_HOST=quotes.railway.internal:4445
have you modified the proxy's caddyfile in anyway?
mrCunningham
mrCunningham9mo ago
nope i launched the template directly
Brody
Brody9mo ago
remove the printenv from the start command and let it redeploy let me know when that deployment finishes
mrCunningham
mrCunningham9mo ago
done deployment has finished
Brody
Brody9mo ago
it looks to be working you are redirecting to an entirely different url for login, you should only change paths, but thats just a minor code change on the frontend
mrCunningham
mrCunningham9mo ago
yeah thanks for all the help man
Brody
Brody9mo ago
no problem, if this 502 issue comes back let me know
mrCunningham
mrCunningham8mo ago
when i have this in two different environments, will having the FRONTEND_HOST and BACKEND_HOST point to the specific environment?
Brody
Brody8mo ago
use reference variables, reference variables are scoped to the environment https://docs.railway.app/develop/variables#railway-provided-variables
mrCunningham
mrCunningham8mo ago
i have my caddy proxy env like this BACKEND_HOST=${{CustomerPortal.RAILWAY_PRIVATE_DOMAIN}}:${{CustomerPortal.PORT}} FRONTEND_HOST=${{CustomerPortal-FE.RAILWAY_PRIVATE_DOMAIN}}:${{CustomerPortal-FE.PORT}} but it is loading the old version of the frontend, when i go directly to the frontend_host it works fine
Brody
Brody8mo ago
click the little eye icon on them, do they render properly?
mrCunningham
mrCunningham8mo ago
yup
Brody
Brody8mo ago
and your caddyfile uses those service variables too?
mrCunningham
mrCunningham8mo ago
those are the variables my caddy is using correct
Brody
Brody8mo ago
is your browser caching something?
Brody
Brody8mo ago
the viewrail.com address is the caddy proxy and the railway.app address is the railway domain for the frontend, correct? if that's correct, it just seems like you've missconfigured something, show me the caddyfile for the staging branch?
mrCunningham
mrCunningham8mo ago
the caddyfile for the react frontend or for the proxy
Brody
Brody8mo ago
proxy
mrCunningham
mrCunningham8mo ago
{ # 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
log { # runtime logs
format console # set runtime log format to console mode
}
servers { # server options
trusted_proxies static private_ranges # trust railway's proxy
}
}

:{$PORT} { # site block, listens on the $PORT environment variable, automatically assigned by railway
log { # access logs
format console # set access log format to console mode
}

reverse_proxy {$FRONTEND_HOST} # proxy all requests for /* to the frontend, configure this variable in the service settings


# the handle_path directive will strip /api/ from the path before proxying
# this is needed if your backend's api routes don't start with /api/
# change paths as needed

handle_path /api/* { # this strips the /api/ prefix from the uri sent to the proxy address
reverse_proxy {$BACKEND_HOST} # proxy all requests for /api/* to the backend, configure this variable in the service settings
}

# if your backend's api routes do start with /api/ then you wouldn't want to strip the path prefix
# if so, comment out the above handle_path block, and uncomment this reverse_proxy directive
# change paths as needed
# reverse_proxy {$BACKEND_HOST} # configure this variable in the service settings
}
{ # 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
log { # runtime logs
format console # set runtime log format to console mode
}
servers { # server options
trusted_proxies static private_ranges # trust railway's proxy
}
}

:{$PORT} { # site block, listens on the $PORT environment variable, automatically assigned by railway
log { # access logs
format console # set access log format to console mode
}

reverse_proxy {$FRONTEND_HOST} # proxy all requests for /* to the frontend, configure this variable in the service settings


# the handle_path directive will strip /api/ from the path before proxying
# this is needed if your backend's api routes don't start with /api/
# change paths as needed

handle_path /api/* { # this strips the /api/ prefix from the uri sent to the proxy address
reverse_proxy {$BACKEND_HOST} # proxy all requests for /api/* to the backend, configure this variable in the service settings
}

# if your backend's api routes do start with /api/ then you wouldn't want to strip the path prefix
# if so, comment out the above handle_path block, and uncomment this reverse_proxy directive
# change paths as needed
# reverse_proxy {$BACKEND_HOST} # configure this variable in the service settings
}
Brody
Brody8mo ago
so caddy is proxying the request to your frontend, I see html returned, but your frontend is then deciding to render a json object to the screen for some reason? so it seems the problem is with your frontend and not so much caddy
mrCunningham
mrCunningham8mo ago
but the url for the frontend renders just fine? should be pointing to the same thing
Brody
Brody8mo ago
im not saying its not odd, im just saying its not specifically caddys fault, your frontend is rendering out a json object to the dom for some reason, this is something you would need to look into in your frontend code
mrCunningham
mrCunningham8mo ago
further looking into this, i had the caddy-proxy generate a domain on railway and that generated domain works fine here is the generated domain: https://caddy-proxy-staging.up.railway.app and the custom domain: https://staging.portal.viewrail.com it appears that the caddy-proxy on the custom domain is caching the old frontend
Brody
Brody8mo ago
have you redeployed the caddy proxy?
mrCunningham
mrCunningham8mo ago
yes
Brody
Brody8mo ago
then it's not a cache issue this is your frontend deciding to render a json object into the viewport
mrCunningham
mrCunningham8mo ago
i guess im confused. the two urls i sent you are for the caddy-proxy. they are both pointing to the same frontend deployment. why would the frontend matter at all? on the generated url, its pointing to the newest deployment while the custom domain is from a previous deployment.
Brody
Brody8mo ago
I am aware this is insanely strange, I have never seen anything like it, but caddy is not the culprit here, that json object you are seeing is being displayed by the frontend code please do not get hung up on the caddy proxy, this is an issue with your frontend