Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Change the IP subnet of Docker's docker0 interface
#!/bin/sh -e
#
# NOTE: Since Docker 1.10 (February 4, 2016), it has been possible to configure the
# Docker daemon using a JSON config file. On Linux, this file is normally located at
# /etc/docker/daemon.json. You should use this JSON config method if you are running
# a version of Docker that is at least 1.10!
# Here is an example configuration that sets the docker0 bridge IP to 192.168.254.1/24:
# {
# "bip": "192.168.254.1/24"
# }
#
# You can run this script directly from github as root like this:
# curl -sS https://gist.githubusercontent.com/kamermans/94b1c41086de0204750b/raw/configure_docker0.sh | sudo bash -s - 192.168.254.1/24
#
# * Make sure you replace "192.168.254.1/24" with the network that you want to use
#
# NOTE: This script is intended for Debian / Ubuntu only!
if [ $# -lt 1 ]; then
echo "Usage: sudo ./configure_docker0.sh <ip/CIDR>"
echo " examples: "
echo " ./configure_docker0.sh 10.200.0.57/16"
echo " ./configure_docker0.sh 172.31.0.21/16"
echo " ./configure_docker0.sh 192.168.254.1/24"
echo " "
echo " NOTE: You should stop Docker before running this script."
echo " When you restart it, Docker will use the new IP."
exit 2
fi
INIT_SYSTEM="sysv"
if ps -o comm -1 | grep -q systemd; then
INIT_SYSTEM="systemd"
fi
NEW_IP="$1"
DOCKER_INIT="/etc/default/docker"
if [ ! -f "$DOCKER_INIT" ]; then
cat << EOF > $DOCKER_INIT
# Docker Upstart and SysVinit configuration file
# Customize location of Docker binary (especially for development testing).
#DOCKER="/usr/local/bin/docker"
# Use DOCKER_OPTS to modify the daemon startup options.
#DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4"
DOCKER_OPTS="--bip=$NEW_IP"
# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy="http://127.0.0.1:3128/"
# This is also a handy place to tweak where Docker's temporary files go.
#export TMPDIR="/mnt/bigdrive/docker-tmp"
EOF
echo "Created a new Docker default file at $DOCKER_INIT"
exit 0;
fi
echo "Removing old docker0 network(s)"
NETWORKS=$(ip addr list docker0 | grep "inet " | cut -d" " -f6)
for NET in $NETWORKS; do
echo " $NET"
ip addr del $NET dev docker0
done
echo "Adding new docker0 network"
ip addr add $NEW_IP dev docker0
echo "Removing old iptables rules"
iptables -t nat -F POSTROUTING
iptables -F DOCKER
CURRENT_OPTS=$(cat $DOCKER_INIT | grep "^ *DOCKER_OPTS" | sed 's/^/ /g')
NEW_OPTS=DOCKER_OPTS=\"--bip=$NEW_IP\"
echo " "
if [ "$CURRENT_OPTS" != "" ]; then
TEMP_FILE="/tmp/docker_config.tmp"
grep -v "^ *DOCKER_OPTS" $DOCKER_INIT > $TEMP_FILE
echo " " >> $TEMP_FILE
echo DOCKER_OPTS=\"--bip=$NEW_IP\" >> $TEMP_FILE
cat $TEMP_FILE > $DOCKER_INIT
rm -f $TEMP_FILE
echo "WARNING: The existing DOCKER_OPTS were overwritten in $DOCKER_INIT:"
echo "Old:"
echo "$CURRENT_OPTS"
echo "New:"
echo " $NEW_OPTS"
else
echo " " >> $DOCKER_INIT
echo DOCKER_OPTS=\"--bip=$NEW_IP\" >> $DOCKER_INIT
echo "Success: $DOCKER_INIT has been modified."
fi
SYSTEMD_DOCKER_DIR="/etc/systemd/system/docker.service.d"
if [ "$INIT_SYSTEM" = "systemd" ]; then
echo "Configuring systemd to use /etc/default/docker"
if [ ! -d $SYSTEMD_DOCKER_DIR ]; then
mkdir -p $SYSTEMD_DOCKER_DIR
fi
OPTS='$DOCKER_OPTS'
cat << EOF > $SYSTEMD_DOCKER_DIR/debian-style-config.conf
# Enable /etc/default/docker configuration files with Systemd
[Service]
EnvironmentFile=-/etc/default/docker
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// $OPTS
EOF
fi
echo ""
echo "Restarting Docker"
case $INIT_SYSTEM in
sysv)
service docker restart
;;
systemd)
systemctl daemon-reload
systemctl restart docker.service
sleep 1
systemctl status --lines=0 docker.service
;;
esac
echo "done."
@muyen

