Docker. How to run my container on a specific local ip - macos

I have such a simple docker-compose.yml file, that is serving some static files:
version: '3'
services:
nginx:
container_name: docs_nginx
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./:/var/www
- ./docker/vhost.conf:/etc/nginx/conf.d/default.conf
Now it can be accessed at
127.0.0.1
0.0.0.0
Is it possible somehow to tweak the docker-compose.yml to run my container at 127.127.127.127, for example?
As an answer I'll accept a working docker-compose.yml example, cause I've read a lot about networking in docs/blogs, but can't figure out what I am doing wrong.
Thanks!

You have to create a network along with the services you wish to run. Then you give a static ip address within the range of the base IP and CIDR mask. Since I don't know your network, you will need to match this closer to your network configuration so gateway can connect to the internet through the same gateway as your host machine. There should be away to set it up so the gateway will route through the host, but I don't remember off the top of my hand how to manage that. I'm sure there is a more specific how-to that will describe that process. I will look when I have a chance to find the answer, to that question.
version: '3'
services:
nginx:
container_name: docs_nginx
image: nginx:latest
ports:
- "80:80"
- "443:443"
networks:
vpcbr:
ipv4_address: 10.5.0.6
volumes:
- ./:/var/www
- ./docker/vhost.conf:/etc/nginx/conf.d/default.conf
networks:
vpcbr:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16
gateway: 10.5.0.1
https://docs.docker.com/engine/userguide/networking/#custom-network-plugins
this gives a pretty good idea of what's going on when creating a network for docker containers. When you call docker-compose it's translating the network key into network commands.
Note: I can not guarantee this will work since I don't know your setup. But this should get you in the ball park.
let me know if you have any questions.

You'll want to pick an IP address that your host can route to. If your host IP address is say 192.168.0.50 it could look something like this in the yml file:
version: "2"
services: host1:
networks:
mynet:
ipv4_address: 192.168.0.101 networks: mynet:
driver: bridge
ipam:
config:
- subnet: 192.168.0.0/24
You could also specify the IP address in a startup script using the manual steps listed at:
https://jpetazzo.github.io/2013/10/16/configure-docker-bridge-network/

Related

Hosts aren't accessible by name in docker compose on Windows

I have two, windows-based images that I'm using with docker compose.
The docker-compose.yaml:
services:
application:
image: myapp-win:latest
container_name: "my-app"
# for diagnosis
entrypoint: ["cmd"]
stdin_open: true
tty: true
# /diagnosis
env_file: .myapp/.env
environment:
- POSTGRES_URI=jdbc:postgresql://db0:5432/mydatabase
depends_on:
db0:
condition: service_healthy
db0:
image: stellirin/postgres-windows:10.10
container_name: "my-db"
ports:
- 10000:5432 # this doesn't seem to work in windows
env_file:
- .postgres/.env
volumes:
- .postgres\initdb\:c:\docker-entrypoint-initdb.d\
healthcheck:
test: [ "CMD", "pg_isready", "-q", "-d", "${POSTGRES_DATABASE}", "-U", "${POSTGRES_USER}" ]
timeout: 45s
interval: 10s
retries: 10
restart: unless-stopped
With the two containers started, I accessed the terminal for the my-db container and got its IP address.
Next, I accessed the terminal for the my-app container. I was able to ping the my-db container by its IP address. However, it did not respond by its hostname:
c:\app> ping db0
Ping request could not find host db0.
This is symptommatic why the application can't reach the database using the POSTGRES_URI variable.
Is there a different syntax for the hostname in a Windows container?
** edit **
I'm not able to ping outside the network, from either container:
c:\app> ping 8.8.8.8
Request timed out.
Not sure if this is relevant.
Regardless of container OS, to my knowledge, referring to the other name (db0) directly won't directly work inside the container, but is simply exposed to the other compose entries
Instead, set an env var dependent on the name and read it in the container
environment:
- "ADDRESS_DB=db0"
Then, if you want to be able to ping db0 or similar, have a script set the env var as an available host name on start
Alternatively, you may have success setting it the extra_hosts field, but I haven't tested this and you may need to give it a different name to prevent interpolation
extra_hosts:
- db_url:db0

