Resolve container name in extra_hosts option in docker-compose - docker

I need to curl my API from another container.
Container 1 is called nginx
Container 2 is called fpm
I need to by able to bash into my fpm container and curl the nginx container.
Config:
#docker-compose.yaml
services:
nginx:
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
volumes:
- ./docker/nginx/conf/dev/api.conf:/etc/nginx/conf.d/default.conf
ports:
- 8080:80
links:
- fpm
fpm:
build:
context: .
dockerfile: ./docker/fpm/Dockerfile
volumes:
- .:/var/www/html
- ./docker/fpm/conf/dev/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
- ./docker/fpm/conf/dev/api.ini:/usr/local/etc/php/conf.d/api.ini
env_file:
- ./docker/mysql/mysql.env
- ./docker/fpm/conf/dev/fpm.env
links:
- mysql
shm_size: 256M
extra_hosts:
- myapi.docker:nginx
My initial thought was to slap it in the extra_hosts option like:
extra_hosts:
- myapi.docker:nginx
But docker-compose up fails with:
ERROR: for apiwip_fpm_1 Cannot create container for service fpm: invalid IP address in add-host: "nginx"
I have seen some examples of people using docker's network configuration but it seems over the top to just resolve an address.
How can I resolve/eval the IP address of the container rather than just passing it literally?

Add network aliases in the default network.
version: "3.7"
services:
nginx:
# ...
networks:
default:
aliases:
- example.local
browser-sync:
# ...
depends_on:
- nginx
command: "browser-sync start --proxy http://example.local"

services:
nginx:
build:
context: .
dockerfile: ./docker/nginx/Dockerfile
volumes:
- ./docker/nginx/conf/dev/api.conf:/etc/nginx/conf.d/default.conf
ports:
- 8080:80
networks:
my_network:
aliases:
- myapi.docker
- docker_my_network
fpm:
build:
context: .
dockerfile: ./docker/fpm/Dockerfile
volumes:
- .:/var/www/html
- ./docker/fpm/conf/dev/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
- ./docker/fpm/conf/dev/api.ini:/usr/local/etc/php/conf.d/api.ini
env_file:
- ./docker/mysql/mysql.env
- ./docker/fpm/conf/dev/fpm.env
links:
- mysql
shm_size: 256M
networks:
- my_network
networks:
my_network:
driver: bridge
add custom network and add container to that network
by default if you curl nginx container from fpm you will curl localhost, so we need to add alias to be the same as your servername in the nginx configuration
with this solution you can curl myapi.docker from the fpm container
#edward let me know if this solution worked for you
Edit:
Jack_Hu is right, I removed extra_hosts. Network alias is enough.

I solved this kind of issue by using links instead of extra_hosts.
In that case, just set link alias can do your favor.
service fpm setting
links
- nginx:myapi.docker
See docker-compose links documentation, The alias name can be the domain which appears in your code.

From the docker documentation,
https://docs.docker.com/compose/networking/
You should be able to use your service name (in this case nginx) as a hostname from within your docker network. So you can bash into my FPM container and call curl nginx and the docker will resolve it for you. Hope this helps.

Quick fix is to point it to a dynamic IP generated by docker. This may change though so... yeah.
Find your networks:
docker network ls
NETWORK ID NAME DRIVER SCOPE
72fef1ce7a50 apiwip_default bridge local <-- here
cdf9d5b885f6 bridge bridge local
2f4f1e7038fa host host local
a96919eea0f7 mgadmin_default bridge local
30386c421b70 none null local
5457b953fadc website2_default bridge local
1450ebeb9856 anotherapi_default bridge local
Copy the NETWORK ID
docker network inspect 72fef1ce7a50
"Containers": {
"345026453e1390528b2bb7eac4c66160750081d78a77ac152a912f3de5fd912c": {
"Name": "apiwip_nginx_1",
"EndpointID": "6504a3e4714a6ba599ec882b21f956bfd1b1b7d19b8e04772abaa89c02b1a686",
"MacAddress": "02:42:ac:14:00:05",
"IPv4Address": "172.20.0.5/16", <-- CIDR block
"IPv6Address": ""
},
"ea89d3089193825209d0e23c8105312e3df7ad1bea6b915ec9f9325dfd11736c": {
"Name": "apiwip_fpm_1",
"EndpointID": "dc4ecc7f0706c0586cc39dbf8a05abc9cc70784f2d44c90de2e8dbdc9148a294",
"MacAddress": "02:42:ac:14:00:04",
"IPv4Address": "172.20.0.4/16",
"IPv6Address": ""
}
},
Add the IP address from that CIDR block to the extra_hosts option:
extra_hosts:
- myapi.docker:172.20.0.5