This comment has been minimized.

Copy link

muyen commented Feb 19, 2016

It works great. Thanks.

@kamermans

This comment has been minimized.

Copy link
Owner Author

kamermans commented Apr 22, 2016

This now supports Ubuntu running sysv, upstart and systemd, so it should work for every Ubuntu version, including 16.04 LTS. Please note that if you are running Ubuntu 15.04 or higher, this script will add a "systemd drop-in" which adds support for the /etc/default/docker file to systemd. This is required so that Docker will continue using your settings after a reboot.

@nikhilweee

This comment has been minimized.

Copy link

nikhilweee commented Aug 22, 2016

You made my day!

@rickynguyen4590

This comment has been minimized.

Copy link

rickynguyen4590 commented Sep 12, 2016

Your 're my hero

@meucaa

This comment has been minimized.

Copy link

meucaa commented Dec 14, 2016

It works great, thank you !

@kevthanewversi

This comment has been minimized.

Copy link

kevthanewversi commented Dec 21, 2016

You're the best man! Keep up the good work!

@mgcrea

This comment has been minimized.

Copy link

mgcrea commented Jan 2, 2017

Shouldn't line 103 be ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS instead of ExecStart=/usr/bin/docker daemon -H fd:// $OPTS ?

@kamermans

This comment has been minimized.

Copy link
Owner Author

kamermans commented Jan 18, 2017

Thanks all!

@mgcrea: actually no, it's sort of a hack to get around string interpolation so that the output line looks like this:

ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS

I set $OPTS='$DOCKER_OTPS' earlier. I could probably figure out how to escape the $ in the heredoc, but I guess I settled on this method instead.

@criloz

This comment has been minimized.

Copy link

criloz commented Jan 19, 2017

thanks, I am taking this script for this project

https://github.com/NebTex/tzk

it create and manage, a tinc vpn, each host is assigned an unique ip, and a unique docker subnet automatically using a kv backend (consul), the docker container are routable in this environment from any host and any other container in the vpn that use the docker0 interface.

initially, it uses tinc for the vpn, but there is a plan to support more like wireguard, and other similar software.

thanks!!!!

@scythargon

This comment has been minimized.

Copy link

scythargon commented Feb 3, 2017

thanks!

@dualvtable

This comment has been minimized.

Copy link

dualvtable commented Feb 6, 2017

Thanks for the script!

@andersonVSA

This comment has been minimized.

Copy link

andersonVSA commented Feb 27, 2017

Thanks!!!

@umarmurtaza

This comment has been minimized.

Copy link

umarmurtaza commented Mar 31, 2017

Thanks a lot !!!
Was badly in need of a solution to this problem, it works great on my Ubuntu 16.04 and there docker versions were:
$ docker --version
Docker version 17.03.1-ce, build c6d412e

$ docker-compose --version
docker-compose version 1.11.2, build dfed245

thanks again.

@ofdata

This comment has been minimized.

Copy link

ofdata commented May 27, 2017

Thanks a loooooooooot!!

$ docker --version
Docker version 17.03.1-ce, build c6d412e

$ docker-compose --version
docker-compose version 1.8.0, build unknown

@airani

This comment has been minimized.

Copy link

airani commented Jun 4, 2017

I have problem in ubuntu 14.04 with docker-compose
When i'm using docker-compose its create new default driver with 172.17.0.1 subnet

@Dropa

This comment has been minimized.

Copy link

Dropa commented Jul 4, 2017

In case someone ends up here because they fail to update docker-ce with errors like

Setting up docker-ce (17.06.0~ce-0~ubuntu) ...
Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.
invoke-rc.d: initscript docker, action "start" failed.
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
  Drop-In: /etc/systemd/system/docker.service.d
           └─debian-style-config.conf
   Active: activating (auto-restart) (Result: exit-code) since ti 2017-07-04 10:07:52 EEST; 3ms ago
     Docs: https://docs.docker.com
  Process: 9065 ExecStart=/usr/bin/docker daemon -H fd:// $DOCKER_OPTS (code=exited, status=1/FAILURE)
 Main PID: 9065 (code=exited, status=1/FAILURE)