Cannot make an HTTP request between two Laravel Docker containers

Let me start off by stating that I know this question has been asked on many forums. I have read them all.
I have two Docker containers that are built with docker-compose and contain a Laravel project each. They are both attached to a network and can ping one another successfully, however, when I make a request from Postman to the one backend that then makes a curl request to the other, I get the connection refused error shown below.
This is my docker-compose file for each project respectfully:
version: '3.8'
services:
bumblebee:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/app
networks:
- picknpack
ports:
- "8010:8000"
networks:
picknpack:
external: true
version: '3.8'
services:
optimus:
build:
context: .
dockerfile: Dockerfile
volumes:
- .:/app
ports:
- "8020:8000"
networks:
- picknpack
depends_on:
- optimus_db
optimus_db:
image: mysql:8.0.25
environment:
MYSQL_DATABASE: optimus
MYSQL_USER: test
MYSQL_PASSWORD: test1234
MYSQL_ROOT_PASSWORD: root
volumes:
- ./storage/dbdata:/var/lib/mysql
ports:
- "33020:3306"
networks:
picknpack:
external: true
Here you can see the successful ping:
I would love to keep messing with configuration files but I have a deadline to meet and nothing is working, any help would be appreciated.
EDIT
Please see inspection of network:
Within the docker network that I created, both containers are exposed on port 8000 as per their Dockerfiles. It was looking at me square in the face: 'Connection refused on port 80'. The HTTP client was using that as default rather than 8000. I updated the curl request to hit port 8000 and it works now. Thanks to #user3532758 for your help. Note that the containers are mapped to ports 8010 and 8020 in the external local network, not within the docker network. There they are both served on port 8000 with different IPs

traefik proxy for docker container running in host network

