3

我有一个运行 Flask 应用程序的 Docker 容器。当 Flask 接收到 http 请求时,我想触发一个新的临时 Docker 容器的执行,一旦它完成它必须做的事情就会关闭。

我已经阅读 Docker-in-Docker 应该避免,所以这个新容器应该在我的主机上作为同级容器运行,而不是在 Flask 容器中运行。

使用docker-py的解决方案是什么?

4

2 回答 2

6

docker.sock我们通过在主机和容器之间挂载为共享卷来做这样的事情。这允许容器向机器发送命令,例如 docker run

这是我们 CI 系统的一个例子:

 volumes:
 - /var/run/docker.sock:/var/run/docker.sock
于 2018-08-12T15:22:19.597 回答
3

回答我自己的问题。这是一个完整的设置。在一个文件夹中,创建以下文件:

  • 要求.txt
  • Dockerfile
  • 码头工人-compose.yml
  • api.py

要求.txt

docker==3.5.0
flask==1.0.2

Dockerfile

FROM python:3.7-alpine3.7


# Project files
ARG PROJECT_DIR=/srv/api
RUN mkdir -p $PROJECT_DIR
WORKDIR $PROJECT_DIR
COPY requirements.txt ./

# Install Python dependencies
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

码头工人-compose.yml

确保将 docker.sock 安装在卷中,如上面前面的答案中所述。

version: '3'
services:
  api:
    container_name: test
    restart: always
    image: test
    build:
      context: ./
    volumes:
      - ./:/srv/api/
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      FLASK_APP: api.py
    command: ["flask", "run", "--host=0.0.0.0"]
    ports:
      - 5000:5000

api.py

from flask import Flask
import docker
app = Flask(__name__)


@app.route("/")
def hello():
    client = docker.from_env()
    client.containers.run('alpine', 'echo hello world', detach=True, remove=True)
    return "Hello World!"

然后打开浏览器并导航到http://0.0.0.0:5000/

它将触发 alpine 容器的执行。如果你还没有 alpine 镜像,第一次会需要一些时间,因为 Docker 会自动下载镜像。

参数detach=True允许异步执行容器,因此 Flask 在返回响应之前不会等待进程结束。

该参数remove=True指示 Docker 在执行完成后删除容器。

于 2018-08-12T16:19:59.900 回答