0
0

前提条件

  • Python 3.11.6
  • Poetry 1.82

フォルダ構成

大体poetry newで生成されるものを使用しました。

my_project/
├── .venv/
├── main/
│   └─ server.py
├── tests/
│   └─ テストファイルたち
├── Dockerfile
├── poetry.lock
├── pyproject.toml
├── README.md
├── .dockerignore
└── .pre-commit-config.yaml

testやpre-commitは今回の記事では触れません。

ライブラリ追加

poetryで必要なライブラリをインストールしていきます。
必要なのはfastapiuvicornです。

poetry add fastapi uvicorn

ファイル作成

server.py

server.py
from fastapi import FastAPI

server = FastAPI()

@server.get("/")
async def root():
    return {"message": "Hello World"}

よくある"Hello, World"を返すだけのやつです。

.dockerignore

.dockerignore
# git関連
.git
.gitignore

# 開発でしか使用しない
tests
.pre-commit-config.yaml
.vscode

# コンテナに含める必要はない
Dockerfile
.dockerignore

# ドキュメント
README.md

# 仮想環境
.venv

# キャッシュファイル
**/*/__pycache__

# このプロジェクトでは使用していない
**/*/__init__.py

コンテナに含める必要のないファイルを指定します。

Dockerfile

# builderとrunnerで使うベースイメージを決めています
FROM python:3.11.9-slim-bullseye AS base

# baseをbuilderステージで使用
FROM base AS builder

RUN pip install poetry

WORKDIR /app

# 作業ディレクトリにpyproject.tomlとpoetry.lockをコピー
COPY pyproject.toml poetry.lock ./

# poetryの仮想環境を作らないように指定、依存関係のインストールを行う
# --no-devを付けることで、開発にしか使用しないパッケージを除いてインストールする
RUN poetry config virtualenvs.create false \
    && poetry install --no-dev

# プロジェクトのコードをコピー
# COPY main ./ とすると失敗します。理由がわかる方教えてください。
COPY . ./

# baseをrunnerステージで使用
FROM base AS runner 
WORKDIR /app

# システムグループを作成
RUN addgroup --system --gid 1001 python

# システムユーザーを作成
RUN adduser --system --uid 1001 api

# builderステージから/appディレクトリ全体をrunnerステージにコピー
COPY --from=builder /app /app

# builderステージからPythonのサイトパッケージディレクトリをrunnerステージにコピー
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages

# builderステージから/usr/local/binディレクトリをrunnerステージにコピー
COPY --from=builder /usr/local/bin /usr/local/bin

# ユーザーをapiに設定
USER api

# コンテナの8080番ポートを開ける
EXPOSE 8080

# poetryを使ってuvicornを実行し、APIサーバーの起動を行っている
CMD ["poetry", "run", "uvicorn", "main.server:server", "--host", "0.0.0.0", "--port", "8080"]

マルチステージビルドを採用することで最終的なイメージのサイズを小さくしています。
また、一般ユーザー(api)にユーザー切り替えすることで、コンテナがroot権限で実行されないようにしています。

# docker runまで

Dockerfileがあるディレクトリからターミナルを操作する想定です。

# name=任意の名前
# tag=任意のタグ
docker build -t name:tag .

最後のコロンはDockerfileに位置を指定しているものです。

docker runを実行します。

docker run -it -p 8080:8080 name:tag
> Creating virtualenv chroma-key-api-9TtSrW0h-py3.11 in /home/api/.cache/pypoetry/virtualenvs
> INFO:     Started server process [1]
> INFO:     Waiting for application startup.
> INFO:     Application startup complete.
> INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)

これでhttp://0.0.0.0:8080に接続できれば成功です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0