介绍
使用docker 方式build应用分为这样几个层次,从上到下依次是:
- Stack
- Services
- Container(you are here )
新的开发环境
过去运行python应用,需要安装python环境。现在使用docker,可以将可移植的Python运行时作为image,无需安装。你的构建可以包含基本Python image,确保您的应用程序,其依赖项和运行时都一起运行。
这个可移植的image 通过Dockerfile来定义
用 Dockerfile 定义一个容器
- 创建一个空目录,切换到该目录
- 创建一个叫做 Dockerfile的文件,将以下内容拷贝到文件中保存。
# Use an official Python runtime as a parent image
FROM python:2.7-slim
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
ADD . /app
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt
# Make port 80 available to the world outside this container
EXPOSE 80
# Define environment variable
ENV NAME World
# Run app.py when the container launches
CMD ["python", "app.py"]
The app itself
创建两个文件 requirements.txt 和 app.py,放到和 Dockerfile 相同的目录.
requirements.txt
Flask
Redis
from flask import Flask
from redis import Redis, RedisError
import os
import socket
# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)
app = Flask(__name__)
@app.route("/")
def hello():
try:
visits = redis.incr("counter")
except RedisError:
visits = "<i>cannot connect to Redis, counter disabled</i>"
html = "<h3>Hello {name}!</h3>" \
"<b>Hostname:</b> {hostname}<br/>" \
"<b>Visits:</b> {visits}"
return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80)
build the app
运行build命令,会创建一个Docker iamge. 使用tag参数可以设置一个更友好的名字。
docker build -t friendlyhello .
Where is your built image? It’s in your machine’s local Docker image registry:
$ docker image ls
REPOSITORY TAG IMAGE ID
friendlyhello latest 326387cea398
Run the app
- Run the app, mapping your machine’s port 4000 to the container’s published port 80 using -p:
> docker run -p 4000:80 friendlyhello
docker: Error response from daemon: cgroups: cannot found cgroup mount destination: unknown.
ERRO[0001] error waiting for container: context canceled
//解决方法:
sudo mkdir /sys/fs/cgroup/systemd
sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
//再次部署
> docker run -p 4000:80 friendlyhello
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
- Now let’s run the app in the background, in detached mode:
docker run -d -p 4000:80 friendlyhello
-
打开浏览器访问http://localhost:4000
-
也可以通过curl命令访问
$ curl http://localhost:4000
<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>
- 获取 container ID
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED
1fa4ab2cf395 friendlyhello "python app.py" 28 seconds ago
- stop 进程
docker container stop 1fa4ab2cf395
Share your image
1、登录Docker
使用Docker ID 登录,如果没有Docker account, 在 cloud.docker.com. 注册。在本机登录
$ docker login
2、Tag the image
命令格式:
docker tag image username/repository:tag
例如:
docker tag friendlyhello yolanda99/get-started:part2
tag 是可选的,推荐填写,This puts the image in the get-started repository and tag it as part2
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
friendlyhello latest d9e555c53008 3 minutes ago 195MB
yolanda99/get-started part2 d9e555c53008 3 minutes ago 195MB
python 2.7-slim 1c7128a655f6 5 days ago 183MB
...
3、Publish the image
Upload your tagged image to the repository。命令格式:
docker push username/repository:tag
例:
docker push yolanda99/get-started:part2
4、Pull and run the image from the remote repository
From now on, you can use docker run and run your app on any machine with this command:
docker run -p 4000:80 username/repository:tag
If the image isn’t available locally on the machine, Docker pulls it from the repository.
$ docker run -p 4000:80 yolanda99/get-started:part2
Unable to find image 'yolanda99/get-started:part2' locally
part2: Pulling from yolanda99/get-started
Digest: sha256:067288f859e81e830b67be58c7e8863a4535f6b23a52a57d02526728eb82f079
Status: Downloaded newer image for yolanda99/get-started:part2
* Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
命令小结
docker build -t friendlyhello . # Create image using this directory's Dockerfile
docker run -p 4000:80 friendlyhello # Run "friendlyhello" mapping port 4000 to 80
docker run -d -p 4000:80 friendlyhello # Same thing, but in detached mode
docker container ls # List all running containers
docker container ls -a # List all containers, even those not running
docker container stop <hash> # Gracefully stop the specified container
docker container kill <hash> # Force shutdown of the specified container
docker container rm <hash> # Remove specified container from this machine
docker container rm $(docker container ls -a -q) # Remove all containers
docker image ls -a # List all images on this machine
docker image rm <image id> # Remove specified image from this machine
docker image rm $(docker image ls -a -q) # Remove all images from this machine
docker login # Log in this CLI session using your Docker credentials
docker tag <image> username/repository:tag # Tag <image> for upload to registry
docker push username/repository:tag # Upload tagged image to registry
docker run username/repository:tag # Run image from a registry