R
Railway•11mo ago
Xevion

Ideal way to compose and manage a full stack app?

Railway doesn't really seem to be exposing an example of how one could/should compose a full stack application. It provides all the services, but it doesn't seem to detail on how you'd put them all together. For example, Django is a great backend, but if you want a great frontend - you'll need something like React, built with Vite, perhaps. But how is one supposed to build and serve your frontend files? Nginx comes to mind, serving static files for your frontend, and proxying all API requests to Django. But how is this to be done? Most people use Docker Compose, which Railway doesn't support at all. Dockerfiles are cool, but I'm struggling to find any examples that include more than a single service. There's no Django + Postgres + React + Nginx example - there's just Django. Or Nginx. Or Django + Postgres at best; which isn't hard to figure out at all.
60 Replies
Percy
Percy•11mo ago
Project ID: N/A
Xevion
Xevion•11mo ago
N/A Any sort of blog posts, discussions, or docs, if I missed them, are what I'm looking for. Templates, dockerfiles also work - but I'm interested in a more generalized example - I really don't care if it's Django and React proxied by Nginx, or Axum and Svelte proxied via Traefik.
Xevion
Xevion•11mo ago
Does this require more than one repository? I don't like doing multiple, but I have very little experience with monorepos, which I've read that Railway provides some of? Trying to understand what I'm looking at; literally never seen anything that you just linked 😓
Brody
Brody•11mo ago
the public project does use 3 separate repos, only because it's comprised of 3 railway templates, but you absolutely could do this in a monorepo format
Xevion
Xevion•11mo ago
The style of repo I'm looking for is
/client
/server
README.md
Dockerfile
/client
/server
README.md
Dockerfile
But I understand limitations may apply and some other format may be forced. It's just what I'm used to, personally ;p
Brody
Brody•11mo ago
you wouldn't have a dockerfile in the root, you would have a dockerfile specific to each service type otherwise that's totally doable on railway
Xevion
Xevion•11mo ago
Oh, okay. So, to confirm what I'm reading on the docs, you add two services, change this
No description
Xevion
Xevion•11mo ago
And have dockerfiles in each?
Brody
Brody•11mo ago
correct
Xevion
Xevion•11mo ago
Are three services required for proxying purposes? Or two? I'm wondering why there are three, when it seems only two things exist (a frontend, and a backend)
No description
Xevion
Xevion•11mo ago
My thought process is, "client" repo receives all requests, and proxies everything in /api to the backend service (perhaps using the Railway private networking)
Brody
Brody•11mo ago
that's exactly what that project you are looking at is doing mysite receives all traffic, proxys requests to /api/* to the backend, and everything else to the frontend all through the internal network, the frontend and backend are not exposing themselves to the public
Xevion
Xevion•11mo ago
So there's two Caddy services? Feels like more overhead when Caddy could be acting directly on the files in the frontend
Brody
Brody•11mo ago
caddy is both a proxy and a file server caddy is used in the frontend to serve the frontend site, and caddy is used on mysite to proxy incoming traffic to it's destination
Xevion
Xevion•11mo ago
Yes; can't it do both at the same time?
Brody
Brody•11mo ago
totally could, wanna see an example of that too? I do prefer keeping them separate when possible though, it's "cleaner" this way imo
Xevion
Xevion•11mo ago
I suppose it's a little cleaner in a diagram kinda way, but isn't the performance loss pretty bad? Have to send an entirely new HTTP request just for proxying
Brody
Brody•11mo ago
nope, rtt would be around 5ms on average between the proxy and the frontend or backend
Xevion
Xevion•11mo ago
Really? That's crazy. Not that I don't believe you, but how do you know?
Brody
Brody•11mo ago
it's an internal network after all
Xevion
Xevion•11mo ago
Does it consume more bandwidth or resources, besides memory; which should be pretty low given that it's just a webserver?
Brody
Brody•11mo ago
example test results of a http get request to another internal service
No description
Xevion
Xevion•11mo ago
I suppose I could spend several hours working up a benchmark with/without Caddy proxy <:no_think_empty_brain:1124358871960522893>
Brody
Brody•11mo ago
well given you arent charged for network usage on the private network, that wouldnt cost any extra, but yes you do pay for running two caddy services you tell me what you want to know, theres a good change i already have testing in place for it
Xevion
Xevion•11mo ago
I mean, transferring a decent file (1MB+) with and without a middleman Caddy server, averaged over a decent number of requests (say 100, or 1000). Compare.
Brody
Brody•11mo ago
you can check the mem usage in the services of that project, in fact they are all go services, so my estimated usage for that whole project is 50 cents
Xevion
Xevion•11mo ago
I have fair confidence though in what you say though; Railway in my opinion is not the platform to be building a service that cares about < 10ms delays. I use it for putting my silly little projects on it, and learning how to build cool shit. If said silly little project blows up, it should not be hard to move it onto a AWS instance that will cost me several car payments per day to run.
Brody
Brody•11mo ago
i could test that, i do have a service in place to generate files of any size, id just need to slap a caddy proxy in front of it
Xevion
Xevion•11mo ago
Caddy is very cool though. I have never heard of this alternative. I've been tearing my hair out over Nginx lately.
Brody
Brody•11mo ago
well thats why i choose caddy to do this, i believe its more user friendly than nginx heres the caddyfile for the proxy https://github.com/brody192/reverse-proxy/blob/main/Caddyfile
Xevion
Xevion•11mo ago
One question though; if I wanted to host a frontend and a backend with Caddy, could I host one service in the root, and the second in, say, /server?
Brody
Brody•11mo ago
yes but youd need to do some file whitelisting, though im not sure why youd want to structure your repo like that
Xevion
Xevion•11mo ago
e.g.
/client
...
/server
Dockerfile
Caddyfile
Dockerfile <--- Builds frontend, serves with Caddy, proxies /api to backend
/client
...
/server
Dockerfile
Caddyfile
Dockerfile <--- Builds frontend, serves with Caddy, proxies /api to backend
Brody
Brody•11mo ago
why not just
/server
/frontend
/proxy
README.md
/server
/frontend
/proxy
README.md
Xevion
Xevion•11mo ago
That's if I wanted to do a three service setup. I'm still curious about a two service setup.
Brody
Brody•11mo ago
and i dont know if youve noticed, but the backend and frontend are not build with a dockerfile
Xevion
Xevion•11mo ago
wym?
No description
Brody
Brody•11mo ago
that was dumb
Xevion
Xevion•11mo ago
No description
Xevion
Xevion•11mo ago
Says the builder was the Dockerfile here, too
Brody
Brody•11mo ago
i know, my mistake
Xevion
Xevion•11mo ago
Oh, okay. :p
Brody
Brody•11mo ago
i think
Xevion
Xevion•11mo ago
I'm okay building/not building with a dockerfile, but for more tuned setups like this, I might be okay with skipping Nixpacks for my own setup.
Brody
Brody•11mo ago
though I absolutely could do the proxy with nixpacks
Xevion
Xevion•11mo ago
Yeah, I assume Caddyfiles are autodetect with nixpacks?
Brody
Brody•11mo ago
no they arent, not at all
Xevion
Xevion•11mo ago
Oh; then how would nixpacks do the proxy?
Brody
Brody•11mo ago
as ive come to learn, you can do a whole lot with nixpacks so give me a sec
Xevion
Xevion•11mo ago
Ok
Brody
Brody•11mo ago
providers = []

