R
Railway•9mo ago
JeffPeterson

How to Use Caddy To Serve Static Vite React Frontend and a Gunicorn Django Backend With Docker

Hello! I am trying to test Caddy locally before deploying to Railway. I would like to have Caddy serve statically built files from Vite React while "forwarding" REST API requests such as /api/v1/* requests to my Django Backend that is served with Gunicorn. For local development I am using Docker compose but I am not using volumes because I know this is not supported on Railway. I am getting an error in the networking tab of my Firefox browser that says "CORS Missing Allow Origin" and for a POST request that says "NS_ERROR_DOM_BAD_URI" (see image). I also get a 502 Bad Gateway. I believe my error is in the Caddyfile because of these errors as well as the fact that I am not getting any information in the Django Docker container. I am a noob at proxing and tools such as Caddy and Ngnix but do you think you could give me some pointers? Here are the relevant files: Caddyfile
:{$PORT} {
root * /var/www/html

header {
Access-Control-Allow-Origin *
Access-Control-Allow-Credentials true
Access-Control-Allow-Methods *
Access-Control-Allow-Headers *
defer
}
reverse_proxy /api/* localhost:8000
file_server
}
:{$PORT} {
root * /var/www/html

header {
Access-Control-Allow-Origin *
Access-Control-Allow-Credentials true
Access-Control-Allow-Methods *
Access-Control-Allow-Headers *
defer
}
reverse_proxy /api/* localhost:8000
file_server
}
Dockerfile for Caddy:
# Build React Image
FROM node:latest AS frontend

WORKDIR /frontend

# React / Yarn / Node stuff
ARG VITE_SERVER_URL

COPY ./frontend/package*.json ./frontend/yarn.lock ./

RUN yarn && yarn install

COPY ./frontend .

RUN yarn build


# Caddy Build Image
FROM caddy:2.7.6-alpine

ARG PORT
ARG CADDY_BACKEND_HOST

# Copy Caddyfile
COPY /caddy-server/Caddyfile /etc/caddy/Caddyfile

# Copy the built application from the previous stage
COPY --from=frontend /frontend/dist /srv
COPY --from=frontend /frontend/dist /var/www/html

RUN caddy fmt --overwrite /etc/caddy/Caddyfile
# Build React Image
FROM node:latest AS frontend

WORKDIR /frontend

# React / Yarn / Node stuff
ARG VITE_SERVER_URL

COPY ./frontend/package*.json ./frontend/yarn.lock ./

RUN yarn && yarn install

COPY ./frontend .

RUN yarn build


# Caddy Build Image
FROM caddy:2.7.6-alpine

ARG PORT
ARG CADDY_BACKEND_HOST

# Copy Caddyfile
COPY /caddy-server/Caddyfile /etc/caddy/Caddyfile

# Copy the built application from the previous stage
COPY --from=frontend /frontend/dist /srv
COPY --from=frontend /frontend/dist /var/www/html

RUN caddy fmt --overwrite /etc/caddy/Caddyfile
No description
149 Replies
Percy
Percy•9mo ago
Project ID: N/A
JeffPeterson
JeffPetersonOP•9mo ago
N/A I had realized that I had forgot to add the Docker service with the other containers in my Docker compose file and therefore I could not use the name of the Docker container in my file (for instance backend-django). I updated my code accordingly and now Caddy is acting as a proxy to Django.
Brody
Brody•9mo ago
so you got everything working how you want it?
JeffPeterson
JeffPetersonOP•9mo ago
I would say to some degree, at least locally, although now when attempting to move to railway I get a a "Mixed Block" error so maybe it is something to do with the url I am passing which has http or https? Also I had updated my Caddyfile among other files:
:{$PORT} {
root * /var/www/html

encode gzip

handle /api* {
reverse_proxy {$CADDY_BACKEND_HOST}:{$CADDY_BACKEND_PORT}
}

handle {
root * /var/www/html
try_files {path} /index.html
file_server
}
}
:{$PORT} {
root * /var/www/html

encode gzip

handle /api* {
reverse_proxy {$CADDY_BACKEND_HOST}:{$CADDY_BACKEND_PORT}
}

handle {
root * /var/www/html
try_files {path} /index.html
file_server
}
}
Brody
Brody•9mo ago
I think you should do three services, frontend, backend, and a proxy. currently you are integrating the proxy into the frontend service, I've seen great success with the 3 service method, and I have ready made solutions for that
JeffPeterson
JeffPetersonOP•9mo ago
Ahh I did see that solution here actually: https://github.com/railwayapp-templates/caddy-reverse-proxy/blob/main/Caddyfile. However, do you know if it is possible to have Caddy statically host the frontend files and reverse proxy the backend?
Brody
Brody•9mo ago
I'm sure it's possible, but the three service method would be far more optimal
JeffPeterson
JeffPetersonOP•9mo ago
Wouldn't having caddy serve files directly to clients be faster than proxying another frontend service?
Brody
Brody•9mo ago
it would be extremely negligible when proxying through the private network you linked the Caddyfile for the reverse proxy, but I'm not sure if you've seen it's example project https://railway.app/project/35d8d571-4313-4049-9699-4e7db7f02a2f
JeffPeterson
JeffPetersonOP•9mo ago
oh yes I have seen that actually. The main concern with me doing this is whether or not I can use call my http://backend/api/v1/* routes from my frontend -- but only through the proxy. Would I be able to do this with your example?
Brody
Brody•9mo ago
yes absolutely, you would end up with only a single custom domain in use (on the proxy service only) you access your frontend from the proxy service and then you make calls with paths (not domains) like fetch('/api/users') and the proxy will route the /api/* calls to the backend service through the private network
JeffPeterson
JeffPetersonOP•9mo ago
Okay another concern is how do you serve the dist folder of the frontend? In your example's case it is Vue.
Brody
Brody•9mo ago
yeah Vue that is built with vite, I have a ready made drop in solution for vite with react though though, not that anything actually changes Caddyfile wise
JeffPeterson
JeffPetersonOP•9mo ago
In that case do you have an example of the dist folder being served with a Dockerfile? For instance CMD yarn <some command to serve dist folder>?
Brody
Brody•9mo ago
my examples for serving frontend apps all use nixpacks, but if you are absolutely stuck on using a dockerfile I can whip you up a dockerfile to do that, the CMD command would start caddy though
JeffPeterson
JeffPetersonOP•9mo ago
Okay so I was thinking about using more like 3 Dockerfiles for the: frontend, backend, and caddy
Brody
Brody•9mo ago
here's the vite and react example repo, the magic happens in the nixpacks.toml and Caddyfile https://github.com/brody192/vite-react-template any reason not to use nixpacks?
JeffPeterson
JeffPetersonOP•9mo ago
I am mainly more comfortable with Docker as well as I like to develop locally with Docker and Compose
Brody
Brody•9mo ago
fair enough, and forgive me if it's already been discussed, but does that mean your backend already deploys from a Dockerfile?
JeffPeterson
JeffPetersonOP•9mo ago
That is correct. So the way I have my monorepo set up is I have a React frontend, a Django Backend, and a Caddyfile.
Brody
Brody•9mo ago
I assume in separate sub folders right?
JeffPeterson
JeffPetersonOP•9mo ago
Oh and yes they are all in Docker containers Yes
Brody
Brody•9mo ago
okay cool, well the reverse proxy is already using a dockerfile, so would you like me to whip you up a Dockerfile for the frontend that uses caddy?
JeffPeterson
JeffPetersonOP•9mo ago
Sure if you don't mind!
Brody
Brody•9mo ago
will do, can you tell me more about how you want the frontend built? what node version? yarn, npm, pnpm? do you have the accompanying lock file? is there any environment variables you use in your frontend that I need to be aware about?
JeffPeterson
JeffPetersonOP•9mo ago
- node:21 - yarn - yes - yes: VITE_SERVER_URL I have this for a start:
FROM node:latest

WORKDIR /app

ARG VITE_SERVER_URL

COPY package.json yarn.lock ./
RUN yarn && yarn install

COPY . .

# Build the application
RUN yarn build
FROM node:latest

WORKDIR /app

ARG VITE_SERVER_URL

COPY package.json yarn.lock ./
RUN yarn && yarn install

COPY . .

# Build the application
RUN yarn build
Brody
Brody•9mo ago
good start, I'll finish the rest when I'm back at my computer
JeffPeterson
JeffPetersonOP•9mo ago
Okay thank you. I am curious to see how you will serve the dist directory.
Brody
Brody•9mo ago
with caddy
JeffPeterson
JeffPetersonOP•9mo ago
Awesome, sounds like a plan
Brody
Brody•9mo ago
theres so many other options, but i really like caddy and strongly believe is it far more user friendly than something like nginx
JeffPeterson
JeffPetersonOP•9mo ago
I am coming to believe that myself -- mainly because I think the documentation is more organized than Nginx. Although I wish there was a larger community base / community help
Brody
Brody•9mo ago
and due to a bunch of sane defaults that it comes with, it works great on railway, nginx on the other hand, not so much
JeffPeterson
JeffPetersonOP•9mo ago
Oh true. I did try Nginx without success. I am hoping that with Caddy this time around it will go more smoothly
Brody
Brody•9mo ago
you can definitely write a caddyfile that isnt going to work on railway, but its much easier to write one that works well than it is to write a nginx.conf that works well
JeffPeterson
JeffPetersonOP•9mo ago
Ahh I see. Caddy seems simple enough but I am still new to it to do anything.
Brody
Brody•9mo ago
here's the branch for a react app built with vite that uses yarn and deploys from a dockerfile https://github.com/brody192/vite-react-template/tree/yarn-dockerfile
JeffPeterson
JeffPetersonOP•9mo ago
Ahh so I see that you made the Dockerfile. One thing that interests me is line 10-13 in your Caddyfile where you do:
# server options
servers {
trusted_proxies static private_ranges # trust railway's proxy
}
# server options
servers {
trusted_proxies static private_ranges # trust railway's proxy
}
Does this allow Caddy to talk to Railway's private IPv6 network?
Brody
Brody•9mo ago
nope, everything you expose publicly on railway will be behind a proxy (in this case its both railway's proxy and your own caddy proxy), so that just allows caddy to trust the proxy so you will be able to see the actual client ip instead of just the proxy's ip that would be something like 10.0.0.124
JeffPeterson
JeffPetersonOP•9mo ago
Hmm interesting. So does this mean I do not need the:
handle /api* {
reverse_proxy {$CADDY_BACKEND_HOST}:{$CADDY_BACKEND_PORT}
}
handle /api* {
reverse_proxy {$CADDY_BACKEND_HOST}:{$CADDY_BACKEND_PORT}
}
lines?
Brody
Brody•9mo ago
nope no need, you would use the caddyfile that comes in that repo i just linked
JeffPeterson
JeffPetersonOP•9mo ago
Okay I will give it a try thanks! I would just like to know however, how the Caddyfile is able to get to the Django backend I have. I may have missed something.
Brody
Brody•9mo ago
that would be a job for the caddyfile in the reverse proxy repo you linked, it makes a call through the private network give the overview a read https://railway.app/template/7uDSyj might wanna just deploy that template into your project
JeffPeterson
JeffPetersonOP•9mo ago
Hmm this sounds interesting. So I want to see if I have this right? : - The frontend's static files are served by Caddy (via its Caddyfile) - The "MySite -Caddy Proxy" is also using Caddy but it is proxing (also via a Caddyfile) - The Backend basically has no Caddy file (in my case I would use Django in Gunicorn)
Brody
Brody•9mo ago
yep that's correct
JeffPeterson
JeffPetersonOP•9mo ago
Interesting I never though about using two Docker containers using Caddy. Thanks Brody I will give this a shot! Perhaps I will come back here if all goes well
Brody
Brody•9mo ago
caddy is a web server, but it is also a very good reverse proxy sounds good, let me know if you run into any troubles or even if it all goes well
JeffPeterson
JeffPetersonOP•9mo ago
Hello Brody, I have attempted to deploy the Caddy frontend, Django backend, and Caddy reverse proxy using much of the code you had provided. I have a question concerning the $PORT variable. Does the $PORT need to be the same for all three of these services to work?
Brody
Brody•9mo ago
it doesnt need to be, it can be if you want to though, but i would do something like 3000, 3001
JeffPeterson
JeffPetersonOP•9mo ago
And the service in which caddy acts as a proxy doesn't need a $PORT right?
Brody
Brody•9mo ago
correct, railway assigns a random port and the proxy service will use that, but we only need to define fixed ports of the back and frontend since we need to talk to those over the private network and that wouldnt work with random ports that change every deployment
JeffPeterson
JeffPetersonOP•9mo ago
Hmmm I am getting a 502 error although I have set up the FRONTEND_HOST and BACKEND_HOST variables:
FRONTEND_HOST=${{frontend.RAILWAY_PRIVATE_DOMAIN}}:${{frontend.PORT}}
BACKEND_HOST=${{django.RAILWAY_PRIVATE_DOMAIN}}:${{django.PORT}}
FRONTEND_HOST=${{frontend.RAILWAY_PRIVATE_DOMAIN}}:${{frontend.PORT}}
BACKEND_HOST=${{django.RAILWAY_PRIVATE_DOMAIN}}:${{django.PORT}}
Brody
Brody•9mo ago
502 on the / (root) route?
JeffPeterson
JeffPetersonOP•9mo ago
Yes although I just found that for some reason the FRONTEND_HOST variable was an empty string so I am now redeploying it to see if that helps
Brody
Brody•9mo ago
does it no longer show as empty?
JeffPeterson
JeffPetersonOP•9mo ago
Okay I may have mistyped something but it is rebuilding now
JeffPeterson
JeffPetersonOP•9mo ago
Okay I got it up sort of but I get a 405 error
No description
Brody
Brody•9mo ago
is this to the route route?
JeffPeterson
JeffPetersonOP•9mo ago
Yes this one I believe a /api/v1/ route
Brody
Brody•9mo ago
what is supposed to be returned by that route?
JeffPeterson
JeffPetersonOP•9mo ago
It should just return a JSON response from the backend
Brody
Brody•9mo ago
what method did you call it with?
JeffPeterson
JeffPetersonOP•9mo ago
POST
Brody
Brody•9mo ago
it says it only accepts GET and HEAD
JeffPeterson
JeffPetersonOP•9mo ago
Hmmm so is there a way to configure this in railway? It does say the server is railway and not Caddy. I'm not really sure actually
Brody
Brody•9mo ago
thats just railway's proxy overwriting the server header the allow header is coming from the backend
JeffPeterson
JeffPetersonOP•9mo ago
That's strange I thought if I left the ALLOWED_HOSTS variable alone in the settings.py file in Django all methods would be allowed
Brody
Brody•9mo ago
im not too sure what that setting has to do with request methods?
JeffPeterson
JeffPetersonOP•9mo ago
It probably doesn't, I am actually stumped on this one. I thought it could be CORs thing but I believe I already fixed that
Brody
Brody•9mo ago
have you tried using GET? thats what it allows
JeffPeterson
JeffPetersonOP•9mo ago
I mean I can directly hit Django with a REST API request if it doesn't go through the proxy That is a good point, I should try that real quick
JeffPeterson
JeffPetersonOP•9mo ago
Seems like I am getting an unsafe-url Referrer Policy when I do a GET request. I am not sure if that is really relevant to the issue though:
No description
Brody
Brody•9mo ago
these would be stuff your backend is setting but are you getting the correct json back?
JeffPeterson
JeffPetersonOP•9mo ago
Actually I don't get anything in my response:
No description
Brody
Brody•9mo ago
can you send me the link so i can see this stuff for myself?
JeffPeterson
JeffPetersonOP•9mo ago
Yes, please fill out the form to trigger the POST request: https://apricot.up.railway.app/login
Brody
Brody•9mo ago
will do when back at my computer! send me the backend domain please
JeffPeterson
JeffPetersonOP•9mo ago
backend-django.railway.internal
Brody
Brody•9mo ago
the public one wouldnt be much of a private network if i could call that internal domain
JeffPeterson
JeffPetersonOP•9mo ago
I didn't know I needed public one if caddy can proxy Django via the internal one?
Brody
Brody•9mo ago
you dont, this is just for testing
JeffPeterson
JeffPetersonOP•9mo ago
Oh okay that makes sense I will generate one then https://backend-django-production.up.railway.app/
Brody
Brody•9mo ago
show me your caddyfile for the proxy service please
JeffPeterson
JeffPetersonOP•9mo ago
# Caddy configuration file
{
# debug

# server options
servers {
# trust railway's proxy
trusted_proxies static private_ranges
}
}


# Comment out for development
# :{$CADDY_BACKEND_PORT} {
:{$PORT} {

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
# # proxy all requests for /api/* to the backend, configure this variable in the service settings
# reverse_proxy {$BACKEND_HOST}
# }

# configure this variable in the service settings
reverse_proxy {$BACKEND_HOST}
}
# Caddy configuration file
{
# debug

# server options
servers {
# trust railway's proxy
trusted_proxies static private_ranges
}
}


# Comment out for development
# :{$CADDY_BACKEND_PORT} {
:{$PORT} {

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
# # proxy all requests for /api/* to the backend, configure this variable in the service settings
# reverse_proxy {$BACKEND_HOST}
# }

# configure this variable in the service settings
reverse_proxy {$BACKEND_HOST}
}
Brody
Brody•9mo ago
in a code block if you dont mind
JeffPeterson
JeffPetersonOP•9mo ago
Okay I edited it
Brody
Brody•9mo ago
i think i have an idea of whats going on let me test some things
JeffPeterson
JeffPetersonOP•9mo ago
Awesome!
Brody
Brody•9mo ago
what is BACKEND_HOST set to?
JeffPeterson
JeffPetersonOP•9mo ago
FRONTEND_HOST=frontend.railway.internal:4173
BACKEND_HOST=backend-django.railway.internal:8000
FRONTEND_HOST=frontend.railway.internal:4173
BACKEND_HOST=backend-django.railway.internal:8000
I hardcoded these values because I was getting some parsing issue
Brody
Brody•9mo ago
okay i was wrong on my first idea, i have a new idea what is the start command for django or CMD command in your case
JeffPeterson
JeffPetersonOP•9mo ago
So basically at the end of the Django's Dockerfile there is a CMD command that calls a shell script that looks like this:
exec python manage.py migrate & gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
exec python manage.py migrate & gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
Brody
Brody•9mo ago
what is BACKEND_DJANGO_PORT set to
JeffPeterson
JeffPetersonOP•9mo ago
BACKEND_DJANGO_PORT=8000
Brody
Brody•9mo ago
also you should use a double && there
JeffPeterson
JeffPetersonOP•9mo ago
Hmm do you think that is what is causing the issue?:
No description
JeffPeterson
JeffPetersonOP•9mo ago
Oh it seems that you had hit the register endpoint a few times so apparently Django is getting something
Brody
Brody•9mo ago
no but you still should use && send me the logs for your proxy service
JeffPeterson
JeffPetersonOP•9mo ago
using provided configuration

admin endpoint started

started background certificate maintenance

server running

autosaved config (load with --resume flag)

serving initial configuration

cleaning storage unit

finished cleaning storage units
using provided configuration

admin endpoint started

started background certificate maintenance

server running

autosaved config (load with --resume flag)

serving initial configuration

cleaning storage unit

finished cleaning storage units
Brody
Brody•9mo ago
thats it?
JeffPeterson
JeffPetersonOP•9mo ago
This one right?:
No description
Brody
Brody•9mo ago
yeah do you have a start command for django set elsewhere?
JeffPeterson
JeffPetersonOP•9mo ago
Such as python manage.py runserver? I don't include that in the container I am pretty sure
Brody
Brody•9mo ago
railway service settings, a procfile, a railway.json, anything
JeffPeterson
JeffPetersonOP•9mo ago
Hmm I haven't used anything like that. I quit using a procfile after moving away from Heroku
Brody
Brody•9mo ago
make this change, and then send me the new logs from django
JeffPeterson
JeffPetersonOP•9mo ago
Okay sure thing! Okay new logs:
/usr/local/lib/python3.11/site-packages/langchain/chat_models/__init__.py:31: LangChainDeprecationWarning: Importing chat models from langchain is deprecated. Importing from langchain will no longer be supported as of langchain==0.2.0. Please import from langchain-community instead:

`from langchain_community.chat_models import ChatOpenAI`.

To install langchain-community run `pip install -U langchain-community`.

warnings.warn(

Operations to perform:

Apply all migrations: Core, admin, auth, authtoken, contenttypes, sessions, token_blacklist

Running migrations:

No migrations to apply.
/usr/local/lib/python3.11/site-packages/langchain/chat_models/__init__.py:31: LangChainDeprecationWarning: Importing chat models from langchain is deprecated. Importing from langchain will no longer be supported as of langchain==0.2.0. Please import from langchain-community instead:

`from langchain_community.chat_models import ChatOpenAI`.

To install langchain-community run `pip install -U langchain-community`.

warnings.warn(

Operations to perform:

Apply all migrations: Core, admin, auth, authtoken, contenttypes, sessions, token_blacklist

Running migrations:

No migrations to apply.
Brody
Brody•9mo ago
show me this please
JeffPeterson
JeffPetersonOP•9mo ago
FROM python:3.11.6

WORKDIR /app/django_project

COPY ./backend-django/requirements.txt ./

ADD ./rabbitmq_immersio_utils ./rabbitmq_immersio_utils

RUN pip install --no-cache-dir -r requirements.txt

COPY ./backend-django /app

# RUN apt-get install systemd && systemctl enable rabbitmq-server
WORKDIR /app/django_project

EXPOSE 8000
EXPOSE 5672
EXPOSE 15672

# We need environment variables during build time (during RUN commands)
# Therefore we use ARG

# 👇 Defined in compose
ARG RABBITMQ_HOST
ARG RABBITMQ_DEFAULT_USER
ARG RABBITMQ_DEFAULT_PASS
ARG RABBITMQ_PORT
ARG RABBITMQ_GUI_PORT

# RUN python manage.py makemigrations && python manage.py migrate

# CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
CMD ["sh", "set_up.sh"]
FROM python:3.11.6

WORKDIR /app/django_project

COPY ./backend-django/requirements.txt ./

ADD ./rabbitmq_immersio_utils ./rabbitmq_immersio_utils

RUN pip install --no-cache-dir -r requirements.txt

COPY ./backend-django /app

# RUN apt-get install systemd && systemctl enable rabbitmq-server
WORKDIR /app/django_project

EXPOSE 8000
EXPOSE 5672
EXPOSE 15672

# We need environment variables during build time (during RUN commands)
# Therefore we use ARG

# 👇 Defined in compose
ARG RABBITMQ_HOST
ARG RABBITMQ_DEFAULT_USER
ARG RABBITMQ_DEFAULT_PASS
ARG RABBITMQ_PORT
ARG RABBITMQ_GUI_PORT

# RUN python manage.py makemigrations && python manage.py migrate

# CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
CMD ["sh", "set_up.sh"]
That is the Dockerfile and the set_up.sh file is a one liner basically
Brody
Brody•9mo ago
send the set_up.sh please
JeffPeterson
JeffPetersonOP•9mo ago
exec python manage.py migrate && gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
exec python manage.py migrate && gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
Brody
Brody•9mo ago
JeffPeterson
JeffPetersonOP•9mo ago
I'm not sure if I used that tool you sent correctly
Brody
Brody•9mo ago
there's no logs from gunicorn itself, something real fishy is going on here
JeffPeterson
JeffPetersonOP•9mo ago
Oh well isn't that because I am not running gunicorn with the --debug flag or something?
Brody
Brody•9mo ago
no, gunicorn by default will print logs like what it's listening on do you have a gunicorn config?
JeffPeterson
JeffPetersonOP•9mo ago
I scraped by without making one
Brody
Brody•9mo ago
well then something real odd is happening here
JeffPeterson
JeffPetersonOP•9mo ago
No description
Brody
Brody•9mo ago
reads like an AI wrote it, all high level help without any actual real solutions this is for access logs, not applicable here because we don't even see boot logs set BACKEND_HOST to https://backend-django-production.up.railway.app
JeffPeterson
JeffPetersonOP•9mo ago
Sure thing
Brody
Brody•9mo ago
what's the current state of the django deployment
JeffPeterson
JeffPetersonOP•9mo ago
No description
Brody
Brody•9mo ago
I'm talking about the deployment state like active or completed
JeffPeterson
JeffPetersonOP•9mo ago
Completed
JeffPeterson
JeffPetersonOP•9mo ago
No description
Brody
Brody•9mo ago
so django never ran
JeffPeterson
JeffPetersonOP•9mo ago
That makes sense I don't see the 0.0.0.0:8000 port information on there
Brody
Brody•9mo ago
alright well it's 5:50am and I haven't slept yet, so I wish you good luck in finding out why django isn't running! we can pick this back up tomorrow
JeffPeterson
JeffPetersonOP•9mo ago
Okay thanks for the help Brody! I will an eye out for it and see what I have for you tomorrow!
Brody
Brody•9mo ago
sounds good
JeffPeterson
JeffPetersonOP•9mo ago
Hello Brody I had determined that issue preventing my frontend from accessing backend via the caddy proxy was due to how I had my Caddyfile configured where handle_path should have been handle as the url path of the REST API request was being stripped by caddy as it made its way to the backend. I have now fixed this with the updated Caddyfile:
# Caddy configuration file
{
# server options
servers {
# trust railway's proxy
trusted_proxies static private_ranges
}
}

:{$PORT} {


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

# proxy all requests for /* to the frontend, configure this variable in the service settings
reverse_proxy {$FRONTEND_HOST}
}
# Caddy configuration file
{
# server options
servers {
# trust railway's proxy
trusted_proxies static private_ranges
}
}

:{$PORT} {


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

# proxy all requests for /* to the frontend, configure this variable in the service settings
reverse_proxy {$FRONTEND_HOST}
}
Thank you again Brody for your help! It works good now!
Brody
Brody•9mo ago
haha i did this locally
Brody
Brody•9mo ago
No description
Brody
Brody•9mo ago
but wanted to figure out why we weren't seeing gunicorns logs first
JeffPeterson
JeffPetersonOP•9mo ago
Lol. Yeah I so what I found out about the Gunicorn logs is that when I temporarily commented the migrate command in:
exec python manage.py migrate & gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
exec python manage.py migrate & gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
Where it became:
exec gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
exec gunicorn django_project.wsgi:application --bind [::]:${BACKEND_DJANGO_PORT} --timeout 0
The logs appeared. Although I think the real reason why they appeared is because the && used to be & or something. Once I had used handle the backend (Gunicorn) was able to get logs.
Brody
Brody•9mo ago
the proxy using handle has nothing to do with gunicorn's boot logs
JeffPeterson
JeffPetersonOP•9mo ago
Well I was never hitting Gunicorn so I had never received logs for it.
Brody
Brody•9mo ago
im not talking about access logs, im talking about boot logs
JeffPeterson
JeffPetersonOP•9mo ago
Right so those were because of the .sh file. Now it shows:
[INFO] Listening at: http://[::]:8000 (7)
[7] [INFO] Using worker: sync
[8] [INFO] Booting worker with pid: 8
[INFO] Listening at: http://[::]:8000 (7)
[7] [INFO] Using worker: sync
[8] [INFO] Booting worker with pid: 8
Brody
Brody•9mo ago
those are the boot logs may i ask why you have omitted admin off, persist_config off, auto_https off, and log ?
JeffPeterson
JeffPetersonOP•9mo ago
Oh. To be honest with you I was not aware of those settings.
Brody
Brody•9mo ago
they where in the original caddyfile
JeffPeterson
JeffPetersonOP•9mo ago
Oh I see what you are saying. I accidently thought they were comments because my IDE did not have Caddyfile support at that time. I could probably re-add them
Brody
Brody•9mo ago
ah gotcha
JeffPeterson
JeffPetersonOP•9mo ago
Alright thanks for the help. I think your example repo (https://github.com/railwayapp-templates/caddy-reverse-proxy/tree/main) does the job!
GitHub
GitHub - railwayapp-templates/caddy-reverse-proxy
Contribute to railwayapp-templates/caddy-reverse-proxy development by creating an account on GitHub.
Brody
Brody•9mo ago
that do be my repo glad i could help you get this all working!
Want results from more Discord servers?
Add your server