Related

docker host: use docker dns to resolve container name from host network

I need to resolve a container name to the IP Address from the docker host.
The reason for this is, i need a container to run on the host network, but it must be also able to resolve the container "backend" which it connects also to. (The container must be send & receive multicast packets)
docker-compose.yml
version: "3"
services:
database:
image: mongo
container_name: database
hostname: database
ports:
- "27017:27017"
backend:
image: "project/backend:latest"
container_name: backend
hostname: backend
environment:
- NODE_ENV=production
- DATABASE_HOST=database
- UUID=5025f846-7587-11ed-9ca7-8b992b5e7dd3
ports:
- "8080:8080"
depends_on:
- database
tty: true
frontend:
image: "project/frontend:latest"
container_name: frontend
hostname: frontend
ports:
- "80:80"
- "443:443"
depends_on:
- backend
environment:
- BACKEND_HOST=backend
connector:
image: "project/connector:latest"
container_name: connector
hostname: connector
ports:
- "1900:1900/udp"
#expose:
# - "1900/udp"
environment:
- NODE_ENV=production
- BACKEND_HOST=backend
- STARTUP_DELAY=1500
depends_on:
- backend
network_mode: host
tty: true
How can i resolve the hostname "backend" via docker from the docker host?
dig backend #127.0.0.11 & dig backend #172.17.0.1 did not work.
A test with a docker ubuntu image & socat proves, that i can receive ssdp multicast packets:
docker run --net host -it --rm ubuntu
socat UDP4-RECVFROM:1900,ip-add-membership=239.255.255.250:0.0.0.0,fork -
The only problem i now have is the DNS/Container name resolution from the host (network).
TL;DR
The container "connector" must be on the host network,but also be able to resolve the container name "backend" to the docker internal IP Address.
NOTE: Perhaps this is better suited on superuser or similar?

Failed to add interface to sandbox

I'm trying to run two Docker containers attached to a single Docker network using Docker Compose.
I'm running into the following error when I run the containers:
Error response from daemon: failed to add interface veth5b3bcc5 to sandbox:
error setting interface "veth5b3bcc5" IP to 172.19.0.2/16:
cannot program address 172.19.0.2/16 in sandbox
interface because it conflicts with existing
route {Ifindex: 10 Dst: 172.19.0.0/16 Src: 172.19.0.1 Gw: <nil> Flags: [] Table: 254}
My docker-compose.yml looks like this:
version: '3'
volumes:
dsn-redis-data:
driver: local
dsn-redis-conf:
driver: local
networks:
dsn-net:
driver: bridge
services:
duty-students-notifier:
image: duty-students-notifier:latest
network_mode: host
container_name: duty-students-notifier
build:
context: ../
dockerfile: ./docker/Dockerfile
env_file: ../.env
volumes:
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
networks:
- dsn-net
restart: always
dsn-redis:
image: redis:latest
expose:
- 5432
volumes:
- dsn-redis-data:/var/lib/redis
- dsn-redis-conf:/usr/local/etc/redis/redis.conf
networks:
- dsn-net
restart: always
Thanks!
The network_mode: host setting generally disables Docker networking, and can interfere with other options. In your case it looks like it might be trying to apply the networks: configuration to the host system network layer.
network_mode: host is almost never necessary, and deleting it may resolve this issue.

Docker-compose bridge network & host remote port forwarding at the same container

I'm trying to make service that can forward remote database port to container and at the same time can be accessible by alias hostname from other containers to work with them.
I am think that make all containers communicate by host network is bad practice, so i am trying to setup that configuration.
When i am triyng to add to php-fpm service network with driver: host, docker says
only one instance of "host" network is allowed
When i am trying to set php-fpm service with this
networks
- host
Docker says that he cant find out network with this name.
When i try to define network in docker-compose by id of built-in host, it just cant start this container.
This is my docker-compose:
version: '3.2'
networks:
backend-network:
driver: bridge
frontend-network:
driver: bridge
volumes:
redis-data:
home-dir:
services:
&app-service app: &app-service-template
build:
context: ./docker/app
dockerfile: Dockerfile
volumes:
- ./src:/app:rw
- home-dir:/home/user
hostname: *app-service
environment:
FPM_PORT: &php-fpm-port 9001
FPM_USER: "${USER_ID:-1000}"
FPM_GROUP: "${GROUP_ID:-1000}"
APP_ENV: local
HOME: /home/user
command: keep-alive.sh
networks:
- backend-network
&php-fpm-service php-fpm:
<<: *app-service-template
user: 'root:root'
restart: always
hostname: *php-fpm-service
ports: [*php-fpm-port]
environment:
FPM_PORT: *php-fpm-port
FPM_USER: "${USER_ID:-1000}"
FPM_GROUP: "${GROUP_ID:-1000}"
APP_ENV: local
HOME: /home/user
entrypoint: /fpm-entrypoint.sh
command: php-fpm --nodaemonize -R -d "opcache.enable=0" -d "display_startup_errors=On" -d "display_errors=On" -d "error_reporting=E_ALL"
networks:
- backend-network
- frontend-network
nginx:
build:
context: ./docker/nginx
dockerfile: Dockerfile
restart: always
working_dir: /usr/share/nginx/html
environment:
FPM_HOST: *php-fpm-service
FPM_PORT: *php-fpm-port
ROOT_DIR: '/app/public' # App path must equals with php-fpm container path
volumes:
- ./src:/app:ro
ports: ['9999:80']
depends_on:
- *php-fpm-service
networks:
- frontend-network
Network scheme (question about green line):
Host works on Debian 7 (updates prohibited) and conainer works with lastest Alpine

