how to access a localhost app from a container in docker-compose - docker

I have a web app running outside of a container (localhost:8090).
How can I access it from within a container in a docker-compose network?
I tried to follow this answer that help for docker.
version: '3.6'
services:
postgres:
image: postgres
restart: always
volumes:
- db_data:/var/lib/postgresql/data
networks:
- host
graphql-engine:
image: hasura/graphql-engine:v1.0.0-beta.6
ports:
- "8080:8080"
depends_on:
- "postgres"
restart: always
environment:
HASURA_GRAPHQL_AUTH_HOOK: "http://localhost:8090/verify"
volumes:
db_data:

Add network_mode: "host" to your graphql-engine: and remove port mapping:
graphql-engine:
image: hasura/graphql-engine:v1.0.0-beta.6
depends_on:
- "postgres"
restart: always
network_mode: "host"
environment:
HASURA_GRAPHQL_AUTH_HOOK: "http://localhost:8090/verify"
graphql-engine would listen on host port 8080 and would be able to connect to localhost:8090
To make sure it worked, verify /etc/hosts file from the docker host is inside graphql-engine contianer .
Docs

Related

Connection between docker containers as localhost

i am trying to dockerize my web application. i am running a apache webserver + mariadb and redis server as you can see in my docker-compose file combined with an nginx proxy to use local domains and ssl.
everything works fine as long is i use the container names to connect to mysql / redis. I dont want to change all localhosts in my code to the mysql / redis container names.
Is there a way to keep "localhost" as Host instead of the containers name?
version: "3.5"
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: portal-proxy
networks:
- portal
ports:
- "80:80"
- "443:443"
volumes:
- ./certs:/etc/nginx/certs
- /var/run/docker.sock:/tmp/docker.sock:ro
portal:
image: portal:latest
container_name: portal-webserver
networks:
- portal
volumes:
- ./portal:/var/www/html/portal
links:
- db
restart: always
environment:
VIRTUAL_HOST: portal.dev
db:
image: mariadb:latest
container_name: portal-db
networks:
- portal
ports:
- "3306:3306"
restart: always
environment:
MYSQL_DATABASE: portal
MYSQL_USER: www-data
MYSQL_PASSWORD: www-data
MYSQL_ROOT_PASSWORD: asdf1234
volumes:
- ./db:/docker-entrypoint-initdb.d
- ./db:/var/lib/mysql
redis:
image: redis:latest
container_name: portal-redis
environment:
- ALLOW_EMPTY_PASSWORD=yes
networks:
- portal
ports:
- "6379:6379"
networks:
portal:
name: portal
Use a common hostname (staging.docker.host) on all containers, that resolves to the docker host's ip 1.2.3.4.
So adding this to containers:
extra_hosts:
- "staging.docker.host:1.2.3.4"
and use that name (staging.docker.host) in all you connection endpoints.
On you local machine you also add (staging.docker.host) to your /etc/hosts or C:\Windows\System32\drivers\etc\hosts with localhost 127.0.0.1 staging.docker.host.

Access localhost and docker network using docker-compose

I have two different services running in a single docker-compose file. I talk to each service by referring to the service name of the containers.
Now I want my container A to access localhost as well. For this when I added the configuration of 'network_mode=host', but this creates an error now stating that container A cannot talk to container B.
version: '2'
services:
rocketchat:
image: myimage
environment:
- MONGO_URL=mongodb://mongo:27017/dbname
depends_on:
- mongo
ports:
- 3000:3000
network_mode: host
mongo:
image: mongo:3.2
ports:
- 27017:27017
For each compose file docker-compose creates a network so in this case, should I manually assign the containers to a dedicated network as well? Or is there any workaround to access both the networks?
try to add links :
version: '2'
services:
rocketchat:
image: myimage
environment:
- MONGO_URL=mongodb://mongo:27017/dbname
depends_on:
- mongo
ports:
- 3000:3000
links:
- mongo
#network_mode: host
mongo:
image: mongo:3.2
ports:
- 27017:27017
and you do not need network_mode: host if you use the links
EDIT - Other solution:
version: '2'
services:
rocketchat:
image: myimage
environment:
- MONGO_URL=mongodb://localhost:27017/dbname
depends_on:
- mongo
ports:
- 3000:3000
network_mode: host
mongo:
image: mongo:3.2
ports:
- 27017:27017
network_mode: host

How ports notation in docker compose service works?

