Docker備忘録
TILリポジトリに書いていたことを転記しただけで校正など一切してないです。
ここが違う!などあったらコメントで教えていただけますと幸いです。
Dockerfile
FROM
大抵のDockerfileで最初に読み込む
ベースとなるイメージを決定する
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.8
COPY
COPY . /app
このパターンで言うとすべてのファイルを/appにコピーする(この実例は少し特殊)
似たもので言うとADDがある(ADDでは解凍してコピー、COPYでは解凍はせずそのままコピー)
RUN
パッケージインストールなどのコマンド(pip install など)
RUN pip install sqlalchemy
CMD
コンテナが作成されたあとで実行するコマンドを指定する
CMD ["ping","127.0.0.1","-c","100"]
その他基本概念
volume
Dockerのデータの永続化
Volumeはデータ保持・永続化のために設計されており、コンテナのライフサイクルとは独立してファイルの管理を行う
わからん
volumes:
- ./messages:/appp/messages
ローカルの./messagesをdocker上の/appp/messagesにマウントする
volumes:
- messages:/appp/messages
これだとnamed volumeを使うことになる。
Volumesには種類がある(らしい)
- volume
- Docker によって生成され管理される
- Docker ホスト上のディレクトリにボリュームが保存される
- VSCodeのDockerタブから見れるのはこれ(多分)
- bind
- ホストマシン上のファイルやディレクトリがコンテナーにマウントされる
- コンテナ内に動作するプロセスを通じてホストのファイルシステムに変更がかけられる
- tmpfs
- named pipe
ports
ポートフォワーディング
port(ポート) forwarding(転送)
※あくまでdocker-composeでしか試してない内容です※
具体例1 Flaskとgunicornだけでdocker-composeを実行する場合
.
├── app
│ ├── Dockerfile
│ ├── main.py
│ └── requirements.txt
└── docker-compose.yml
main.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return {'messagege': 'hiiiii'}
これだけで動く。if __name__なんていらない
Dockerfile
FROM python:3.7
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
requirememts.txt
gunicorn
flask
docker-compose.yml
version: '3'
services:
app:
container_name: fastapi_practice
build: ./app
ports:
- "5001:5000"
command: gunicorn main:app -b 0.0.0.0:5000
これをローカルで実行すると、localhost:5001で{'messagege': 'hiiiii'}が表示される
docker-compose.ymlでポートフォワーディングを指定しているが、これはlocalhostの5001番にアクセスしたときに5000番で待機しているgunicornに転送しているということである
当然"5000:5000"としてlocalhost:5000にアクセスしても同じ挙動をする。
ただし"5000"だと表示されない。これだと5000番への転送設定はされているが、開放されるポートがdockerによって決められる(多分)。docker ps
で確認できる。
❯ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4be76bc52e85 smallest_docker_app "gunicorn main:app -…" 28 seconds ago Up 28 seconds 0.0.0.0:60069->5000/tcp fastapi_practice
具体例2 Flask, gunicorn, nginxを使うとき
.
├── app
│ ├── Dockerfile
│ ├── main.py
│ └── requirements.txt
├── docker-compose.yml
└── nginx
├── Dockerfile
└── default.conf
nginxではportsでポートを指定しているが、appではポートを指定していない。
例えば先ほどと同じくappの方でも"5001:5000"で開放すると、5001番に接続しても{"messagege":"hiiiii"}が取得できてしまい、意図しない挙動となる。
Discussion