D
Dokploy3mo ago
monte

Connecting backend to frontend

Hi, I have a backend service, which uses docker-compose to deploy. I was able to successfully deploy it to dokploy. This service has a fastapi webserver, which i would like to expose as api.myproject.com. I would like to keep this webserver internal only and not expose to public, such that only frontend is allowed to talk to it. The frontend is deployed as an application on the same vps. What changes do i need to make to make this work? If there is any guidebook/examples, that would be really helpful. Both the backend and frontend are separate git repos. Thanks for time and efforts.
46 Replies
Firdaus
Firdaus3mo ago
why dont you host the frontend also in the same docker-compose. That way you can make them to be in the same network and access each other
monte
monteOP3mo ago
They are in separate git repository
Firdaus
Firdaus3mo ago
you can make a docker image of them but, with your current setup, is it giving any error when the frontend is making a request to the backend?
monte
monteOP3mo ago
I was relying on dokploy to build the docker image and deploy. Instead of me setting it up. I haven't yet planned for it as it seemed rather complex. I am using the following configuration in my backend
networks:
- dokploy-network
labels:
- traefik.enable=true
- traefik.http.routers.saralprod-saral-prod-b0moyj.rule=Host(`api.saral.club`)
# - traefik.http.routers.saralprod-saral-prod-b0moyj.entrypoints=web
- traefik.http.routers.saralprod-saral-prod-b0moyj.internal=true
- traefik.http.services.saralprod-saral-prod-b0moyj.loadbalancer.server.port=8000
networks:
- dokploy-network
labels:
- traefik.enable=true
- traefik.http.routers.saralprod-saral-prod-b0moyj.rule=Host(`api.saral.club`)
# - traefik.http.routers.saralprod-saral-prod-b0moyj.entrypoints=web
- traefik.http.routers.saralprod-saral-prod-b0moyj.internal=true
- traefik.http.services.saralprod-saral-prod-b0moyj.loadbalancer.server.port=8000
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
Need to be in one network! And you can allow cors from origin ’’’container-name’’’
monte
monteOP3mo ago
I found similar to this in dokploy docs
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
In backend add front-end container name And it’s done
monte
monteOP3mo ago
when I curl from inside of my frontend application container, I get the error could not resolve host. I do curl http://api.saral.club/info
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
You can use axios,fetch in front
monte
monteOP3mo ago
is this a dokploy setting that i can configure?
Firdaus
Firdaus3mo ago
that means you are exposing that to the internet I would assume
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
Which stack are you using?
Firdaus
Firdaus3mo ago
cause if you keep it internal, then you can just do port and not assign a domain
monte
monteOP3mo ago
I don't want to expose it to internet. this means, instead of this: - traefik.http.routers.saralprod-saral-prod-b0moyj.rule=Host(api.saral.club) it should simply be - traefik.http.routers.saralprod-saral-prod-b0moyj.rule=Host(8000`) it's fastapi on backend, and sveltekit on frontend
Firdaus
Firdaus3mo ago
i dont think you would need that not even sure you would need traefik to be connected to backend at least i dont think because what you are exposing is only the frontend to the internet right so only frontend has access to backend
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
version: "3.8" services: backend: build: ./backend ports: - "8000" environment: - FASTAPI_ENV=production networks: - mynetwork frontend: build: ./frontend ports: - "5173:5173" depends_on: - backend networks: - mynetwork networks: mynetwork: driver: bridge
monte
monteOP3mo ago
when I am inside the server, I am able to connect with curl http://localhost:8000/ but when I am in container the same doesn't work
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
Some things like this you need
monte
monteOP3mo ago
yes, I am only exposing frontend to the internet and backend is exposed only to the backend
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
const API_URL = "http://backend:8000/api"; // backend container name in svelt export async function getData() { const res = await fetch(${API_URL}/hello); const data = await res.json(); return data; }
DJKnaeckebrot
DJKnaeckebrot3mo ago
You just published api and web to the internet with that, he didnt want to have it exposed 😄
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
You don’t understand)
Firdaus
Firdaus3mo ago
and also i dont think this will work for his setup because what you shared is a docker-compose setup. He has his as 2 seperate service
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
No expose by default dokploy no deploy nothing) In internet
DJKnaeckebrot
DJKnaeckebrot3mo ago
I do very well, you shouldn't use ports for that cause that will mount servers port to container port. you need to use expose to expose it from the container but not on the host
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
It will work. You can put docker name no build method
Firdaus
Firdaus3mo ago
No description
Firdaus
Firdaus3mo ago
Also, I think what DJK was refering to was this about exposing your ports
DJKnaeckebrot
DJKnaeckebrot3mo ago
yup thats one of the points. Using port:port WILL expose the port to the internet. You need to expose it in the dockerfile so you can than access it via internal docker network but ill remain silent as apprently i dont undestand 😉
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
Just close 8000 port with ufw 😀
DJKnaeckebrot
DJKnaeckebrot3mo ago
sorry buts thats not smart at all there are better ways of not exposing it at all minimizng the risk of an attack on the port.
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
Close redoc,docs , and add origin cors And no risk And add token for api
Firdaus
Firdaus3mo ago
I believe this is a bit of a hack. I mean, yes it works of course, but it can be solved by configuring the docker-compose correctly
DJKnaeckebrot
DJKnaeckebrot3mo ago
+1 and it should be done by setting it up properly initially ill move myself out of this conversation. if anyone needs my opinion on anything lmk
Henrik
Henrik3mo ago
My understanding is that the sveltekit's inbuilt backed is to be used as a proxy to the actual API hosted with flask and the flask is not supposed to be exposed to the internet. If it's important to keep the fast api as a separate service I would add the --hostname as a custom start command to make it reachable from Sveltekit
monte
monteOP3mo ago
yes, I am keeping fastapi as separate service and not exposed to internet. where should i add this flag? are you referring to dokploy run command/
Firdaus
Firdaus3mo ago
do you have a dockerfile in your backend and frontend repo
monte
monteOP3mo ago
yes
Firdaus
Firdaus3mo ago
Is there a CMD line somewhere in there something like this
FROM python:3.11-slim