[phases.setup]
nixPkgs = ['caddy']

[phases.fmt]
dependsOn = ['setup']
cmds = ['caddy fmt --overwrite Caddyfile']

[start]
cmd = 'caddy run'
providers = []

[phases.setup]
nixPkgs = ['caddy']

[phases.fmt]
dependsOn = ['setup']
cmds = ['caddy fmt --overwrite Caddyfile']

[start]
cmd = 'caddy run'
this doesnt use any providers, we manually install caddy and run it
Xevion
Xevion•11mo ago
Interesting.
Brody
Brody•11mo ago
i just wrote that off the top of my head, though i dont see why it wouldnt do what i want
Xevion
Xevion•11mo ago
I don't know that I have anything more to add to the conversation, but this was really enlightening from start to end. Thanks for the examples!
Brody
Brody•11mo ago
no problem, i got all the examples if you ever need any help structuring your app on railway or even setting up caddy just ask!
Xevion
Xevion•11mo ago
Will do! I forgot if it said a way to mark this as solved, or where to press or w/e. If you can do it, please do. Or tell me. Whichever.
Brody
Brody•11mo ago
you can use apps > mark solution in the context menu of a message, but in this case where we are mostly just chatting and I've answered all questions, I will just mark the entire thread as solved by editing the tags and I have already done just that
Xevion
Xevion•11mo ago
Cool! The Discord apps thing is new to me lol.
Brody
Brody•11mo ago
no worries!