This is my first time to write a post for docker, and I hope it wouldn’t be the last. The reason why I write this docker tutorial is because of a small project. Yes, a small project which need to be deployed by docker. It takes me 6 hours to learn docker and use it to deploy Python project and Java project. Besides that, the project need to read a configuration file from a fixed location in the file system (inside Docker envoriment). Basing on the deploy envorinment, the configuration file is different. For example, configuration file for development and production is totally different. For security reason and easy management, all configuration files are hosted on a remote server. So when running the docker, we shall download the corresponding configuration file from the remote server by passing the arguments in the docker command line. Here I will not repeat what’s the Docker and what benefits we can get from Docker, as you can get all the information from Docker homepage. In this post, I will describe how to make a docker image which can expect outside arguments. And this time, I will host all the source code on my public git. Hope it will help you to solve your problem within 6 minutes.
Make a Docker Image with Python Project
To make the project simple, the docker image only includes 3 files. Let’s discuss these 3 files first.
- Dockerfile, the text document contains all the commands a user could call on the command line to assemble the docker image.
- main.py, the real Python project file will read the configuration file “host.json” in the same folder.
- start.sh, the bash script will be run when a container is started from the docker image. It will download the configuration file from remote server by given argument and save it as “host.json” in the current folder. Then, it will invoke the Python project.
In the docker image configuration file Dockerfile, it specifies the container running environment. Then, it sets the working directory and copy the current directory contents into the container at working directory. The last statement specifies the command to run when the container is ready. Now let’s see the example source code.
# Use an official Python runtime as a parent image FROM python:3.6-jessie # Set the working directory to /app WORKDIR /app # Copy the current directory contents into the container at /app ADD . /app # Run start.sh when the container launches CMD ["/bin/bash", "start.sh"]
Python Project File
The Python project is the final app we want to run in the container. To make the example simple, this project only reads the configuration file “host.json” and print out the content. Here is the example source code.
# coding=utf-8 import os import re import time import urllib.request import urllib.parse import urllib.error filename = "host.json" if not os.path.exists(filename): print("config file does not exist!!!") else: fileObj = open(filename, 'r') data = fileObj.read() fileObj.close() print(data)
Docker Entry Point Command
Here I assign the docker entry point to run a bash script. The script is doing 2 jobs, downloading the configuration file from remote hosting and run the python file. The bash script will read the parameter from docker running command line. Basing on the parameter passing through the docker command, it will download the corresponding hosting configuration json file. To download a file from remote server, there are several approaches. I choose the simplest way to download the files by wget widget. You can also download the file inside Python project if you want. Here I will not cover this topic. This is the source code of my bash script:
#!/bin/bash #HOST: stage, production, dev #docker build -t hello . #docker run -e HOST="stage" hello echo start to download config file: $HOST.json wget -O host.json http://jmsliu.cn/wechat/$HOST.json python main.py
Build Docker Image
When I get all files ready, I am running the following command to build the docker image in the current folder.
docker build -t demo .
Run Docker Image by Passing Argument Into Docker Container
To be honest, there are several ways to pass arguments into docker container. I search on Google and find three ways. One is passing the parameter as environment variables through the docker run command. In my example, I am using this approach. Another way is passing the arguments with the -e switch. In this way, the Dockerfile need to declare the environment variable with a default value and it will be able to access this variable in CMD entrypoint. The third way is passing the arguments directly in the docker run command. Then we can access it directly in bash script. Here I attach the original place where I find these ways.
For 1st and 3rd way, you can find here.
For 2st and 3rd way, you can find here.
Here, I will run the following command (1st way mentioned above) to pass the argument to my bash script in docker image.
docker run -e HOST=”stage” demo
For the project, you can check this repository.