i am running traefik as a proxy in docker container
i am using DockerToolBox in windows 10
the traefik proxy was able to recognize the service app which is running in 127.0.0.1, but the service app is actually running in docker host = 192.168.99.x ip
version: '3'
services:
reverse_proxy:
image: traefik
command: --api --docker
ports:
- "81:80"
- "8081:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- backend
whoami:
image: containous/whoami
labels:
- "traefik.frontend.rule=Host:whoami.default"
- "traefik.enable=true"
- "traefik.port=80"
network_mode: host
networks:
backend:
driver: bridge
in the Traefik dashboard http://192.168.99.100:8081
it shows http://127.0.0.1:80 for whoami service
instead of http://192.168.99.100:80
any help would be appreciated.
i want network_mode: host to pick 192.168.99.100 instead of 127.0.0.1
As traefik official documentation says, when resolving service IP, first it
try a lookup of host.docker.internal
and second
if the lookup was unsuccessful, fall back to 127.0.0.1
This means we can just add a host in the traefik container, using --add-host {docker0_IP}(it's the bridge's IP, you can easily use docker inspect {NAME_OF_TRAEFIK} and find the IP of Gateway(for me, it's 172.18.0.1). If you use docker-compose, you can use add following lines to your definition of traefik:
extra_hosts:
- host.docker.internal:{docker0_IP}
Also, I find that it's ok to use the IP my eth0 IP, which means the IP of your LAN(for me, it's 192.168.0.20).
Then, recreate traefik and everything works like a daisy.

Docker Container Connection Refused MacOS

I have this docker-compose file:
networks:
default:
ipam:
config:
- subnet: 10.48.0.0/16
gateway: 10.48.0.1
services:
haproxy:
build: haproxy
container_name: haproxy
volumes:
- ./haproxy/conf/:/usr/local/etc/haproxy/
- ./haproxy/ssl/:/etc/ssl/xip.io/
ports:
- "80:80"
- "443:443"
networks:
default:
ipv4_address: 10.48.0.2
server:
build: server
container_name: server
restart: always
environment:
- ENV=env=production db=true
ports:
- "8081:8081"
volumes:
- ./server/config:/usr/src/app/config
depends_on:
- haproxy
networks:
default:
ipv4_address: 10.48.0.4
frontend:
build: frontend
container_name: frontend
restart: always
ports:
- "8080:8080"
volumes:
- ./frontend/config:/usr/src/app/config
depends_on:
- server
networks:
default:
ipv4_address: 10.48.0.5
version: '2'
In order to deploy a backend server and a frontend interface inside a subnet defined in the range 10.48.0.0/16.
So I tried to assign fixed ip to each container. On Linux everything is ok, so I can reach 10.48.0.4_8081/api, but on MacOS when I try to do the same thing, I have ERR_CONNECTION_REFUSED.
If I try to connect without using IP, but with localhost:8081/api, this is ok. But with multiple containers, I have to access directly with the IP.
Inside each container, if I try to ping the other ip address (example from container frontend with IP 10.48.0.5 I try to ping 10.48.0.4) everything is OK.
So my question is, How can I do in order make an http call to an api that is on another service? thanks for your help.
I've read everywhere that is a well know situation under windows and mac, but not on linux, where is possible from the client side making request directly on the ip address of the container. This is not possible on mac and is still open an issue on github.
In this case, I've used haproxy in order to proxy requests to each container.

Using a shared MySQL container

Tl;Dr; Trying to get WordPress docker-compose container to talk to another docker-compose container.
On my Mac I have a WordPress & MySQL container which I have built and configured with a linked MySQL server. In production I plan to use a Google Cloud MySQL storage instance, so plan on removing the MySQL container from the docker-compose file (unlinking it) and then separate shared container I can use from multiple docker containers.
The issue I'm having is that I cant connect the WordPress container to the separate MySQL container. Would anyone be able to shed any light on how I might go about this?
I have tried unsuccessfully to create a network as well as tried creating a fixed IP that the local box has reference to via the /etc/hosts file (my preferred configuration as I can update the file according to ENV)
WP:
version: '2'
services:
wordpress:
container_name: spmfrontend
hostname: spmfrontend
domainname: spmfrontend.local
image: wordpress:latest
restart: always
ports:
- 8080:80
# creates an entry in /etc/hosts
extra_hosts:
- "ic-mysql.local:172.20.0.1"
# Sets up the env, passwords etc
environment:
WORDPRESS_DB_HOST: ic-mysql.local:9306
WORDPRESS_DB_USER: root
WORDPRESS_DB_PASSWORD: root
WORDPRESS_DB_NAME: wordpress
WORDPRESS_TABLE_PREFIX: spm
# sets the working directory
working_dir: /var/www/html
# creates a link to the volume local to the file
volumes:
- ./wp-content:/var/www/html/wp-content
# Any networks the container should be associated with
networks:
default:
external:
name: ic-network
MySQL:
version: '2'
services:
mysql:
container_name: ic-mysql
hostname: ic-mysql
domainname: ic-mysql.local
restart: always
image: mysql:5.7
ports:
- 9306:3306
# Create a static IP for the container
networks:
ipv4_address: 172.20.0.1
# Sets up the env, passwords etc
environment:
MYSQL_ROOT_PASSWORD: root # TODO: Change this
MYSQL_USER: root
MYSQL_PASS: root
MYSQL_DATABASE: wordpress
# saves /var/lib/mysql to persistant volume
volumes:
- perstvol:/var/lib/mysql
- backups:/backups
# creates a volume to persist data
volumes:
perstvol:
backups:
# Any networks the container should be associated with
networks:
default:
external:
name: ic-network
What you probably want to do is create a shared Docker network for the two containers to use, and point them both to it. You can create a network using docker network create <name>. I will use sharednet as an example below, but you can use any name you like.
Once the network is there, you can point both containers to it. When you're using docker-compose, you would do this at the bottom of your YAML file. This would go at the top level of the file, i.e. all the way to the left, like volumes:.
networks:
default:
external:
name: sharednet
To do the same thing on a normal container (outside compose), you can pass the --network argument.
docker run --network sharednet [ ... ]

Resources