in docker-compose.yml,
What is the difference between in following ports notations?
ports:
- "5000:5000"
resp:
ports:
- "8080"
or no ports at all.
For example in following docker-compose.yml, the mongodb service must be exposing a port to communicate with node service, but no port is specified
services:
node:
build:
context: .
dockerfile: node.dockerfile
ports:
- "3000:3000"
networks:
- nodeapp-network
depends_on:
- mongodb
mongodb:
image: mongo
networks:
- nodeapp-network
networks:
nodeapp-network:
driver: bridge
source: https://github.com/DanWahlin/NodeExpressMongoDBDockerApp
However in these docker-compose.yml, there are ports awlays specified with either 27017:27017 or 8080 notation.
services:
nginx:
container_name: nginx
image: ${DOCKER_ACCT}/nginx
build:
context: .
dockerfile: .docker/nginx.${APP_ENV}.dockerfile
links:
- node1:node1
- node2:node2
- node3:node3
ports:
- "80:80"
- "443:443"
networks:
- codewithdan-network
node1:
container_name: node-codewithdan-1
image: ${DOCKER_ACCT}/node-codewithdan
build:
context: .
dockerfile: .docker/node-codewithdan.${APP_ENV}.dockerfile
ports:
- "8080"
volumes:
- .:/var/www/codewithdan
working_dir: /var/www/codewithdan
env_file:
- ./.docker/env/app.${APP_ENV}.env
depends_on:
- mongo
- redis
networks:
- codewithdan-network
node2:
container_name: node-codewithdan-2
image: ${DOCKER_ACCT}/node-codewithdan
build:
context: .
dockerfile: .docker/node-codewithdan.${APP_ENV}.dockerfile
ports:
- "8080"
volumes:
- .:/var/www/codewithdan
working_dir: /var/www/codewithdan
env_file:
- ./.docker/env/app.${APP_ENV}.env
depends_on:
- mongo
- redis
networks:
- codewithdan-network
node3:
container_name: node-codewithdan-3
image: ${DOCKER_ACCT}/node-codewithdan
build:
context: .
dockerfile: .docker/node-codewithdan.${APP_ENV}.dockerfile
ports:
- "8080"
volumes:
- .:/var/www/codewithdan
working_dir: /var/www/codewithdan
env_file:
- ./.docker/env/app.${APP_ENV}.env
depends_on:
- mongo
- redis
networks:
- codewithdan-network
mongo:
container_name: mongo
image: ${DOCKER_ACCT}/mongo
build:
context: .
dockerfile: .docker/mongo.dockerfile
ports:
- "27017:27017"
env_file:
- ./.docker/env/mongo.${APP_ENV}.env
networks:
- codewithdan-network
redis:
container_name: redis
image: ${DOCKER_ACCT}/redis
build:
context: .
dockerfile: .docker/redis.${APP_ENV}.dockerfile
ports:
- "6379"
networks:
- codewithdan-network
networks:
codewithdan-network:
driver: bridge
source: https://github.com/DanWahlin/CodeWithDanDockerServices
Can you explain the difference?
Typical Docker containers run a long-running server listening on some TCP port. Other containers on the same Docker network can reach that container using the container’s name (docker run --name, container_name: directive) as a DNS name and the port the server is running on. In Docker Compose, Compose creates a Docker network per Compose YAML file, and also makes services available under their key in the YAML file. This works even if no ports: are specified.
So, for instance, if your docker-compose.yml file says
services:
mongo:
image: mongo
others:
env:
MONGODB_HOST: mongo
MONGODB_PORT: 27017
then the MongoDB container will be reachable on that host name and (default) port, even though it doesn’t explicitly have a ports:.
If you do declare a ports: then the container will be reachable from outside Docker space. If you only have one port it’s the port number of the server, and Docker picks the host port; this isn’t useful in most cases (but it’s guaranteed to not hit a port conflict). If you have two ports they’re the host port and internal service port. You can also specify a host IP address to bind(2) to.
Presence or absence of ports: doesn’t affect inter-dontainer communication. Always use the container’s name (or Docker-compose.yml service name) and the “internal” port number the server is listening on.
Either specify both ports (HOST:CONTAINER), or just the container port (an ephemeral host port is chosen). So in your case 8080 is container port
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "6060:6060/udp"
From here
The ephemeral port range is configured by /proc/sys/net/ipv4/ip_local_port_range kernel parameter, typically ranging from 32768 to 61000.
Either way, you should be able to peek at what Docker has accomplished in your network stack by examining your NAT tables. from here
In docker compose by default no ports will be created in case they collide with already opened ports

Docker Compose | Virtual Hosts

