🎆

ブラウザ上でコードを書いて実行(2)

2022/06/01に公開

https://zenn.dev/u_tan/articles/f351dc7e84e6f3

この記事の改良版(?)[1]を作りました。

https://github.com/OHMORIYUSUKE/Playground

改良した点

  • 任意のコードを実行するコンテナを分割
  • コンテナ間で実行するコードを共有
  • apiサーバーのイメージサイズを小さくした

概要

構成図

Dockerコンテナ内からホスト側のDockerコンテナを操作しています。(Docker outside of Dockerを行っています)

https://kazuhira-r.hatenablog.com/entry/2021/07/22/204449

役割

apiサーバー

Fast API(Python)で動作しています。フロントエンドはFastAPIのテンプレートエンジンを使っています。
コード・標準の入力、実行結果の出力を行います。

Fast APIのテンプレートエンジン
https://fastapi.tiangolo.com/advanced/templates/

コードを実行するコンテナ(Perl実行コンテナ、Go実行コンテナ...)

言語別にコンテナを動かしています。それぞれ、役割の言語のみ実行可能です。

例)

Playground/docker/go/Dockerfile
FROM golang:1.18

WORKDIR /user/run-scripts
Playground/docker/julia/Dockerfile
FROM julia

WORKDIR /user/run-scripts

Docker outside of Dockerとは

Dockerコンテナ内でホストのDockerとソケットを共有し、ホスト側のDockerを操作します。

詳細

https://zenn.dev/raku/articles/f278acb46651fc#doodとは

Playground/docker-compose.yml
services:
  web:
    build: ./server
    container_name: DooD-web
    volumes:
      - ./server/app:/app
+      - /var/run/docker.sock:/var/run/docker.sock
    ports:
      - 80:8000

apiサーバーのコンテナ

Playground/server/Dockerfile
FROM python:3.8

+RUN apt-get update && apt-get install -y \
+    curl \
+    && rm -rf /var/lib/apt/lists/*
+
+ENV DOCKER_CLIENT_VERSION=1.12.3
+ENV DOCKER_API_VERSION=1.24
+RUN curl -fsSL +https://get.docker.com/builds/Linux/x86_64/docker-${DOCKER_CLIENT_VERSION}.tgz \
+    | tar -xzC /usr/local/bin --strip=1 docker/docker

# コンテナ内で必要なパッケージをインストール
WORKDIR /app
COPY /app/requirements.txt .
RUN pip install -r requirements.txt

# __pycache__
ENV PYTHONDONTWRITEBYTECODE 1

WORKDIR /app
EXPOSE 8000
# FastAPIを8000ポートで待機
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]

webコンテナにDockerをインストールし、- /var/run/docker.sock:/var/run/docker.sockでホストとコンテナでソケットを共有することで、webコンテナからrustコンテナやgoコンテナを実行できる。

これにより、apiサーバーのコンテナからrustコンテナ、goコンテナ...を呼び出し、任意のコードを実行し、結果をapiサーバーのコンテナが受け取ることができます。

脚注
  1. ホスト側のDockerを操作するので、前回のこれより危険なものになりました。 ↩︎

Discussion