heinä 04 10:07:52 mmsami systemd[1]: Failed to start Docker Application Container Engine.
heinä 04 10:07:52 mmsami systemd[1]: docker.service: Unit entered failed state.
heinä 04 10:07:52 mmsami systemd[1]: docker.service: Failed with result 'exit-code'.
dpkg: error processing package docker-ce (--configure):
 subprocess installed post-installation script returned error exit status 1
Errors were encountered while processing:
 docker-ce

Run sudo rm -rf /etc/systemd/system/docker.service.d/debian-style-config.conf to fix that.

Seems that this script isn't compatible with newest docker-ce

$ docker -v; docker-compose -v
Docker version 17.06.0-ce, build 02c1d87
docker-compose version 1.8.0, build unknown
@C-Duv

This comment has been minimized.

Copy link

C-Duv commented Jul 7, 2017

@Dropa Won't removing /etc/systemd/system/docker.service.d/debian-style-config.conf make the daemon not use $DOCKER_OPTS (which contains the --bip) anymore thus causing the daemon not to use desired IP subnet?
Of course it will continue to work as long as the docker0 is not deleted, but the moment that interface disappear, Docker will recreate it using it's default IP subnet.

Instead of removing the file, I suggest changing the ExecStart= line as follow:

ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS

Which can be done with:

sed -i \
    's,^ExecStart=/usr/bin/docker daemon ,ExecStart=/usr/bin/dockerd ,' \
    /etc/systemd/system/docker.service.d/debian-style-config.conf

(Anyways, thanks for the message, I was running into the exact same issue since they changed docker daemon into dockerd)

@kamermans

This comment has been minimized.

Copy link
Owner Author

kamermans commented Oct 4, 2017

Thanks @C-Duv and sorry I missed your comment (and the original report from @Dropa) - this seems to have broken in the official Docker repos in version 17.06 (docker/for-linux#11), and will probably start breaking in the distro-specific repos soon. I've updated the Gist to use dockerd instead of docker daemon and tested it successfully back to Docker version 1.12.5.

@cristiandley

This comment has been minimized.

Copy link

cristiandley commented Oct 23, 2017

Im having same issue than @Dropa and applied @C-Duv but no luck

# docker ps -a
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
# systemctl status docker.service
● docker.service - Docker Application Container Engine
   Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/docker.service.d
           └─debian-style-config.conf
   Active: failed (Result: exit-code) since lun 2017-10-23 10:34:43 ART; 41min ago
     Docs: https://docs.docker.com
 Main PID: 6360 (code=exited, status=1/FAILURE)

oct 23 10:34:43 localhost.localdomain systemd[1]: Starting Docker Application Container Engine...
oct 23 10:34:43 localhost.localdomain dockerd[6360]: no sockets found via socket activation: make sure the service was...stemd
oct 23 10:34:43 localhost.localdomain systemd[1]: docker.service: main process exited, code=exited, status=1/FAILURE
oct 23 10:34:43 localhost.localdomain systemd[1]: Failed to start Docker Application Container Engine.
oct 23 10:34:43 localhost.localdomain systemd[1]: Unit docker.service entered failed state.
oct 23 10:34:43 localhost.localdomain systemd[1]: docker.service failed.
Warning: docker.service changed on disk. Run 'systemctl daemon-reload' to reload units.
Hint: Some lines were ellipsized, use -l to show in full.

debian-style-config.conf file is empty...

anyone having an issue like this ? or a clue ?

Thanks

@kamermans

This comment has been minimized.

Copy link
Owner Author

kamermans commented May 24, 2018

Thanks @evan-wu, that is indeed the correct way to configure it in newer versions of Docker - I'm going to add a warning for people still using this script to use the new method:
Create / edit /etc/docker/daemon.json and set bip:

{
  "bip": "172.26.0.1/16"
}
@keyax

This comment has been minimized.

Copy link

keyax commented May 30, 2018

The new method with daemon.json dont reset the ip addr list, when restarting systemctl networking. I also tried robooting the system, no chance. With the script ifconfig and ip addr list changed to new ip. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.