How to join the default bridge network with docker-compose v2? - docker

I tried to setup an nginx-proxy container to access my other containers via subdomains on port 80 instead of special ports. As you can guess, I could not get it to work.
I'm kind of new to docker itself and found that it's more comfortable for me to write docker-compose.yml files so I don't have to constantly write long docker run ... commands. I thought there's no difference in how you start the containers, either with docker or docker-compose. However, one difference I noticed is that starting the container with docker does not create any new networks, but with docker-compose there will be a xxx_default network afterwards.
I read that containers on different networks cannot access each other and maybe that might be the reason why the nginx-proxy is not forwarding the requests to the other containers. However, I was unable to find a way to configure my docker-compose.yml file to not create any new networks, but instead join the default bridge network like docker run does.
I tried the following, but it resulted in an error saying that I cannot join system networks like this:
networks:
default:
external:
name: bridge
I also tried network_mode: bridge, but that didn't seem to make any difference.
How do I have to write the docker-compose.yml file to not create a new network, or is that not possible at all?
Bonus question: Are there any other differences between docker and docker-compose that I should know of?

Adding network_mode: bridge to each service in your docker-compose.yml will stop compose from creating a network.
If any service is not configured with this bridge (or host), a network will be created.
Tested and confirmed with:
version: "2.1"
services:
app:
image: ubuntu:latest
network_mode: bridge

Related

docker compose communication with container

I am trying to create an example to create two WEB API 's and containerize them and to communicate between them.
I would like to see the side car design pattern, I have found an example in Github that I am trying to run.
https://github.com/cesaroll/dotnet-sidecar
In the above example, HelloAPI makes a call to HelloSideCar API which is a different project.
In the HelloAPI a call is made to another API in another project. I am trying to run in local using Docker Compose.
When I try to hit the API from HelloAPI(localhost:8080/FromSidecar) project to SideCarAPI, I see a 404 error, request is not going to another container
Below Is my Docker Compose
# docker-compose up -d
# docker-compose stop
# docker-compose rm -f
version: '3.8'
services:
hello-sidecar-api:
image: hello-sidecar-api:latest
container_name: hello-sidecar-api
ports:
- "8180:8080"
hello-api:
image: helloapi:latest
container_name: hello-api
environment:
- SIDERCAR_URL=http://localhost:8180/
depends_on:
- hello-sidecar-api
ports:
- "8080:8080"
You can either change SIDECAR_URL to http://hello-sidecar-api:8080/ or place both APIs in the same container. Note that I also changed the port from 8180 to 8080, because 8180 is a port mapped on the host, but inside your Docker network your API is accessible by other containers on 8080.
Your containers are separate network entities with their own IPs, so when you call http://localhost:8180 from the inside of a container, you're not calling the host, but the same container from which the request originates. (assuming you're not using host network driver).
What you are trying to do here resembles the behavior of pods in Kubernetes (where sidecar term is widely used). In Kubernetes you could put these two containers in one pod and then they could call each other on localhost

Create a NFS share between containers described in different docker-compose files and running in different docker-machines

I have the following setup in my computer:
One docker-machine set-up for the containers of my Project A. I have my docker-compose.yml file, describing which containers have to be build, the volumes to mount and so on, and the Dockerfile for each container.
Another docker-machineset-up for the containers of my Project B, with its docker-compose.yml and Dockerfiles.
I now want to do a NFS share between a container in my project A (let's call it container 1) and another container in my project B (container 2).
I was checking links like this, but, as far as I understand it, that's for containers in the same network. In this case, my container 1 and container 2 are not in the same network, and they are in different machines.
I haven't specified any networking option when running docker-machine or in my docker-compose.yml files (apart from exposing the ports that my apps use).
How can I do an NFS share between those 2 containers?
The 'docker-compose up' command creates a network by name [projectname]_default" and all the services specified in the docker-compose.yml file will be mapped to the network that got created.
For example, suppose your app is in a directory called myapp, and your docker-compose.yml looks like this:
version: "3"
services:
web:
build: .
ports:
- "8000:8000"
db:
image: postgres
ports:
- "8001:5432"
When you run docker-compose up, the following happens:
1) A network called myapp_default is created.
2) A container is created using web’s configuration. It joins the network myapp_default under the name web.
3) A container is created using db’s configuration. It joins the network myapp_default under the name db.
and If you want other service to make use of the existing docker network that is created then you need to define that using 'external' option
Use a pre-existing network
If you want your containers to join a pre-existing network, use the external option:
networks:
default:
external:
name: my-pre-existing-network
Instead of attempting to create a network called [projectname]_default, Compose looks for a network called my-pre-existing-network and connect your app’s containers to it.
source: https://docs.docker.com/compose/networking/#use-a-pre-existing-network

Docker Networking Stack

