Docker-compose assigns non coherent IPs for my containers - docker

I have several containers on my server, and almost using the same docker-composer.yaml file :
version: '3.5'
services:
myAppX:
container_name: myprojectX
build:
context: .
dockerfile: ./.docker/Dockerfile
env_file: .env
ports:
- 8009:80
volumes:
- ${DIR_IMAGES_MAPS}:/app/public/maps
I've notice the containers don't always have the same IP :
docker inspect -f '{{.Id}};{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
696fa33040be3c13f03e7f7697450d753dcb87aeff8629b2418b17a2b3d0baff;192.168.96.2
49ab637898ecb79e5b18a22e6d9466ab6f712960695046ba0c233437475cad3d;192.168.32.2
ba9912bb221b53f7b319430f1624a17a8d25ababb68854717e88026e448539fc;172.26.0.2
b21ad6f8bd9770de20edf55a07e3e2531d4a5d67f2cc15749146c16f27400263;172.25.0.2
4bb3b317e22fa96cef5e219a81909052a899fbc1a48401c63f292050ab3734a7;172.23.0.2
74df8ec521bbe08fcfc3851558349add7c4bead2314ee49e63f80a63d67420c6;172.22.0.2
35bbfe5d3e52a4b2ae5907e815a4cdbd0b7c4cd5ac21c348c8aa65d078ea892f;172.21.0.3
0f0ad718b5110f6ce8c4bd44a931f9ad10fc48d485bda9d6708767cf9ba486e9;172.21.0.4
5c590d55a128e69b256a92bff703c112db6f4bc9f2bbdb6c503f40afa24395d2;172.21.0.2
006269c383d5a424ba123abc1d54e802bf297542f623b6925002cbc365c16d85;172.20.0.2
5d13ed8352c833d18ee16aa7b9fec2604c600032bdcd8d10d9c94ea0faaca539;172.19.0.2
I don't get why the two first containers have an IP with 192. and not like the other with 172. ! All my containers have to use the same IP (172.) due to firewall rules ! But with Composer v3 I can no more define static IP !
How can I force docker to always have the same IP type ?

Edit (or create) /etc/docker/daemon.json and add this :
{
"bip":"172.17.0.1/16"
}
Then restart docker service.
IP ends with 1 and not 0 ! Maybe Docker don't want a mask but he need the very first IP !

Related

error while removing network: <network> id has active endpoints

I am trying run docker compose down using jenkins job.
"sudo docker-compose down --remove-orphans"
I have used --remove-orphans command while using the docker-compose down.
Still it gives below error.
Removing network. abc
error while removing network: network id ************ has active endpoints
Failed command with status 1: sudo docker-compose down --remove-orphans
Below is my docker compose:
version: "3.9"
services:
abc:
image: <img>
container_name: 'abc'
hostname: abc
ports:
- "5****:5****"
- "1****:1***"
volumes:
- ~/.docker-conf/<volume>
networks:
- <network>
container-app-1:
image: <img2>
container_name: 'container-app-1'
hostname: 'container-app-1'
depends_on:
- abc
ports:
- "8085:8085"
env_file: ./.env
networks:
- <network>
networks:
<network>:
driver: bridge
name: <network>
To list your networks, run docker network ls. You should see your <network> there. Then get the containers still attached to that network with (replacing your network name at the end of the command):
docker network inspect \
--format '{{range $cid,$v := .Containers}}{{printf "%s: %s\n" $cid $v.Name}}{{end}}' \
"<network>"
For the various returned container id's, you can check why they haven't stopped (inspecting the logs, making sure they are part of the compose project, etc), or manually stop them if they aren't needed anymore with (replacing the <cid> with your container id):
docker container stop "<cid>"
Then you should be able to stop the compose project.
There is a situation when there are no containers at all, but there is an error. Then systemctl restart docker helped me
This can also happen, when you have a db instance running on separate container and using the same network. In this case, removing the db instance using the command
docker container stop "<cid>"
will stop the container. We can find the container id that is using the network by using the command provided by #BMitch
docker network inspect \
--format '{{range $cid,$v := .Containers}}{{printf "%s: %s\n" $cid $v.Name}}{{end}}' \
"<network>"
But in my case, when I did that, it also made that postgres instance "orphaned". Then i did
docker-compose up -d --remove-orphans
After that, I booted up a new db instance (postgres) using docker compose file and mapped the volume of data directory of that to the data directory of the previous db instance.
volumes:
- './.docker/postgres/:/docker-entrypoint-initdb.d/'
- ~/backup/postgress:/var/lib/postgresql/data
My Problem was solved only by restarting the docker and then deleting the container manually from the docker desktop.

docker-compose how to define container scoped network like in docker run?

Running 2 containers where mycontainer2 must use the same network stack of mycontainer1. As if the two containers were running in the same machine. Here how I try to do by using docker run with --network container:xxx
$ docker run -it --rm --name mycontainer1 -p 6666:7777 myregistry/my-container1:latest
$ docker run -it --rm --network container:mycontainer1 --name mycontainer2 myregistry/my-container2:latest
I tried to replicate this behavior using docker-compose instead. But the networks: definition of docker-compose.yaml doesn't indicate something equivalent to the --network container:xxx option of docker run. Is it possible in docker-compose to configure two containers to use the same network stack?
This is a network_mode: setting.
version: '3.8'
services:
mycontainer1:
image: myregistry/my-container1:latest
ports: ['6666:7777']
mycontainer2:
image: myregistry/my-container2:latest
network_mode: service:mycontainer1 # <---
Since Compose will generally pick its own container names, this service:name form uses the container matching the named Compose service. (If you override container_name: then you can also use container:mycontainer1 the same way you did with docker run.)
Creating an external network and use it inside docker-compose YAML manifest might help. Here is how you do it.
version: '3.7'
networks:
default:
external:
name: an-external-network
services:
my-container1:
...
my-container2:
...
Note: use docker network create command to create an-external-network before running docker-compose up command.

