We're making move to Docker from Vagrant.
Our first aim is to move some services out first. In this case I'm trying to host a redis server on a docker container and connect to it from my vagrant machine.
On the vagrant machine there is an apache2 webserver hosting a Laravel App
It's the connection part I'm struggling with, currently I have
Dockerfile.redis
FROM redis:3.2.12
RUN redis-server
docker-compose.yml (concatenated)
version: '3'
services:
redis:
build:
context: .
dockerfile: Dockerfile.redis
working_dir: /opt
ports:
- "6379:6379"
I've tried various way to connect to this:
Attempt 1
Using the host ip 10.0.2.2 in the config in Laravel. Results in a "Connection refused"
Attempt 2
Set up a network in the docker compose
redis:
build:
context: .
dockerfile: Dockerfile.redis
working_dir: /opt
network:
- app_net:
ipv4_address: 172.16.238.10
ports:
- "6379:6379"
networks:
app_net:
driver: bridge
ipam:
driver: default
- subnet: 172.16.238.0/24
This instead results in timeouts. Most solutions seem to require a gateway configured on the network, but this isn't configurable in docker compose 3. Is there maybe a way around this?
If anyone can give any guidance that would be great, most guides talk about connect to dockers in a vagrant rather than from one.
FYI - this is using Docker for Mac and version 3 of docker compose
We were able to get this going use purely docker compose and not having a dockerfile for redis at all:
redis:
image: redis
container_name: redis
working_dir: /opt
ports:
- "6379:6379"
Once done like this, able to connect to redis from within the vagrant file using
redis-cli -h 10.0.2.2
Or as the following in laravel, although we're using environment variables to set these)
'redis' => [
'client' => 'phpredis',
'default' => [
'host' => '10.0.2.2',
'password' => null,
'port' => 6379,
'database' => 0,
]
]
Your Attempt 1 should work actually. When you create a service without defining a network, docker-compose automatically creates a bridge network. For example:
When you run docker-compose up on this:
version: '3'
services:
redis:
build:
context: .
dockerfile: Dockerfile.redis
working_dir: /opt
ports:
- "6379:6379"
docker-compose creates a bridge network named <project name>_default, which is docker_compose_test_default in my case, as shown below:
me#myshell:~/docker_compose_test $ docker network ls
NETWORK ID NAME DRIVER SCOPE
6748b1ea4b85 bridge bridge local
4601c6ea30c3 docker_compose_test_default bridge local
80033acaa6e4 host host local
When you inspect your container, you can see that an IP has already been assigned to it:
docker inspect e6b196f952af
...
"Networks": {
"bridge": {
...
"Gateway": "172.18.0.1",
"IPAddress": "172.18.0.2",
You can then use this IP to connect from the host or your vagrant box:
me#myshell:~/docker_compose_test $ redis-cli -h 172.18.0.2 -p 6379
172.18.0.2:6379> ping
PONG
Related
In the docker compose file i added api server as a service and mongodb is installed in my local pc. But when the api run in docker container it could not connect with 127.0.0.1:27017.
Here is the docker-compose file.
networks:
test_network:
name: test_network
driver: bridge
services:
api:
container_name: api
build: ./api
ports:
- "3031:3031"
networks:
- test_network
Why this problem is happening
and how i can resolve this problem ?
It happens because the IP address 127.0.0.1:27107 refers to the container itself.
You have to address the above port, but the host ip as I explained here.
I have a docker-compose file with three services (Solr, PostgreSQL and pgAdmin), all sharing a Docker network.
version: '2'
services:
solr:
image: solr:7.7.2
ports:
- '8983:8983'
networks:
primus-dev:
ipv4_address: 10.105.1.101
volumes:
- data:/opt/solr/server/solr/mycores
entrypoint:
- docker-entrypoint.sh
- solr-precreate
- primus
- /opt/solr/server/solr/configsets/sample_techproducts_configs
environment:
- SOLR_HEAP=2048m
logging:
options:
max-size: 5m
db:
image: "postgres:11.5"
container_name: "primus_postgres"
ports:
- "5432:5432"
networks:
primus-dev:
ipv4_address: 10.105.1.102
volumes:
- primus_dbdata:/var/lib/postgres/data
environment:
- POSTGRES_DB=primus75
- POSTGRES_USER=primus
- POSTGRES_PASSWORD=primstav
pgadm4:
image: "dpage/pgadmin4"
networks:
primus-dev:
ipv4_address: 10.105.1.103
ports:
- "3050:80"
volumes:
- /home/nils/docker-home:/var/docker-home
environment:
- PGADMIN_DEFAULT_EMAIL=nils.weinander#kulturit.se
- PGADMIN_DEFAULT_PASSWORD=dev
networks:
primus-dev:
driver: bridge
ipam:
config:
- subnet: 10.105.1.0/24
volumes:
data:
primus_dbdata:
This works just fine after docker-compose up (at least pgAdmin can talk to PostgreSQL).
But, then I have a script (actuall a make target, but that's not the point here), which builds, runs and deletes a container with docker-compose run:
docker-compose run -e HOME=/app -e PYTHONPATH=/app/server -u 0 --rm backend \
bash -c 'cd /app/server && python tools/reindex_mp.py -s -n'
This does not work as the reindex_mp.py cannot reach Solr on 10.105.1.101, as the one shot container is not on the same Docker network. So, is there a way to tell docker-compose to use a named network with docker-compose run? docker run has an option --network but that is not available for docker-compose.
You can create a docker network outside your docker-compose and use that network while running services in docker-compose.
docker network create my-custom-created-network
now inside your docker-compose, use this network like this:
services:
serv1:
image: img
networks:
my-custom-created-network
networks:
my-custom-created-network:
external: true
The network creation example creates a bridge network.
To access containers across hosts, use an overlay network.
You can also use the network created inside docker-compose and connect containers to that network.
Docker creates a default network for docker-compose and services which do not have any network configuration specified, will be using default network created by docker for that compose file.
you can find the network name by executing this command:
docker network ls
Use the network appropriate name while starting a container, like this
docker run [options] --network <network-name> <image-name>
Note: Containers in a same network are accessible using container names, you can leverage this instead of using ips
I have a java application, that connects through external database through custom docker network
and I want to connect a Redis container.
docker-redis github topic
I tried the following on the application config:
1 localhost:6379
2 app_redis://app_redis:6379
3 redis://app_redis:6379
nothing works on my setup
docker network setup:
docker network create -d bridge --subnet 192.168.0.0/24 --gateway 192.168.0.1 mynet
Connect to a Database Running on Your Docker Host
PS: this might be off-topic, how I can add the network on docker-compose instead of external
docker-compose:
services:
app-kotin:
build: ./app
container_name: app_server
restart: always
working_dir: /app
command: java -jar app-server.jar
ports:
- 3001:3001
links:
- app-redis
networks:
- front
app-redis:
image: redis:5.0.9-alpine
container_name: app-redis
expose:
- 6379
networks:
front:
external:
name: mynet
with the setup above how can I connect through a Redis container?
Both containers need to be on the same Docker network to communicate with each other. The app-kotin container is on the front network, but the app-redis container doesn't have a networks: block and so goes onto an automatically-created default network.
The simplest fix from what you have is to also put the app-redis container on to the same network:
app-redis:
image: redis:5.0.9-alpine
networks:
- front
The Compose service name app-redis will then be usable as a host name, from other containers on the same network.
You can simplify this setup considerably. You don't generally need to manually specify IP configuration for the Docker-private networks. Compose can create the network for you, and in fact it will create a network named default for you. (Networking in Compose discusses this further.) links: and expose: aren't used in modern Docker networking; Compose can provide a default container_name: for you; and you don't need to repeat the working_dir: or command: from the image. Removing all of that would leave you with:
version: '3'
services:
app-kotin:
build: ./app
restart: always
ports:
- '3001:3001'
app-redis:
image: redis:5.0.9-alpine
The server container will be able to use the other container's Compose service name app-redis as a host name, even with this minimal configuration.
I want to create a PostgreSQL cluster composed by a master and two slaves within three containers. I want to do that with docker-compose. Everything works fine but I cannot ping containers from my Mac.
Here the code of my docker-compose.yml.
On Stackoverflow there is this thread How could I ping my docker container from my host that address docker standalone and not docker-compose.
version: '3.6'
volumes:
pgmaster_volume:
pgslave1_volume:
pgslave2_volume:
services:
pgmaster:
container_name: pgmaster
build:
context: ../src
dockerfile: Dockerfile
image: docker-postgresql:latest
environment:
NODE_NAME: pgmaster # Node name
ports:
- 5422:5432
volumes:
- pgmaster_volume:/home/postgres/data
networks:
cluster:
ipv4_address: 10.0.2.31
aliases:
- pgmaster.domain.com
pgslave1:
container_name: pgslave1
build:
context: ../src
dockerfile: Dockerfile
image: docker-postgresql:latest
environment:
NODE_NAME: pgslave1 # Node name
ports:
- 5441:5432
volumes:
- pgslave1_volume:/home/postgres/data
networks:
cluster:
ipv4_address: 10.0.2.32
aliases:
- pgslave1.domain.com
pgslave2:
container_name: pgslave2
build:
context: ../src
dockerfile: Dockerfile
image: docker-postgresql:latest
environment:
NODE_NAME: pgslave2 # Node name
ports:
- 5442:5432
volumes:
- pgslave2_volume:/home/postgres/data
networks:
cluster:
ipv4_address: 10.0.2.33
aliases:
- pgslave2.domain.com
networks:
cluster:
driver: bridge
ipam:
config:
- subnet: 10.0.2.1/24
On my Mac, I have a 192.168.0.0 local network. I expect that doing ping 10.0.2.31 I can ping my container but this is not possible. I think this is due to Linux VM created inside Mac where containers live and the IPs are not reachable outside this VM.
Can someone help me to understand how to make the above three IP reachable? IPs are reachable from one container to another.
Here my full code:
https://github.com/sasadangelo/docker-postgres
you should be able to ping your containers from you host.
via public ip:
just use their public ip. (you had been trying to ping your
container local ip, inside the docker network)
how to find the container public IP?
you can get it by running ifconfig inside the container.
or
or by running on your host docker container inspect <container_id>.
it should be there under NetworkSettings.<network_name>.IPAddress )
via container name/id
docker is running some sort of dns on your machine so you can also use
the container name or id - ping <container_name/id>
note
the way to access your containers outside the docker network is via their published ports. you have bound port 5432 on the docker network to port 5442 on your host, therefore the container should listen and accept traffic at 127.0.0.1:5442 (thats your localhost at the port you've bound)
I have the following docker-compose file. I am trying to access the service running in the container, from the host.
But the hostname never resolves.
version: '2'
networks:
mynet:
driver: bridge
services:
grpcserver:
image: test/image
volumes:
- ./:/var/local/git
ports:
- 50051:50051
stdin_open: true
tty: true
hostname: grpcserver
networks:
- mynet
entrypoint: bash ../var/local/git/service/start.sh
When I exec to the container I can telnet grpcserver 50051 to the running service using the hostname successfully. But from the host, I cannot.
Version
docker-compose version 1.16.1, build 6d1ac21
Docker containers are not resolved using their name on the host. They can only be resolved inside other containers. The name would be dependent on whether you are trying to connect from another service in same compose/network or a different one.
If you need your containers to be discoverable from host you need to use a tool like dnsmasq. See the answer below on more details on how to do such a setup
Access to container by his hostname from host-mascine