I don't understand at all about ports in Docker. I couldn't find any good material explaining this to me. I just found out that there is a host port and an internal one. As I understand it, the external one must be unique so that you can connect from outside to this service, and the internal one can be anything and is used by the containers themselves.
I have a problem. When I try to access the main service, no error occurs; everything goes well along the path http://localhost:3002. But when you try to access another service, test - http://localhost:3003/, the error Error: Failure when receiving data from the peer occurs. I do this through insomnia, but it’s unlikely that it affects anything.
I also don’t understand what to write in prism/DATABASE_URL in my env file, do I write port 5432, or should I write an external port? Or write an internal port? Or should I always write 5432?
DATABASE_URL=postgresql://user:123456@main_db:5432/mydb
services:
main:
ports:
- 3002:3000
depends_on:
- main_db
networks:
- backend
main_db:
image: postgres:16
container_name: main_db
ports:
- 5432:5432
volumes:
- main_db_pgdata:/var/lib/postgresql/data
networks:
- backend
test:
ports:
- 3003:3000
depends_on:
- test_db
networks:
- backend
test_db:
image: postgres:16
container_name: test_db
ports:
- 5433:5432
volumes:
- test_db_pgdata:/var/lib/postgresql/data
networks:
- backend
volumes:
main_db_pgdata: {}
test_db_pgdata: {}
networks:
backend:
driver: bridge
Here is a stripped down version of my composition.
I tried to make a unique internal port for each service, but I always had problems when trying to start the service, there were some problems with the database, so I just stopped. I don’t even know which way to think, the AI says the same thing
I don't understand at all about ports in Docker. I couldn't find any good material explaining this to me. I just found out that there is a host port and an internal one. As I understand it, the external one must be unique so that you can connect from outside to this service, and the internal one can be anything and is used by the containers themselves.
I have a problem. When I try to access the main service, no error occurs; everything goes well along the path http://localhost:3002. But when you try to access another service, test - http://localhost:3003/, the error Error: Failure when receiving data from the peer occurs. I do this through insomnia, but it’s unlikely that it affects anything.
I also don’t understand what to write in prism/DATABASE_URL in my env file, do I write port 5432, or should I write an external port? Or write an internal port? Or should I always write 5432?
DATABASE_URL=postgresql://user:123456@main_db:5432/mydb
services:
main:
ports:
- 3002:3000
depends_on:
- main_db
networks:
- backend
main_db:
image: postgres:16
container_name: main_db
ports:
- 5432:5432
volumes:
- main_db_pgdata:/var/lib/postgresql/data
networks:
- backend
test:
ports:
- 3003:3000
depends_on:
- test_db
networks:
- backend
test_db:
image: postgres:16
container_name: test_db
ports:
- 5433:5432
volumes:
- test_db_pgdata:/var/lib/postgresql/data
networks:
- backend
volumes:
main_db_pgdata: {}
test_db_pgdata: {}
networks:
backend:
driver: bridge
Here is a stripped down version of my composition.
I tried to make a unique internal port for each service, but I always had problems when trying to start the service, there were some problems with the database, so I just stopped. I don’t even know which way to think, the AI says the same thing
Share Improve this question edited 7 hours ago David Maze 159k45 gold badges242 silver badges283 bronze badges asked 7 hours ago IsatIsat 1 New contributor Isat is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.1 Answer
Reset to default 1If you have some sort of server process, it listens on a port. The PostgreSQL server listens on port 5432; a typical Node Express server listens on port 3000; and so on. Docker's internal networking layer means you don't need to reconfigure the server's port to not have conflicts (your sample setup has two services internally listening on each of ports 5432 and 3000 and that's okay).
The process inside the container must be listening on 0.0.0.0 ("all interfaces") and not 127.0.0.1 ("only the container-private localhost").
The second
ports:
number must exactly match the port number the process is using. You can't pick an arbitrary number for this port, and it's not usually worth it to try to reconfigure a prebuilt image to pick a different port.When you are calling between containers:
- You always use the service's internal port.
ports:
are not required or considered. - Use the service's Compose service name as a host name. You don't need to set
container_name:
. - If you do have
networks:
then the two containers need a network in common. For almost all Compose applications, though, the correct setup is to delete all of thenetworks:
blocks, and let Compose create a network nameddefault
for you.
So for your server, you should set
DATABASE_URL
to include the Compose service name and the standard PostgreSQL port;main_db:5432
as you've shown it. If you need to run migrations from outside Docker, the host name would be different (probablylocalhost
) and the port number would be the firstports:
number.- You always use the service's internal port.
You mention a
.env
file. Compose has two separate levels of environment-variable handling. Unless you explicitly specify a Composeenv_file:
, a.env
file on the host system will not be automatically injected into containers.In the setup you show, you have two separate copies of the application in the same Compose file. Compose has the notion of a project name, though, and it includes the project name in names it generates. You can combine this with Compose environment-variable substitution to have only one copy of the application in the Compose file.
So I'd probably rewrite the Compose file as:
version: '3.8' # not harmful, compatible with older versions of Compose tool, useful for documenting new Compose feature requirements
services:
app:
build: .
ports:
- ${APP_PORT:-3002}:3000
depends_on:
- db
environment:
DATABASE_URL: postgresql://user:passw0rd@db:5432/mydb
db:
image: postgres:16
volumes:
- db_pgdata:/var/lib/postgresql/data
environment: { ... }
volumes:
db_pgdata:
I've removed the unnecessary networks:
and container_name:
settings, and added in a couple of build:
and environment:
blocks you probably already have. And there's only one copy of the setup here.
You can run one copy of this listening on port 3002 (the default from the Compose file) as
docker-compose up -d
and a second copy listening on port 3003
APP_PORT=3003 docker-compose -p test up -d
Note that the DATABASE_URL
is specified in the Compose file (it is very specific to this Compose-based setup), but conversely that it is identical across the two copies of the Compose setup.