docker img creation and run

#Firslty create a local directory, e.g. /home/flasktest

sudo mkdir /home/flasktest

#Go to the created directory, create a Dockerfile

sudo vi Dockerfile

#And type in the following codes:

# Dockerfile

# Use a slim version of python 2.7 as the parent image, you may create you own image from scratch too.

FROM python:2.7-slim

# Set the working directory to /app

WORKDIR /app

# Copy everything in the current directory contents into the container at /app

COPY . /app

# Install any needed packages for the docker instance specified in requirements.txt, so it will install the packages on top of python slim. 

# Note this is within the docker image, not your hosts python environment. Comment out the proxy if not needed.

RUN pip install --trusted-host pypi.python.org -r requirements.txt  --proxy http://xxx.xxx.xx.x:8080

# Make port 80 available to the world outside this container

EXPOSE 80

# Run app.py when the container launches

CMD ["python", "app.py"]

#######################################################

#Obviously the Dockerfile refers to (1) the python packages requirements.txt. For now we only need one line: Flask, but you may add other packages for a more complex image

#requirements.txt

Flask

#######################################################

#The app.py simply returns the host name:

from flask import Flask

import os

import socket

app = Flask(__name__)

@app.route("/")

def test():

    html = "<b>hello your hostname is {hostname}<b><br/>"

    return html.format(hostname=socket.gethostname())

if __name__ == "__main__":

    app.run(host='0.0.0.0', port=80)


#######################################################

#Now its ready to build the docker image. Note there is a "." at the end which means copying everything from the local directory into the image.

#the tag here is the name of the image, the version (tag) is default to latest. to set a version, use sudo docker build --tag=flasktest:v0.1 .

sudo docker build --tag=flasktest .

#now check if the images is available

sudo docker image ls

#if something wrong, remove the image

sudo docker image rm imageid

#run the image as a container instance. The container listens at port 80 which is unknown to the local host, and it needs to map the container's port to a local hosts port, 8080 in this case.

sudo docker run -p 8080:80 flasktest

#if everything is ok, go to http://localhost:8080

#######################################################

#once running an image, a container is created. 

sudo docker ps -a  #list all containers

sudo docker stop containerid  #stop by container id

#you may stop the container, but it wont delete the container, you can always start the container again by container id

sudo docker start containerid  #start by container id

sudo docker start -a -i ab2ed27d4fef  #

#to remove a container

sudo docker rm containerid

#to save a docker image to a file

sudo docker save flasktest > /home/flasktest.tar

#to load an image file

sudo docker load --input /home/flasktest.tar

############################### if docker hub is behind a proxy and docker pull doesnt work #######################################

In the case when it can not pull image from Docker hub, you may build a docker image from file.

For example, download centos-7-docker.tar.xz  file from https://github.com/luxknight007/centos7.

It seems to be a zip folder of all the necessary centos system files.

There is also a Dockerfile

FROM scratch

ADD centos-7-docker.tar.xz /

LABEL name="CentOS Base Image" 

CMD ["/bin/bash"]

Then simply run:

  docker build --tag=centos7 .

It creates a base image for centos7. The ADD command seems to extract the centos7's system files to the root path /.

To start from the image:

  docker run -it centos7

To restart from an exited container. -a for attaching the image, -i for the terminal, followed by container id

  docker start -a -i ab2ed27d4fef

Then add whatever changes you need to the base image if needed. E.g. update python.

If the changes are commonly needed for building other images, then commit the changes to another base image v2.

  docker commit [the container id] [new image name]

Finally save the base image v2 for future use.

  docker save [new image name] > /home/[new image name]

Run docker image automatically.

  docker run -p host_port: image_port --restart always image_name:version

  The --restart always parameters means: Always restart the container if it stops. If it is manually stopped, it is restarted only when Docker daemon restarts or the container itself is manually restarted.

  The docker itself is already is systemd service so docker automatically starts on server restart, which will automatically restart the container.

Environment variables

Try not to save connection string / username password within the docker image. Instead pass in those information as environment variables when kicking off a docker run. example:

===========Dockerfile===========

FROM python:2.7-slim

WORKDIR /app

COPY . /app

CMD python app.py $env_var

===========app.py===========

import sys

print('the parameters are : {0}'.format(sys.argv))

Pass in the value for env_var when kick off a docker run. In this way the secret variables can be managed outside of the docker image.

$docker build --tag=testenv:v1 .

$docker run -e env_var=123 testenv:v1

the output is:

  the parameters are : ['app.py', '123']

Another way to put in a list of environment variables is using --env-file

$docker run --env-file=FILE .....