One can find “manuals” and “how to”s for this topic everywhere, but there is always something important missing and thus you'll have to do further search and puzzle everything together. I'm not saying that my manual here is ever complete, but at least from an administrators standpoint it hopefully covers more than the average docker page on the interwebs to prevent Docker from going haywire and pulling down your host. Since we dont want it to fill up our ROOT filesystem, right?
These are my goals for this manual:
Beside the Docker runtime itself im also going to install docker-compose , the manuals and additional “Dockerfile” syntax highlighting for vim.
aptitude install -y vim-syntax-docker aptitude remove -y docker.io docker.io-doc docker-compose # add Docker.com's GPG key to APT: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - # add Docker.com's APT repo to APT add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" # install docker-ce (community edition) apt-get update apt-get install \ docker-ce \ docker-ce-cli
systemctl status docker # prevent starting docker on boot systemctl disable docker # stop docker for now systemctl stop docker
# trash everyhing at former (default) docker location and within /etc/ rm -rv /var/lib/docker /etc/docker # prepare new destination dir/drive mkdir -vp /yourDataDrive/docker/ # create configuration file for Docker daemon: cat << 'EOF' > /etc/docker/daemon.json { "ip-forward": false, "ip-masq": false, "iptables": false, "data-root": "/yourDataDrive/docker/", "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } } EOF
systemctl start docker
systemctl status docker docker version # pull and run a temporarily # container from the default # docker registry on the # interwebs # docker run --rm hello-world # expect some hello world output # clean up the hello-world remains: # docker image rm hello-world
There are times and scenarios where you might run out of free ports or get port collisions between services running on your Docker host and your Docker containers. “Well… just remap your container ports to something free on your Docker host! Whats the problem?” you might say. The Problem lays with the kind of service you may want to run. There are services and apps who REQUIRE the use of specific ports and protocols and are unwilling or just troublesome to fiddle around with it.
In my case the DNS port 53 tcp+udp on my docker host was occupied by a productive DNS server. But i wanted to run “some 3rd party app” in a container which brings (and requires) its own DNS server on port 53. My goal was to run BOTH on the SAME HOST with the SAME PORT. So i simply needed another IP address i can bind the container to.
In these rare cases you might want to add more IP addresses to your Docker host, so you can separate things a bit better and bind container and services to “unused” IP addresses and ports.
This is how i did it…
cat << EOF > /etc/netplan/55-manual-net-config.yaml network: version: 2 ethernets: enp1s0: dhcp4: false dhcp6: false bridges: br0: addresses: - 192.168.0.1/24 - 192.168.0.2/24 - 192.168.0.3/24 - fd00:dead:beef:affe::1/64 - fd00:dead:beef:affe::2/64 - fd00:dead:beef:affe::3/64 dhcp4: false dhcp6: false interfaces: - enp1s0 nameservers: addresses: - 192.168.0.1 - ::1 search: - lan EOF
netplan apply
ip addr show
docker run -ti --name nameYourContainer -p 192.168.0.2:80:80 -p 192.168.0.2:443:443 yourImage:tag
Without any kind of host firewall or network firewall in place, Docker is by default allowed to access anything on your local network (and the internet) as well as services running within containers can be accessed from your local network. That might be ok for you.
However…
If you run your Docker daemon on a host with some sort of host firewall (iptables, firewalld or similar), multiple network interfaces, routing plus IP masquerading/NAT etc, Docker messes up your firewall rules and it gets complicated real quick and your Docker container might fail to access the internet or services within the container cannot be reached from your LAN. Now what ?
Well… since this highly depends on the type of firewall/script/scenario you have, my example may or may not work for you. It may be even dangerous to do it like this. But it seems to work so far for me in my experimental network environment and it did not blew up in my face just yet.
In my case my Docker host was denying, rejecting and reporting any traffic or connection attempts on any network interfaces that is unexpected. Therefore i had to allow incoming traffic on the docker0: virtual network interface (bridge), as well as allowing forwarding/routing of any traffic coming from that interface to everywhere else (local net and internet).
The iptables commands shown are just examples and are totally ripped out of context. Its just to demo the crucial part which made it fly again for me. Depending on your firewall script the possitions of the commands are crucial of course.
... iptables -I INPUT n -i docker0 -j ACCEPT -m comment --comment "ACCEPT anything on docker0" ... iptables -I FORWARD n -i docker0 -j ACCEPT -m comment --comment "FORWARD anything from docker0 to anywhere" ... iptables -I FORWARD n -i $INTERNET-IF -o docker0 -m state --state RELATED,ESTABLISHED -j ACCEPT -m comment --comment "enable incoming dynamic reverse nat for docker0 ...