i am not experienced working with docker and docker-compose, but atleast i know how to get a container running, below is my compose file of a simple react app boiler plate. my intention was to assign an IP to it so that i can ping it from the external network, and also to access it without any port mapping to the host
version: "3.9"
services:
front-web:
build:
context: .
dockerfile: Dockerfile
args:
buildno: 1.0.0
container_name: web-front
domainname: fontend
dns: 8.8.8.8
network_mode: "host"
hostname: alpha
restart: unless-stopped
stop_grace_period: 1m
expose:
- 4000
tty: true
pid: host
stdin_open: true
ports:
- target: 4000
published: 4000
protocol: tcp
mode: host
networks:
web-net:
ipv4_address: 192.168.1.195
volumes:
- web-front:/app/data
networks:
web-net:
name: web-net
driver: bridge
driver_opts:
enable_ipv4: 1
enable_ipv6: 1
ipam:
driver: default
config:
- subnet: 192.168.1.1/24
ip_range: 192.168.1.195/24
gateway: 192.168.1.195/24
volumes:
web-front:
the docker file of the app is below
FROM node:alpine3.16
# RUN addgroup app && adduser -SG app app
# USER app
WORKDIR /app
RUN mkdir data
EXPOSE 4000
COPY package* .
RUN npm install
COPY . .
CMD [ "npm", "start" ]
ignore the "adduser" although it also failed to workout. whenever i run docker-compose up, i get an error saying:
Attaching to web-front
Error response from daemon: failed to add interface vethcf21a7d to sandbox: error setting interface "vethcf21a7d" IP to 192.168.1.195/24: cannot program address 192.168.1.195/24 in sandbox interface because it conflicts with existing route {Ifindex: 31 Dst: 192.168.1.0/24 Src: 192.168.1.1 Gw: <nil> Flags: [] Table: 254}
i am not sure how to go about this, kindly assist
I tried changing the driver part in the Networks section from brigde to macvlan, the build would pass but again i could not ping the the container with its ip. adding external:true, makes the whole thing fail
CodePudding user response:
Docker containers running in their own network. If you want to talk them, then you have to setup a lot of things.
- An IP-address of your container
- A route from your host-machine (
iptables
is your friend) - Maybe a special route for all your clients (because you have to use private ip-addresses which may conflict with other networks)
At the end ... it is pretty hardcore to set this up. If you still want it, then you should ask this on https://serverfault.com/.
It would be much easier, when you the expose port feature from docker.
When this is not possible for you, then the network: host
may help you.
CodePudding user response:
The normal way to set up external access to a container is using the Compose ports:
directive. In most cases that's the only network-related configuration you need at all; setups that try to avoid ports:
are almost always more complicated.
The Dockerfile you show is a pretty typical Node application. You can omit almost all of the Compose options. I'd probably reduce this to no more than:
version: "3.8" # newest supported by all current common Compose implementations
services:
front-web:
build: . # default Dockerfile name, no args
restart: unless-stopped
ports:
- "4000:4000"
volumes: # only because you store data in the container
- web-front:/app/data
volumes:
web-front:
Notice in particular that I do have a ports:
line, but I've removed all of the other network-related settings, including the IP address assignment, DNS configuration, and naming overrides.
This should achieve the stated goal of making the container accessible from other hosts, and it is the standard Docker setup. In principle it's possible to assign another IP address to your host and map the container to only that address, or use more exotic setups like a Docker macvlan network, but these are unusual setups and much more complex.