How to link frontend and backend docker containers

should I define a client service in the docker-compose file situated in the server side project?

This is one option, and this is probably the easiest and most straightforward. docker-compose, by default, sets up a docker network for the services you define per docker-compose.yml. Since all the services are on the same network then, they can resolve each other by hostname, i.e. your client application would reach backend like http://app:9000/api/login/, where you use the docker-compose service name as the host.

Or is it okay that they run sepratly ?

It's ok to run them separately if you want. You will need to do a little modification to ensure the frontend can reach the backend. Two options would be:

  1. Create a docker bridge network manually. Here are the docs for that. You'd just want to define a network with docker network create, add that network in your docker-compose, and make sure you put your frontend container in the same network when you docker run it by using the --network option. Similarly, you can just define a new network in your docker-compose.yml, skip creating it by hand, and put your frontend container in that network.

Any of these #1 options end up being brittle because you'd need to make sure your network is there before running the frontend, or possibly the docker-compose stack. Regardless, it's an option.

In bridge mode, which is the network mode default, referencing localhost in your container does not reference your host. For example, curl localhost:9000 from your frontend will try to curl the frontend container on port 9000. curl localhost:9000 from your app service should succeed, because it's curling itself.

  1. Use the host network driver, which will put your containers on your host network by removing the Docker network isolation. Then everything would just use localhost:<port> to talk to each other.

If you don't have a good case for keeping the frontend out of the docker-compose.yml, I would encourage you to just add it there and be done. Doing that will offload a lot of the thinking to docker-compose. It will also scale better if you use a CI pipeline, and it will be easier to hand off to another developer because it's all in a neat package. Good luck!


It's ok to have them running separately.

You need to connect them by placing both frontend and backend in same docker network (you don't need to put db in that network).

Just create manually a standalone network and then reference it in docker-compose as external - same for backend and frontend. Then you will be able to use the service names to make frontend talk to backend.

frontend-docker-compose.yml:

services:
  frontend:
    networks:
      project_network:
networks:
  project_network:
    external: true

backend-docker-compose.yml:

services:
  app:
    networks:
      project_network:
networks:
  project_network:
    external: true

docker network create --attachable project_network