Whats wrong in my code? thanks in advance!
I'm trying to set up a virtual host for my docker container.
On localhost: 8000 works perfectly, but when I try to access through http: //borgesmelo.local/ the error ERR_NAME_NOT_RESOLVED appears, what can be missing?
This is my -> docker-compose.yml
version: '3.3'
services:
borgesmelo_db:
image: mariadb:latest
container_name: borgesmelo_db
restart: always
volumes:
- ./mariadb/:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: My#159#Sql
MYSQL_PASSWORD: My#159#Sql
borgesmelo_ws:
image: richarvey/nginx-php-fpm:latest
container_name: borgesmelo_ws
restart: always
volumes:
- ./public/:/var/www/html
ports:
- "8000:80"
borgesmelo_wp:
image: wordpress:latest
container_name: borgesmelo_wp
volumes:
- ./public/:/var/www/html
restart: always
environment:
VIRTUAL_HOST: borgesmelo.local
WORDPRESS_DB_HOST: borgesmelo_db:3306
WORDPRESS_DB_PASSWORD: My#159#Sql
depends_on:
- borgesmelo_db
- borgesmelo_ws
borgesmelo_phpmyadmin:
image: phpmyadmin/phpmyadmin:latest
container_name: borgesmelo_phpmyadmin
links:
- borgesmelo_db
ports:
- "8001:80"
environment:
- PMA_ARBITRARY=1
borgesmelo_vh:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "8002:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
default:
external:
name: nginx-proxy
This is my hosts file (/etc/hosts) [macOS]
#DOCKER
127.0.0.1:8000 borgesmelo.local
Hosts file doesn't support ports as it is for name lookup only. So you would have to set your hosts file to:
127.0.0.1 borgesmelo.local
Then access your application with http://borgesmelo.local:8000.
If you are listening on port 8000 because you already have something else on port 80, then consider using nginx as a reverse proxy and then you can route to different applications based on the server_name. That way, you can access multiple applications through port 80. If you're dealing with docker containers, then consider looking into Traefik as a reverse proxy.

Can't to connect to postgres container

I define postgres server in docker-compose.yml:
db:
image: postgres:9.5
expose:
- 5432
Then in another docker container I tried to connect to this postgres container. But it gives an error with warning:
Is the server running on host "db" (172.22.0.2) and accepting
data-service_1 | TCP/IP connections on port 5432?
Why container can't to connect to another by provided information (host="db" and port=5432)?
PS
Full docker-compose.yml:
version: "2"
services:
data-service:
build: .
depends_on:
- db
ports:
- "50051:50051"
db:
image: postgres:9.5
depends_on:
- data-volume
environment:
- POSTGRES_USER=cobrain
- POSTGRES_PASSWORD=a
- POSTGRES_DB=datasets
ports:
- "8000:5432"
expose:
- 5432
volumes_from:
- data-volume
# - container:postgres9.5-data
restart: always
data-volume:
image: busybox
command: echo "I'm data container"
volumes:
- /var/lib/postgresql/data
Solution #1. Same file.
To be able to access the db container, you have to define your other containers in context of docker-compose.yml. When containers are started, each container gets all other containers mapped in /etc/hosts.
Just do
version: '2'
services:
web:
image: your/image
db:
image: postgres:9.5
If you do not wish to put your other containers into the same docker-compose.yml, there are other solutions:
Solution #2. IP
Do docker inspect <name of your db container> and look for IPAddress directive in the result listing. Use that IPAddress as host to connect to.
Solution #3. Networks
Make your containers join same network. For that, under each service, define:
services:
db:
networks:
- myNetwork
Don't forget to change db for each container you are starting.
I usually go with the first solution during development. I use apache+php as one container and pgsql as another one, a separate DB for every project. I do not start more than one setting of docker-compose.yml, so in this case defining both containers in one .yml config is perfect.
the depends on is not correct. i would try to use other paramters like LINKS and environment:
version: "2"
services:
data-service:
build: .
links:
- db
ports:
- "50051:50051"
volumes_from: ["db"]
environment:
DATABASE_HOST: db
db:
image: postgres:9.5
environment:
- POSTGRES_USER=cobrain
- POSTGRES_PASSWORD=a
- POSTGRES_DB=datasets
ports:
- "8000:5432"
expose:
- 5432
#volumes_from:
#- data-volume
# - container:postgres9.5-data
restart: always
data-volume:
image: busybox
command: echo "I'm data container"
volumes:
- /var/lib/postgresql/data
this one works for me (not postgres but mysql)

Resources