Accessing Docker from host network using domain name

hey guys I have a docker container A with a domain name attached to it on a host B with a domain name attached to it as well.....how can I access the said container A via A's domain name rather than an B's ip address or domain name from computer C on the host B's local network.
thus C -> A( via wwww.cname.url) rather than C -> B( www.bname.url:port) -> A
E.G.
the following is a docker-compose with services
version: "3.2"
services:
php:
links:
- mysql
image: arm32v6/php:7.1.24-fpm-alpine3.8-lavalite
networks:
- backend
working_dir: /var/www/html
volumes:
- ./website/:/var/www/html/
privileged: true
node:
domainname: docker.local
hostname: node
networks:
frontend:
aliases:
- node.docker.local
links:
- "apache:dev.docker.local"
depends_on:
- apache
image: arm32v7/node:latest
entrypoint: yarn
command: twill-dev
volumes:
- ./website:/usr/src/app
working_dir: /usr/src/app
ports:
- "3000:3000"
- "3001:3001"
apache:
domainname: docker.local
hostname: dev
image: arm32v7/httpd:2.4
depends_on:
- php
- mysql
networks:
frontend:
aliases:
- apache
- dev.docker.local
backend:
aliases:
- apache
privileged: true
ports:
- "8880:80"
working_dir: /var/www/html
volumes:
- ./website/:/var/www/html/
- ./httpd.conf:/usr/local/apache2/conf/httpd.conf
- ./fpm.conf:/usr/local/apache2/conf/extra/httpd-vhosts.conf
mysql:
image: yobasystems/alpine-mariadb:arm32v7
volumes:
- ./datadir:/var/lib/mysql
networks:
- backend
environment:
- MYSQL_VERSION=5.7
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_USER=test
- MYSQL_PASSWORD=testpass
- MYSQL_DATABASE=test_db
networks:
frontend:
external:
name: localnet
backend:
I want to be able to access service apache by its domain name set to dev.docker.local the ip of which is on a network 17.18.0.1/24
The host has an IP which is on a network 192.168.1.0/24 with a domain name dev.server.local
I have a dev pc on the network 192.168.1.0/24 and it can access the service containers via the hosts IP and usually a port exposed for the particular service.
UPDATE
The host can be reached at server.local from outside the network
my network interface has the following entries
dns-search server.local
dns-domain server.local
the docker container has the following
hostname nginx
domainname server.local
do I need to also edit a host file or resolv.conf file?
It seems the host is running avahi service discovery. Would this affect anything?
So can I
set an internal domain set to the host and have docker containers on subdomains? How would outside devices access this via the domain?
attach the docker container to be on the host's network thus having an ip in the 192.168.1.0/24 and being able to be pinged by devices on that network as well. Will the domain resolve to it?
Is there a dynamic DNS software I can use that can hook this up to me so that its not a manual process. Thus it will detect the server and route incoming requests to it via the domain name?
You can do this by configuring an nginx container with the containers bound to the subdomain.
So for example the host is accessible by domain example.com and you want the php container to be accessible on php.example.com you could use a setup like the following:
services:
php:
image: arm32v6/php:7.1.24-fpm-alpine3.8-lavalite
environment:
- VIRTUAL_HOST=php.example.com
nginx-proxy:
image: jwilder/nginx-proxy
depends_on:
- php
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
Any request to the subdomain would first be send to the host, this is bound by nginx, which in turn registers that because the subdomain php is requested it should send the user to that container.
I hope this can help you and if you have any questions please let me know

Connect to Redis Docker container from Vagrant machine

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

Resources