Docker DNS with Multiple Projects Using the Same Network

I have the following docker-compose.yml file:
version: '3'
services:
frontend:
image: alpine
command: tail -f /dev/null
networks:
- shared
- default
backend:
image: alpine
command: tail -f /dev/null
networks:
- shared
- default
networks:
shared:
external: true
Based on the file from above I create two projects which use the same network (shared) and the same service names (frontend and backend):
docker-compose -p foo up -d
docker-compose -p bar up -d
Does the DNS of docker make sure that docker-compose -p foo exec frontend ping backend only resolves to the backend container in project foo and vice versa for project bar?
According to https://github.com/docker/compose/issues/4645, the resolve order in this case in non deterministic. Since the network is being converted to unordered dict in golang, the order is not preserved. Which implies https://github.com/docker/libnetwork/blob/master/sandbox.go#L593 the order of endpoints being queried don't match the order of network.
The solution is to define https://docs.docker.com/compose/compose-file/compose-file-v2/#priority if using docker-compose version 2. Or fully qualified dns name as service.network such as backend.foo_default or backend.shared.
Based on your setup I have used nslookup to find out whether the DNS resolution is isolated or not.
$ docker-compose -p foo exec frontend nslookup backend
Name: backend
Address 1: 172.19.0.2 foo_backend_1.shared
Address 2: 172.19.0.4 bar_backend_1.shared
As you can see from the output above, backend resolves to both of the containers.
If you use docker swarm you can qualify hostnames with the service name to disambiguate containers. But I don't believe docker-compose does this.

docker-compose down - network is external, skipping

I'm trying bring down all services for an external network defined in my docker-compose file (using version 2).
When I try to do a docker-compose down, I get a message stating,
Network 'your_network' is external, skipping
Is there a way, using docker-compose, to stop and remove all the containers for a user-defined or external network?
I've encountered the same error. docker-compose can only stop the containers started by docker-compose.
In my case: the containers that I wanted to stop were started by docker run.
So I stopped the containers one by one. then started them with the docker-compose.yml
Not sure if you are the same case.
This isn't an error. You have a network declared as "external", mostly meaning that it may be used by other services or other docker-compose files. So when you stop those services, the network gets "skipped", because the network is shared among all services that reference it, and it would create an error to try to delete the external network.
Docker error messages (and in general) sucks as always.
Originally I had multiple services that used a custom network, as shown here:
version: '3'
networks:
mynet:
external: true
services:
nexus-repository:
image: sonatype/nexus3
ports:
- '8082:8081'
networks:
- mynet
volumes:
- '/nexus-data:/nexus-data'
To remove the containers I tried:
sudo docker-compose down => NOPE
ssudo docker network remove mynet => NOPE
sudo docker-compose rm -sfv nexus-repository => NOPE
Nothing worked until I completely removed all references to the exernal network.
Solution
services:
nexus-repository:
image: sonatype/nexus3
ports:
- '8082:8081'
volumes:
- '/nexus-data:/nexus-data'
No more:
Network 'mynet' is external, skipping
And no more containers !
In my case, I had started my containers using a docker-compose file indeed yet through VSCode's remote container extension. If that's your case, you can stop your containers using VSCode's Docker extension (right click on your container group -> Docker Compose Down)

How can I add hostnames to a container on the same docker network?

Suppose I have a docker compose file with two containers. Both reference each other in their /etc/hosts file. Container A has a reference for container B and vice versa. And all of this happens automatically. Now I want to add one or more hostnames to B in A's hosts file. How can I go about doing this? Is there a special way I can achieve this in Docker Compose?
Example:
172.0.10.166 service-b my-custom-hostname
Yes. In your compose file, you can specify network aliases.
services:
db:
networks:
default:
aliases:
- database
- postgres
In this example, the db service could be reached by other containers on the default network using db, database, or postgres.
You can also add aliases to running containers using the docker network connect command with the --alias= option.
Docker compose has an extra_hosts feature that allows additional entries to be added to the container's host file.
Example
docker-compose.yml
web1:
image: tomcat:8.0
ports:
- 8081:8080
extra_hosts:
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229"
web2:
image: tomcat:8.0
ports:
- 8082:8080
web3:
image: tomcat:8.0
ports:
- 8083:8080
Demonstrate host file entries
Run docker compose with the new docker 1.9 networking feature:
$ docker-compose --x-networking up -d
Starting tmp_web1_1
Starting tmp_web2_1
Starting tmp_web3_1
and look at the hosts file in the first container. Shows the other containers, plus the additional custom entries:
$ docker exec tmp_web1_1 cat /etc/hosts
..
172.18.0.4 web1
172.18.0.2 tmp_web2_1
172.18.0.3 tmp_web3_1
50.31.209.229 otherhost
162.242.195.82 somehost
If I understand your question correctly, you can pass a host name referenced in your host's /etc/hosts file via --add-host flag :
$ docker run ... --add-host="droid"
Your host's /etc/hosts would need the following entry:
xx.xx.xx.xx droid
Of course, xx.xx.xx.xx will need to be reachable from inside the container you just started using the 'docker run' command. You can have one or more --add-host="xyz".
More details about --add-host here:
http://docs.docker.com/v1.8/reference/commandline/run/

Resources