User Tools

Site Tools


Setting NIC IP addresses as environment variables


For me, most any work day consists of Ubuntu Server, Docker, Ansible, Python, and Golang; but not all server instances have Static IP addresses, some only have an Ephemeral IP address. When I need to pass an interface's address to systemd, shell script, Docker, Kubernetes, etc. without having to perform edits on code or configuration, this can become problematic.

An easy way to do so is with setup-network-environment via system initialization and optionally, VPN connection parameters (e.g. OpenVPN's up and down options). Running this program will produce (and subsequently update) an environment file (by default, located at /etc/network-environment) that can be parsed by Bash, systemd, and others, in order to populate variables.

An example of the generated environment file:



In this article, I'll assume that these prerequisites haven't been fulfilled (Snappy, Git, and Go aren't part of the standard install for Ubuntu Server 16 LTS), and will cover those installation processes as well.


Update the package cache:

sudo apt update

Set ~/.bashrc to be loaded by ~/.bash_profile: 1)

echo 'source $HOME/.bashrc' >> $HOME/.bash_profile


Since Ubuntu 18.04 and later include Snappy, you can skip this step if this is what you're using.

Install Snappy:

sudo apt install --yes snapd


Install Git and build tools:

sudo apt install --yes \
    build-essential \
    git \


After you perform this step, please logout, and log back in. If you don't, Golang will not properly function for the next step.

Install the latest version of Golang:

snap install --classic go

The reason that I set $GOBIN to /usr/local/bin is because I want Go-based binaries to be accessible by the entire system. In a multi-user environment, your needs may differ, and plenty of people use $GOPATH/bin, and update $PATH, to reflect these utilities existing in their home directories.

That said, there's plenty of discussion on the Internet about what this should be set to 2) 3), so, YMMV.

Furthermore, the reason that I don't simply call source /etc/network-environment, is due to Bash not being able to parse variables with dashes in them (this seems to happen on particular Linux instances.)

Append environment variables to ~/.bashrc:

cat << 'EOF' | tee --append $HOME/.bashrc > /dev/null
# Golang
export GOPATH=$HOME/go
export GOBIN=/usr/local/bin

# setup-network-environment
if [ -f /etc/network-environment ]; then
    cp -a /etc/network-environment ${tnef}
    sed --in-place 's~[^0-9A-Za-z\=\.\_/]\+~_~g' ${tnef}
    source ${tnef}
    export $(cut -d= -f1 ${tnef})
    rm -rf ${tnef}

You remembered to logout and log back in, right? ;-)


Download, build, and install setup-network-environment:

go get



Important shortcuts:


  • Reload management parameters:
    systemctl daemon-reload

  • Enable specific service:
    systemctl enable NAME.service

  • Disable specific service:
    systemctl disable NAME.service


  • systemctl start NAME.service
  • systemctl restart NAME.service
  • systemctl stop NAME.service
  • Overview:
    systemctl status NAME.service

  • Log:
    journalctl --follow --unit=NAME.service


  • Start when system boots:
    systemctl list-unit-files --state=enabled

  • Currently Running:
    systemctl list-units --type=service --state=running

  • Active (running or exited):
    systemctl list-units --type=service --state=active

2018/01/28 19:25 · Louis T. Getterman IV


  1. Save:
    wget \
        --output-document=/etc/systemd/system/setup-network-environment.service \
  2. Set permissions: chmod -v 644 /etc/systemd/system/setup-network-environment.service
  3. Reload management parameters: systemctl daemon-reload
  4. Enable service: systemctl enable setup-network-environment.service
  5. Start service: systemctl start setup-network-environment.service
  6. Check status: systemctl status setup-network-environment.service
  7. View generated environment file: cat /etc/network-environment
Description=Setup Network Environment




This is an optional step, and to serve as an example for using systemd to assign Nginx to the host's default IPv4 address with environment variables.

  1. Save to:
    wget \
        --output-document=/etc/systemd/system/docker-nginx.service \
  2. Set permissions: chmod -v 644 /etc/systemd/system/docker-nginx.service
  3. Reload management parameters: systemctl daemon-reload
  4. Start service: systemctl start docker-nginx.service
  5. Check status: systemctl status docker-nginx.service
  6. View the default Nginx page: curl "http://${DEFAULT_IPV4}"
  7. Stop service: systemctl stop docker-nginx.service
  8. Remove test service: rm -rfv /etc/systemd/system/docker-nginx.service
  9. Reload management parameters: systemctl daemon-reload
Description=Docker Nginx example.
Requires=docker.service setup-network-environment.service
After=docker.service setup-network-environment.service

ExecStartPre=-/usr/bin/docker stop %n
ExecStartPre=-/usr/bin/docker rm %n
ExecStartPre=/usr/bin/docker pull nginx
ExecStart=/usr/bin/docker run \
    --rm \
    --name=%n \
    --publish ${DEFAULT_IPV4}:80:80 \


OpenVPN (optional)

In (each of) your OpenVPN configuration file(s) that are usually located in /etc/openvpn/, add 2 entries:

up /usr/local/bin/setup-network-environment
down /usr/local/bin/setup-network-environment


You are now able to use variables that represent the IP address of each of your system's NICs. As you see with the Dependencies example in this article, you can quickly bind a service to an interface's address, regardless of its IP address state as static or dynamic.

To expand upon real-world use cases of this example: when I want a containerized service to bind to VPN connections, I use ${TUN0_IPV4} in place of the ${DEFAULT_IPV4} parameter.

See also


External links

2018/01/20/nic-ip-as-environment-variables.txt · Last modified: 2018/12/28 15:38 by Louis T. Getterman IV