... the rest of your dockerfile ...

CMD ["python3", "-m", "app.bot.main"] <---- this one
FROM python:3.11-slim

... the rest of your dockerfile ...

CMD ["python3", "-m", "app.bot.main"] <---- this one
I would think thats where you add the network flag or hostname actually nevermind maybe there are some cli stuff you need to do, cause from what I am reading, you need to make a network and put both of your container in the same network so they can communicate with eac oter
# Create a network
docker network create my-network

# Run your containers on this network
docker run --name backend --network my-network [backend-image]
docker run --name frontend --network my-network [frontend-image]
# Create a network
docker network create my-network

# Run your containers on this network
docker run --name backend --network my-network [backend-image]
docker run --name frontend --network my-network [frontend-image]
something like this, but thats as far as my knowledge goes and this is done on the docker level, not a container level
monte
monteOP3mo ago
but isn't dokploy-network doing this?
𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲
. I said this )
Firdaus
Firdaus3mo ago
as far as my understand goes, that is a syntax for docker-compose, and you are not using docker-compose, right what you said is that you have a Dockerfile, not a docker-compose
monte
monteOP3mo ago
apparently uvicorn doesn't have the --hostname flag, it does have --host flag though
Henrik
Henrik3mo ago
I think you can set the hostname in the custom command section, but I have not verified it. If you change the flask application to a docker compose file you can set the hostname in the compose. You can still build it with your own Dockerfile. See picture one. This allows you to reach the container using that hostname. In the second picture you can see the URL just uses the hostname.
No description
No description
monte
monteOP3mo ago
Thanks a lot henrik, your proposed solution worked. I have both, docker-compose.yml for backend and dockerfile for frontend. Backend depends on other services which themselve have their dockerfile. Neverthless, henrik proposed solution worked. Thank your time @Firdaus Also thanks for your time @𝗠𝗿𝟭𝗕𝗹𝗮𝘇𝗲 and @DJKnaeckebrot
Henrik
Henrik3mo ago
Awesome!

Did you find this page helpful?