Riaan's SysAdmin Blog

My tips, howtos, gotchas, snippets and stuff. Use at your own risk!

Docker

Docker Test Environment Variable

I did a simple test of how to utilize environment variables in docker images and recored a few notes here.

 

Install Docker on a Ubuntu 16.04.1 Virtualbox guest for this test.
https://docs.docker.com/engine/installation/linux/ubuntulinux/

root@docker:~# apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D

root@docker:~# echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
deb https://apt.dockerproject.org/repo ubuntu-xenial main

root@docker:~# apt-get update
root@docker:~# apt-cache policy docker-engine

root@docker:~# apt-get install linux-image-extra-$(uname -r) linux-image-extra-virtual

Simple docker test.

root@docker:~#  docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
c04b14da8d14: Pull complete 
Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

Fix docker permissions so normal user can use.

 
root@docker:~# groupadd docker
groupadd: group 'docker' already exists
root@docker:~# usermod -aG docker rrosso

rrosso@docker:~$ docker run hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
 https://hub.docker.com

For more examples and ideas, visit:
 https://docs.docker.com/engine/userguide/

Make sure docker runs at OS boot time.

 
root@docker:~# systemctl enable docker
Synchronizing state of docker.service with SysV init with /lib/systemd/systemd-sysv-install...
Executing /lib/systemd/systemd-sysv-install enable docker

Test simple python web app.
https://docs.docker.com/engine/tutorials/usingdocker/

rrosso@docker:~$ docker run -d -P training/webapp python app.py
Unable to find image 'training/webapp:latest' locally
latest: Pulling from training/webapp
e190868d63f8: Pull complete 
909cd34c6fd7: Pull complete 
0b9bfabab7c1: Pull complete 
a3ed95caeb02: Pull complete 
10bbbc0fc0ff: Pull complete 
fca59b508e9f: Pull complete 
e7ae2541b15b: Pull complete 
9dd97ef58ce9: Pull complete 
a4c1b0cb7af7: Pull complete 
Digest: sha256:06e9c1983bd6d5db5fba376ccd63bfa529e8d02f23d5079b8f74a616308fb11d
Status: Downloaded newer image for training/webapp:latest
331df8667f005e40555944b7e61108525e843b6262275808f016695aacd7fc67

rrosso@docker:~$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
331df8667f00        training/webapp     "python app.py"     34 seconds ago      Up 33 seconds       0.0.0.0:32768->5000/tcp   focused_jang

rrosso@docker:~$ docker inspect focused_jang
[
    {
        "Id": "331df8667f005e40555944b7e61108525e843b6262275808f016695aacd7fc67",
        "Created": "2016-10-31T21:18:32.596139908Z",
        "Path": "python",
        "Args": [
            "app.py"
        ],
        "State": {
            "Status": "running",
[.. snip ..]
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02"
                }
            }
        }
    }
]

rrosso@docker:~$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' focused_jang
172.17.0.2

Try an environment variable.

 
rrosso@docker:~$ docker run -e "PROVIDER=app1" -d -P training/webapp python app.py
c300d87ef0a9ad3ca5f3c40fd5ae7d54f095ada52d1f092e991a2271652b573b
rrosso@docker:~$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
c300d87ef0a9        training/webapp     "python app.py"     11 seconds ago      Up 10 seconds       0.0.0.0:32770->5000/tcp   sleepy_varahamihira

Browser response: http://192.168.1.134:32770/
Hello app1!

Make a change to app.py. Play with restart/commit etc to understand volatile vs non-volatile changes.

 
rrosso@docker:~$ docker stop sleepy_varahamihira
sleepy_varahamihira
rrosso@docker:~$ docker run -t -i training/webapp /bin/bash
root@3c94c01cc795:/opt/webapp# vi app.py 
root@3c94c01cc795:/opt/webapp# cat app.py 
import os

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    provider = str(os.environ.get('PROVIDER', 'world'))
    return 'Riaan added '+provider+'!'

if __name__ == '__main__':
    # Bind to PORT if defined, otherwise default to 5000.
    port = int(os.environ.get('PORT', 5000))
    app.run(host='0.0.0.0', port=port)
root@3c94c01cc795:/opt/webapp# exit

rrosso@docker:~$ docker run -e "PROVIDER=app1" -d -P training/webapp python app.py
8116836ea65f7254e81671a58b68cf263b42427b066a1c3cfc971c70303b614d

rrosso@docker:~$ docker stop evil_colden
evil_colden

rrosso@docker:~$ docker run -e "PROVIDER=app1" -d -P training/webapp python app.py
190207e1eadad71205256a5127de982ad837dbad5a41896546ba480e2416ba20

rrosso@docker:~$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
190207e1eada        training/webapp     "python app.py"     8 seconds ago       Up 7 seconds        0.0.0.0:32772->5000/tcp   condescending_wilson

rrosso@docker:~$ docker stop condescending_wilson
condescending_wilson

rrosso@docker:~$ docker run -t -i training/webapp /bin/bash
root@f6dd40e4a838:/opt/webapp# vi app.py 
root@f6dd40e4a838:/opt/webapp# exit

rrosso@docker:~$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS                     PORTS               NAMES
f6dd40e4a838        training/webapp     "/bin/bash"         About a minute ago   Exited (0) 5 seconds ago                       determined_cray

rrosso@docker:~$ docker commit f6dd40e4a838 training/webapp
sha256:8392632ac934525ae846d6a2e0284a52de7cbfa1a682bf8a9804966c5c3e15c9

rrosso@docker:~$ docker run -e "PROVIDER=app1" -d -P training/webapp python app.py
594d6edb3ab7400ae3c38584c0d48276f24973a4328c3f60c1b1bc4cce16f17a

rrosso@docker:~$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
594d6edb3ab7        training/webapp     "python app.py"     5 seconds ago       Up 4 seconds        0.0.0.0:32773->5000/tcp   focused_hawking

Check changes in browser: http://192.168.1.134:32773/
Riaan added app1!

NOTES/IDEAS:

http://stackoverflow.com/questions/30494050/how-to-pass-environment-variables-to-docker-containers

Question:
# Dockerfile
ENV DATABASE_URL amazon:rds/connection?string

Answer:
You can pass environment variables to your containers with the -e flag.
example from a startup script

sudo docker run -d -t -i -e REDIS_NAMESPACE='staging' \ 
-e POSTGRES_ENV_POSTGRES_PASSWORD='foo' \
-e POSTGRES_ENV_POSTGRES_USER='bar' \
-e POSTGRES_ENV_DB_NAME='mysite_staging' \
-e POSTGRES_PORT_5432_TCP_ADDR='docker-db-1.hidden.us-east-1.rds.amazonaws.com' \
-e SITE_URL='staging.mysite.com' \
-p 80:80 \
--link redis:redis \  
--name container_name dockerhub_id/image_name

admin

Bio Info for Riaan