Currently I am trying to make my docker container's network stack be the same as my machine's in my docker-compose yml. I saw on the docker docs you can use "hostnet" to use your own network stack. I am using this but I keep getting an error saying...
services:
xxxxx:
xxxxx:
networks:
hostnet:{}
networks:
hostnet:
external: true
name: host
networks.hostnet value Additional properties are not allowed ('name' was unexpected)
What is wrong, and is there also a way to configure a docker compose file so that my container will have the same Network ID?
This can be achieved using:
network_mode: "host"
in the definition for your service. See Docker's compose file documenting for more details on this: https://docs.docker.com/compose/compose-file/#network_mode
Note that I personally consider this the option of last resort. If you can achieve your goals by publishing a single port instead of disabling the network namespacing features of docker, your solution will be more secure and portable.

How do I access Mopidy running in Docker container from another container

To start, I am more familiar running Docker through Portainer than I am with doing it through the console.
What I'm Doing:
Currently, I'm running Mopidy through a container, which is being accessed by other machines through the default Mopidy port. In another container, I am running a Slack bot using the Limbo repo as a base. Both of them are running on Alpine Linux.
What I Need:
What I want to do is for my Slack bot to be able to call MPC commands, such as muting the volume, etc. This is where I am stuck. What is the best way for this to work
What I've tried:
I could ssh into the other container to send a command, but it doesn't make sense to do this since they're both running on the same server machine.
The best way to connect a bunch of containers is to define a service stack using docker-compose.yml file and launch all of them using docker-compose up. This way all the containers will be connected via single user-defined bridge network which will make all their ports accessible to each other without you explicitly publishing them. It will also allow the containers to discover each other by the service name via DNS-resolution.
Example of docker-compose.yml:
version: "3"
services:
service1:
image: image1
ports:
# the following only necessary to access port from host machine
- "host_port:container_port"
service2:
image: image2
In the above example any application in the service2 container can reach some port on service1 just by using service2:port address.

can not use user-defined bridge in swarm compose yaml file

I learned from docker documentation that I can not use docker DNS to find containers using their hostnames without utilizing user-defined bridge network. I created one using the command:
docker network create --driver=overlay --subnet=172.22.0.0/16 --gateway=172.22.0.1 user_defined_overlay
and tried to deploy a container that uses it. compose file looks like:
version: "3.0"
services:
web1:
image: "test"
ports:
- "12023:22"
hostname: "mytest-web1"
networks:
- test
web2:
image: "test"
ports:
- "12024:22"
hostname: "mytest-web2"
networks:
- test
networks:
test:
external:
name: user_defined_overlay
my docker version is: Docker version 17.06.2-ce, build cec0b72
and I got the following error when I tried deploying the stack:
network "user_defined_bridge" is declared as external, but it is not in the right scope: "local" instead of "swarm"
I was able to create an overlay network and define it in compose file. that worked fine but it didn't for bridge.
result of docker network ls:
NETWORK ID NAME DRIVER SCOPE
cd6c1e05fca1 bridge bridge local
f0df22fb157a docker_gwbridge bridge local
786416ba8d7f host host local
cuhjxyi98x15 ingress overlay swarm
531b858419ba none null local
15f7e38081eb user_defined_overlay overlay swarm
UPDATE
I tried creating two containers running on two different swarm nodes(1st container runs on manager while second runs on worker node) and I specified the user-defined overlay network as shown in stack above. I tried pinging mytest-web2 container from within mytest-web1 container using hostname but I got unknown host mytest-web2
As of 17.06, you can create node local networks with a swarm scope. Do so with the --scope=swarm option, e.g.:
docker network create --scope=swarm --driver=bridge \
--subnet=172.22.0.0/16 --gateway=172.22.0.1 user_defined_bridge
Then you can use this network with services and stacks defined in swarm mode. For more details, you can see PR #32981.
Edit: you appear to have significantly overcomplicated your problem. As long as everything is being done in a single compose file, there's no need to define the network as external. There is a requirement to use an overlay network if you want to communicate container-to-container. DNS discovery is included on bridge and overlay networks with the exception of the default "bridge" network that docker creates. With a compose file, you would never use this network without explicitly configuring it as an external network with that name. So to get container to container networking to work, you can let docker-compose or docker stack deploy create the network for your project/stack automatically with:
version: "3.0"
services:
web1:
image: "test"
ports:
- "12023:22"
web2:
image: "test"
ports:
- "12024:22"
Note that I have also removed the "hostname" setting. It's not needed for DNS resolution. You can communicate directly with a service VIP with the name "web1" or "web2" from either of these containers.
With docker-compose it will create a default bridge network. Swarm mode will create an overlay network. These defaults are ideal to allow DNS discovery and container-to-container communication in each of the scenarios.
The overlay network is the network to be used in swarm. Swarm is meant to be used to manage containers on multiple hosts and overlay networks are docker's multi-host networks https://docs.docker.com/engine/userguide/networking/get-started-overlay/

Resources