--- /dev/null
+# 컨ν
μ΄λμ FastAPI - λ컀
+
+FastAPI μ΄ν리μΌμ΄μ
μ λ°°ν¬ν λ μΌλ°μ μΈ μ κ·Ό λ°©λ²μ **리λ
μ€ μ»¨ν
μ΄λ μ΄λ―Έμ§**λ₯Ό μμ±νλ κ²μ
λλ€. μ΄ λ°©λ²μ μ£Όλ‘ <a href="https://www.docker.com/" class="external-link" target="_blank">**λ컀**</a>λ₯Ό μ¬μ©ν΄ μ΄λ£¨μ΄μ§λλ€. κ·Έλ° λ€μ ν΄λΉ 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό λͺκ°μ§ λ°©λ²μΌλ‘ λ°°ν¬ν μ μμ΅λλ€.
+
+리λ
μ€ μ»¨ν
μ΄λλ₯Ό μ¬μ©νλ λ°μλ **보μ**, **λ°λ³΅ κ°λ₯μ±**, **λ¨μν¨** λ±μ μ₯μ μ΄ μμ΅λλ€.
+
+!!! ν
+ μκ°μ μ«κΈ°κ³ μκ³ μ΄λ―Έ μ΄λ°κ²λ€μ μκ³ μλ€λ©΄ [`Dockerfile`π](#build-a-docker-image-for-fastapi)λ‘ μ νν μ μμ΅λλ€.
+
+<details>
+<summary>λ컀νμΌ λ―Έλ¦¬λ³΄κΈ° π</summary>
+
+```Dockerfile
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+COPY ./app /code/app
+
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+
+# If running behind a proxy like Nginx or Traefik add --proxy-headers
+# CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--proxy-headers"]
+```
+
+</details>
+
+## 컨ν
μ΄λλ
+
+컨ν
μ΄λ(μ£Όλ‘ λ¦¬λ
μ€ μ»¨ν
μ΄λ)λ μ΄ν리μΌμ΄μ
μ μμ‘΄μ±κ³Ό νμν νμΌλ€μ λͺ¨λ ν¨ν€μ§νλ λ§€μ° **κ°λ²Όμ΄** λ°©λ²μ
λλ€. 컨ν
μ΄λλ κ°μ μμ€ν
μ μλ λ€λ₯Έ 컨ν
μ΄λ(λ€λ₯Έ μ΄ν리μΌμ΄μ
μ΄λ μμλ€)μ λ
립μ μΌλ‘ μ μ§λ©λλ€.
+
+리λ
μ€ μ»¨ν
μ΄λλ νΈμ€νΈ(λ¨Έμ , κ°μ λ¨Έμ , ν΄λΌμ°λ μλ² λ±)μ κ°μ 리λ
μ€ μ»€λμ μ¬μ©ν΄ μ€νλ©λλ€. μ΄λ§μ 리λ
μ€ μ»¨ν
μ΄λκ° (μ 체 μ΄μ체μ λ₯Ό λͺ¨λ°©νλ λ€λ₯Έ κ°μ λ¨Έμ κ³Ό λΉκ΅νμ λ) λ§€μ° κ°λ³λ€λ κ²μ μλ―Έν©λλ€.
+
+μ΄ λ°©λ²μ ν΅ν΄, 컨ν
μ΄λλ μ§μ νλ‘μΈμ€λ₯Ό μ€ννλ κ²κ³Ό λΉμ·ν μ λμ **μ μ μμ**μ μλΉν©λλ€ (κ°μ λ¨Έμ μ ν¨μ¬ λ§μ μμμ μλΉν κ²μ
λλ€).
+
+컨ν
μ΄λλ λν κ·Έλ€λ§μ **λ
립λ** μ€ν νλ‘μΈμ€ (μΌλ°μ μΌλ‘ νλμ νλ‘μΈμ€λ‘ μΆ©λΆν©λλ€), νμΌ μμ€ν
, κ·Έλ¦¬κ³ λ€νΈμν¬λ₯Ό κ°μ§λ―λ‘ λ°°ν¬, 보μ, κ°λ° λ° κΈ°ν κ³Όμ μ λ¨μν ν©λλ€.
+
+## 컨ν
μ΄λ μ΄λ―Έμ§λ
+
+**컨ν
μ΄λ**λ **컨ν
μ΄λ μ΄λ―Έμ§**λ₯Ό μ€νν κ² μ
λλ€.
+
+컨ν
μ΄λ μ΄λ―Έμ§λ 컨ν
μ΄λμ νμν λͺ¨λ νμΌ, νκ²½ λ³μ κ·Έλ¦¬κ³ λν΄νΈ λͺ
λ Ή/νλ‘κ·Έλ¨μ **μ μ ** λ²μ μ
λλ€. μ¬κΈ°μ **μ μ **μ΄λ λ§μ 컨ν
μ΄λ **μ΄λ―Έμ§**κ° μλλκ±°λ μ€νλμ§ μμΌλ©°, λ¨μ§ ν¨ν€μ§ νμΌκ³Ό λ©ν λ°μ΄ν°λΌλ κ²μ μλ―Έν©λλ€.
+
+μ μ₯λ μ μ 컨ν
μΈ μΈ **컨ν
μ΄λ μ΄λ―Έμ§**μ λμ‘°λκ², **컨ν
μ΄λ**λ λ³΄ν΅ μ€νλ μ μλ μλ μΈμ€ν΄μ€λ₯Ό μλ―Έν©λλ€.
+
+**컨ν
μ΄λ**κ° (**컨ν
μ΄λ μ΄λ―Έμ§**λ‘ λΆν°) μμλκ³ μ€νλλ©΄, 컨ν
μ΄λλ νμΌμ΄λ νκ²½ λ³μλ₯Ό μμ±νκ±°λ λ³κ²½ν μ μμ΅λλ€. μ΄λ¬ν λ³νλ μ€μ§ 컨ν
μ΄λμμλ§ μ‘΄μ¬νλ©°, κ·Έ κΈ°λ°μ΄ λλ 컨ν
μ΄λ μ΄λ―Έμ§μλ μ§μλμ§ μμ΅λλ€ (μ¦ λμ€ν¬μλ μ μ₯λμ§ μμ΅λλ€).
+
+컨ν
μ΄λ μ΄λ―Έμ§λ **νλ‘κ·Έλ¨** νμΌκ³Ό 컨ν
μΈ , μ¦ `python`κ³Ό μ΄λ€ νμΌ `main.py`μ λΉκ΅ν μ μμ΅λλ€.
+
+κ·Έλ¦¬κ³ (**컨ν
μ΄λ μ΄λ―Έμ§**μ λλΉν΄μ) **컨ν
μ΄λ**λ μ΄λ―Έμ§μ μ€μ μ€ν μΈμ€ν΄μ€λ‘ **νλ‘μΈμ€**μ λΉκ΅ν μ μμ΅λλ€. μ¬μ€, 컨ν
μ΄λλ **νλ‘μΈμ€ λ¬λ**μ΄ μμ λλ§ μ€νλ©λλ€ (κ·Έλ¦¬κ³ λ³΄ν΅ νλμ νλ‘μΈμ€ μ
λλ€). 컨ν
μ΄λλ λ΄λΆμμ μ€νλλ νλ‘μΈμ€κ° μμΌλ©΄ μ’
λ£λ©λλ€.
+
+## 컨ν
μ΄λ μ΄λ―Έμ§
+
+λ컀λ **컨ν
μ΄λ μ΄λ―Έμ§**μ **컨ν
μ΄λ**λ₯Ό μμ±νκ³ κ΄λ¦¬νλλ° μ£Όμ λꡬ μ€ νλκ° λμ΄μμ΅λλ€.
+
+κ·Έλ¦¬κ³ <a href="https://hub.docker.com/" class="external-link" target="_blank">λ컀 νλΈ</a>μ λ€μν λꡬ, νκ²½, λ°μ΄ν°λ² μ΄μ€, κ·Έλ¦¬κ³ μ΄ν리μΌμ΄μ
μ λν΄ λ―Έλ¦¬ λ§λ€μ΄μ§ **곡μ 컨ν
μ΄λ μ΄λ―Έμ§**κ° κ³΅κ°λμ΄ μμ΅λλ€.
+
+μλ₯Ό λ€μ΄, 곡μ <a href="https://hub.docker.com/_/python" class="external-link" target="_blank">νμ΄μ¬ μ΄λ―Έμ§</a>κ° μμ΅λλ€.
+
+λν λ€λ₯Έ λμ, μλ₯Ό λ€λ©΄ λ°μ΄ν°λ² μ΄μ€λ₯Ό μν μ΄λ―Έμ§λ€λ μμ΅λλ€:
+
+* <a href="https://hub.docker.com/_/postgres" class="external-link" target="_blank">PostgreSQL</a>
+* <a href="https://hub.docker.com/_/mysql" class="external-link" target="_blank">MySQL</a>
+* <a href="https://hub.docker.com/_/mongo" class="external-link" target="_blank">MongoDB</a>
+* <a href="https://hub.docker.com/_/redis" class="external-link" target="_blank">Redis</a> λ±
+
+미리 λ§λ€μ΄μ§ 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό μ¬μ©νλ©΄ μλ‘ λ€λ₯Έ λꡬλ€μ **κ²°ν©**νκΈ° μ½μ΅λλ€. λλΆλΆμ κ²½μ°μ, **곡μ μ΄λ―Έμ§λ€**μ μ¬μ©νκ³ νκ²½ λ³μλ₯Ό ν΅ν΄ μ€μ ν μ μμ΅λλ€.
+
+μ΄λ° λ°©λ²μΌλ‘ λλΆλΆμ κ²½μ°μ 컨ν
μ΄λμ λ컀μ λν΄ λ°°μΈ μ μμΌλ©° λ€μν λꡬμ μμλ€μ λν μ§μμ μ¬μ¬μ©ν μ μμ΅λλ€.
+
+λ°λΌμ, μλ‘ λ€λ₯Έ **λ€μ€ 컨ν
μ΄λ**λ₯Ό μμ±ν λ€μ μ΄λ€μ μ°κ²°ν μ μμ΅λλ€. μλ₯Ό λ€μ΄ λ°μ΄ν°λ² μ΄μ€, νμ΄μ¬ μ΄ν리μΌμ΄μ
, 리μ‘νΈ νλ‘ νΈμλ μ΄ν리μΌμ΄μ
μ μ¬μ©νλ μΉ μλ²μ λν 컨ν
μ΄λλ₯Ό λ§λ€μ΄ μ΄λ€μ λ΄λΆ λ€νΈμν¬λ‘ κ° μ»¨ν
μ΄λλ₯Ό μ°κ²°ν μ μμ΅λλ€.
+
+λͺ¨λ 컨ν
μ΄λ κ΄λ¦¬ μμ€ν
(λ컀λ μΏ λ²λ€ν°μ€)μ μ΄λ¬ν λ€νΈμνΉ νΉμ±μ ν¬ν¨νκ³ μμ΅λλ€.
+
+## 컨ν
μ΄λμ νλ‘μΈμ€
+
+**컨ν
μ΄λ μ΄λ―Έμ§**λ λ³΄ν΅ **컨ν
μ΄λ**λ₯Ό μμνκΈ° μν΄ νμν λ©νλ°μ΄ν°μ λν΄νΈ 컀맨λ/νλ‘κ·Έλ¨κ³Ό κ·Έ νλ‘κ·Έλ¨μ μ λ¬νκΈ° μν νλΌλ―Έν°λ€μ ν¬ν¨ν©λλ€. μ΄λ 컀맨λ λΌμΈμμ νλ‘κ·Έλ¨μ μ€νν λ νμν κ°λ€κ³Ό μ μ¬ν©λλ€.
+
+**컨ν
μ΄λ**κ° μμλλ©΄, ν΄λΉ 컀맨λ/νλ‘κ·Έλ¨μ΄ μ€νλ©λλ€ (κ·Έλ¬λ λ€λ₯Έ 컀맨λ/νλ‘κ·Έλ¨μ μ€ννλλ‘ μ€λ²λΌμ΄λ ν μ μμ΅λλ€).
+
+컨ν
μ΄λλ **λ©μΈ νλ‘μΈμ€**(컀맨λ λλ νλ‘κ·Έλ¨)μ΄ μ€νλλ λμ μ€νλ©λλ€.
+
+컨ν
μ΄λλ μΌλ°μ μΌλ‘ **λ¨μΌ νλ‘μΈμ€**λ₯Ό κ°μ§κ³ μμ§λ§, λ©μΈ νλ‘μΈμ€μ μλΈ νλ‘μΈμ€λ₯Ό μμνλ κ²λ κ°λ₯νλ©°, μ΄ λ°©λ²μΌλ‘ νλμ 컨ν
μ΄λμ **λ€μ€ νλ‘μΈμ€**λ₯Ό κ°μ§ μ μμ΅λλ€.
+
+κ·Έλ¬λ **μ΅μν νλμ μ€νμ€μΈ νλ‘μΈμ€**λ₯Ό κ°μ§μ§ μκ³ μλ μ€νμ€μΈ 컨ν
μ΄λλ₯Ό κ°μ§ μ μμ΅λλ€. λ§μ½ λ©μΈ νλ‘μΈμ€κ° μ€λ¨λλ©΄, 컨ν
μ΄λλ μ€λ¨λ©λλ€.
+
+## FastAPIλ₯Ό μν λ컀 μ΄λ―Έμ§ λΉλνκΈ°
+
+μ΄μ 무μΈκ°λ₯Ό λ§λ€μ΄ λ΄
μλ€! π
+
+**곡μ νμ΄μ¬** μ΄λ―Έμ§μ κΈ°λ°νμ¬, FastAPIλ₯Ό μν **λ컀 μ΄λ―Έμ§**λ₯Ό **맨 μ²μλΆν°** μμ±νλ λ°©λ²μ 보μ΄κ² μ΅λλ€.
+
+**λλΆλΆμ κ²½μ°**μ λ€μκ³Ό κ°μ κ²λ€μ νκ² λ©λλ€. μλ₯Ό λ€λ©΄:
+
+* **μΏ λ²λ€ν°μ€** λλ μ μ¬ν λꡬ μ¬μ©νκΈ°
+* **λΌμ¦λ² 리 νμ΄**λ‘ μ€ννκΈ°
+* 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό μ€νν ν΄λΌμ°λ μλΉμ€ μ¬μ©νκΈ° λ±
+
+### μꡬ ν¨ν€μ§
+
+μΌλ°μ μΌλ‘λ μ΄ν리μΌμ΄μ
μ νΉμ νμΌμ μν **ν¨ν€μ§ μꡬ 쑰건**μ΄ μμ κ²μ
λλ€.
+
+κ·Έ μꡬ 쑰건μ **μ€μΉ**νλ λ°©λ²μ μ¬λ¬λΆμ΄ μ¬μ©νλ λꡬμ λ°λΌ λ€λ₯Ό κ²μ
λλ€.
+
+κ°μ₯ μΌλ°μ μΈ λ°©λ²μ ν¨ν€μ§ μ΄λ¦κ³Ό λ²μ μ΄ μ€ λ³λ‘ κΈ°λ‘λ `requirements.txt` νμΌμ λ§λλ κ²μ
λλ€.
+
+λ²μ μ λ²μλ₯Ό μ€μ νκΈ° μν΄μλ [FastAPI λ²μ λ€μ λνμ¬](./versions.md){.internal-link target=_blank}μ μ°μ¬μ§ κ²κ³Ό κ°μ μμ΄λμ΄λ₯Ό μ¬μ©ν©λλ€.
+
+μλ₯Ό λ€μ΄, `requirements.txt` νμΌμ λ€μκ³Ό κ°μ μ μμ΅λλ€:
+
+```
+fastapi>=0.68.0,<0.69.0
+pydantic>=1.8.0,<2.0.0
+uvicorn>=0.15.0,<0.16.0
+```
+
+κ·Έλ¦¬κ³ μΌλ°μ μΌλ‘ ν¨ν€μ§ μ’
μμ±μ `pip`λ‘ μ€μΉν©λλ€. μλ₯Ό λ€μ΄:
+
+<div class="termy">
+
+```console
+$ pip install -r requirements.txt
+---> 100%
+Successfully installed fastapi pydantic uvicorn
+```
+
+</div>
+
+!!! μ 보
+ ν¨ν€μ§ μ’
μμ±μ μ μνκ³ μ€μΉνκΈ° μν λ°©λ²κ³Ό λꡬλ λ€μν©λλ€.
+
+ λμ€μ μλ μΈμ
μμ Poetryλ₯Ό μ¬μ©ν μμλ₯Ό 보μ΄κ² μ΅λλ€. π
+
+### **FastAPI** μ½λ μμ±νκΈ°
+
+* `app` λλ ν°λ¦¬λ₯Ό μμ±νκ³ μ΄λν©λλ€.
+* λΉ νμΌ `__init__.py`μ μμ±ν©λλ€.
+* λ€μκ³Ό κ°μ `main.py`μ μμ±ν©λλ€:
+
+```Python
+from typing import Union
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+def read_root():
+ return {"Hello": "World"}
+
+
+@app.get("/items/{item_id}")
+def read_item(item_id: int, q: Union[str, None] = None):
+ return {"item_id": item_id, "q": q}
+```
+
+### λ컀νμΌ
+
+μ΄μ κ°μ νλ‘μ νΈ λλ ν°λ¦¬μ λ€μκ³Ό κ°μ νμΌ `Dockerfile`μ μμ±ν©λλ€:
+
+```{ .dockerfile .annotate }
+# (1)
+FROM python:3.9
+
+# (2)
+WORKDIR /code
+
+# (3)
+COPY ./requirements.txt /code/requirements.txt
+
+# (4)
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (5)
+COPY ./app /code/app
+
+# (6)
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. 곡μ νμ΄μ¬ λ² μ΄μ€ μ΄λ―Έμ§μμ μμν©λλ€.
+
+2. νμ¬ μνΉ λλ ν°λ¦¬λ₯Ό `/code`λ‘ μ€μ ν©λλ€.
+
+ μ¬κΈ°μ `requirements.txt` νμΌκ³Ό `app` λλ ν°λ¦¬λ₯Ό μμΉμν¬ κ²μ
λλ€.
+
+3. μꡬ 쑰건과 νμΌμ `/code` λλ ν°λ¦¬λ‘ 볡μ¬ν©λλ€.
+
+ μ²μμλ **μ€μ§** μꡬ μ‘°κ±΄μ΄ νμν νμΌλ§ 볡μ¬νκ³ , μ΄μΈμ μ½λλ κ·Έλλ‘ λ‘λλ€.
+
+ μ΄ νμΌμ΄ **μμ£Ό λ°λμ§ μκΈ° λλ¬Έμ**, λ컀λ νμΌμ νμ§νμ¬ μ΄ λ¨κ³μ **μΊμ**λ₯Ό μ¬μ©νμ¬ λ€μ λ¨κ³μμλ μΊμλ₯Ό μ¬μ©ν μ μλλ‘ ν©λλ€.
+
+4. μꡬ 쑰건 νμΌμ μλ ν¨ν€μ§ μ’
μμ±μ μ€μΉν©λλ€.
+
+ `--no-cache-dir` μ΅μ
μ `pip`μκ² λ€μ΄λ‘λν ν¨ν€μ§λ€μ λ‘컬 νκ²½μ μ μ₯νμ§ μλλ‘ μ λ¬ν©λλ€. μ΄λ λ§μΉ κ°μ ν¨ν€μ§λ₯Ό μ€μΉνκΈ° μν΄ μ€μ§ `pip`λ§ λ€μ μ€ννλ©΄ λ κ² κ°μ§λ§, 컨ν
μ΄λλ‘ μμ
νλ κ²½μ° κ·Έλ μ§λ μμ΅λλ€.
+
+ !!! λ
ΈνΈ
+ `--no-cache-dir` λ μ€μ§ `pip`μ κ΄λ ¨λμ΄ μμΌλ©°, λ컀λ 컨ν
μ΄λμλ 무κ΄ν©λλ€.
+
+ `--upgrade` μ΅μ
μ `pip`μκ² μ€μΉλ ν¨ν€μ§λ€μ μ
λ°μ΄νΈνλλ‘ ν©λλ€.
+
+ μ΄μ λ¨κ³μμ νμΌμ 볡μ¬ν κ²μ΄ **λ컀 μΊμ**μ μν΄ νμ§λκΈ° λλ¬Έμ, μ΄ λ¨κ³μμλ κ°λ₯ν ν **λ컀 μΊμ**λ₯Ό μ¬μ©νκ² λ©λλ€.
+
+ μ΄ λ¨κ³μμ μΊμλ₯Ό μ¬μ©νλ©΄ **λ§€λ²** λͺ¨λ μ’
μμ±μ λ€μ΄λ‘λ λ°κ³ μ€μΉν νμκ° μμ΄, κ°λ° κ³Όμ μμ μ΄λ―Έμ§λ₯Ό μ§μμ μΌλ‘ μμ±νλ λ°μ λλ **μκ°**μ λ§μ΄ **μ μ½**ν μ μμ΅λλ€.
+
+5. `/code` λλ ν°λ¦¬μ `./app` λλ ν°λ¦¬λ₯Ό 볡μ¬ν©λλ€.
+
+ **μμ£Ό λ³κ²½λλ** λͺ¨λ μ½λλ₯Ό ν¬ν¨νκ³ μκΈ° λλ¬Έμ, λ컀 **μΊμ**λ μ΄ λ¨κ³λ **μ΄νμ λ¨κ³μμ** μ μ¬μ©λμ§ μμ΅λλ€.
+
+ κ·Έλ¬λ―λ‘ μ»¨ν
μ΄λ μ΄λ―Έμ§ λΉλ μκ°μ μ΅μ ννκΈ° μν΄ `Dockerfile`μ **κ±°μ λ λΆλΆ**μ μ
λ ₯νλ κ²μ΄ μ€μν©λλ€.
+
+6. `uvicorn` μλ²λ₯Ό μ€ννκΈ° μν΄ **컀맨λ**λ₯Ό μ€μ ν©λλ€.
+
+ `CMD`λ λ¬Έμμ΄ λ¦¬μ€νΈλ₯Ό μ
λ ₯λ°κ³ , κ° λ¬Έμμ΄μ 컀맨λ λΌμΈμ κ° μ€μ μ
λ ₯ν λ¬Έμμ΄μ
λλ€.
+
+ μ΄ μ»€λ§¨λλ **νμ¬ μνΉ λλ ν°λ¦¬**μμ μ€νλλ©°, μ΄λ μμμ `WORKDIR /code`λ‘ μ€μ ν `/code` λλ ν°λ¦¬μ κ°μ΅λλ€.
+
+ νλ‘κ·Έλ¨μ΄ `/code`μμ μμνκ³ κ·Έ μμ `./app` λλ ν°λ¦¬κ° μ¬λ¬λΆμ μ½λμ ν¨κ» λ€μ΄μκΈ° λλ¬Έμ, **Uvicorn**μ μ΄λ₯Ό λ³΄κ³ `app`μ `app.main`μΌλ‘λΆν° **λΆλ¬ μ¬** κ²μ
λλ€.
+
+!!! ν
+ κ° μ½λ λΌμΈμ μ½λμ μ«μ λ²λΈμ ν΄λ¦νμ¬ λ¦¬λ·°ν μ μμ΅λλ€. π
+
+μ΄μ μ¬λ¬λΆμ λ€μκ³Ό κ°μ λλ ν°λ¦¬ ꡬ쑰λ₯Ό κ°μ§κ³ μμ κ²μ
λλ€:
+
+```
+.
+βββ app
+βΒ Β βββ __init__.py
+β βββ main.py
+βββ Dockerfile
+βββ requirements.txt
+```
+
+#### TLS μ’
λ£ νλ‘μμ λ°°ν
+
+λ§μ½ μ¬λ¬λΆμ΄ 컨ν
μ΄λλ₯Ό Nginx λλ Traefikκ³Ό κ°μ TLS μ’
λ£ νλ‘μ (λ‘λ λ°Έλ°μ) λ€μμ μ€ννκ³ μλ€λ©΄, `--proxy-headers` μ΅μ
μ λνλ κ²μ΄ μ’μ΅λλ€. μ΄ μ΅μ
μ Uvicornμκ² μ΄ν리μΌμ΄μ
μ΄ HTTPS λ±μ λ€μμ μ€νλκ³ μμΌλ―λ‘ νλ‘μμμ μ μ‘λ ν€λλ₯Ό μ λ’°ν μ μλ€κ³ μ립λλ€.
+
+```Dockerfile
+CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
+```
+
+#### λ컀 μΊμ
+
+μ΄ `Dockerfile`μλ μ€μν νΈλ¦μ΄ μλλ°, μ²μμλ **μμ‘΄μ±μ΄ μλ νμΌλ§** 볡μ¬νκ³ , λλ¨Έμ§ μ½λλ κ·Έλλ‘ λ‘λλ€. μ μ΄λ° λ°©λ²μ μ¨μΌνλμ§ μ€λͺ
νκ² μ΅λλ€.
+
+```Dockerfile
+COPY ./requirements.txt /code/requirements.txt
+```
+
+λ컀μ λ€λ₯Έ λꡬλ€μ 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό **μ¦κ°νλ λ°©μμΌλ‘ λΉλ**ν©λλ€. `Dockerfile`μ 맨 μ λΆλΆλΆν° μμν΄, λ μ΄μ΄ μμ μλ‘μ΄ λ μ΄μ΄λ₯Ό λνλ λ°©μμΌλ‘, `Dockerfile`μ κ° μ§μ μ¬νμΌλ‘ λΆν° μμ±λ μ΄λ€ νμΌμ΄λ λν΄κ°λλ€.
+
+λ컀 κ·Έλ¦¬κ³ μ΄μ μ μ¬ν λꡬλ€μ μ΄λ―Έμ§ μμ± μμ **λ΄λΆ μΊμ**λ₯Ό μ¬μ©ν©λλ€. λ§μ½ μ΄λ€ νμΌμ΄ λ§μ§λ§μΌλ‘ 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό λΉλν λλ‘λΆν° λ°λμ§ μμλ€λ©΄, νμΌμ λ€μ 볡μ¬νμ¬ μλ‘μ΄ λ μ΄μ΄λ₯Ό μ²μλΆν° μμ±νλ κ²μ΄ μλλΌ, λ§μ§λ§μ μμ±νλ **κ°μ λ μ΄μ΄λ₯Ό μ¬μ¬μ©**ν©λλ€.
+
+λ¨μ§ νμΌ λ³΅μ¬λ₯Ό μ§μνλ κ²μΌλ‘ ν¨μ¨μ΄ λ§μ΄ ν₯μλλ κ²μ μλμ§λ§, κ·Έ λ¨κ³μμ μΊμλ₯Ό μ¬μ©νκΈ° λλ¬Έμ, **λ€μ λ¨κ³μμλ λ§μ°¬κ°μ§λ‘ μΊμλ₯Ό μ¬μ©**ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, λ€μκ³Ό κ°μ μμ‘΄μ±μ μ€μΉνλ μ§μ μ¬νμ μν μΊμλ₯Ό μ¬μ©ν μ μμ΅λλ€:
+
+```Dockerfile
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+```
+
+ν¨ν€μ§λ₯Ό ν¬ν¨νλ νμΌμ **μμ£Ό λ³κ²½λμ§ μμ΅λλ€**. λ°λΌμ ν΄λΉ νμΌλ§ 볡μ¬νλ―λ‘μ, λ컀λ κ·Έ λ¨κ³μ **μΊμλ₯Ό μ¬μ©**ν μ μμ΅λλ€.
+
+κ·Έ λ€μμΌλ‘, λ컀λ **λ€μ λ¨κ³μμ** μμ‘΄μ±μ λ€μ΄λ‘λνκ³ μ€μΉνλ **μΊμλ₯Ό μ¬μ©**ν μ μκ² λ©λλ€. λ°λ‘ μ΄ κ³Όμ μμ μ°λ¦¬λ **λ§μ μκ°μ μ μ½**νκ² λ©λλ€. β¨ ...κ·Έλ¦¬κ³ κΈ°λ€λ¦¬λ μ§λ£¨ν¨λ νΌν μ μμ΅λλ€. πͺπ
+
+ν¨ν€μ§ μμ‘΄μ±μ λ€μ΄λ‘λ λ°κ³ μ€μΉνλ λ°μ΄λ **μ λΆμ΄ 걸릴 μ μμ§λ§**, **μΊμ**λ₯Ό μ¬μ©νλ©΄ μ΅λ **μ μ΄λ§μ** λλΌ μ μμ΅λλ€.
+
+λν μ¬λ¬λΆμ΄ κ°λ° κ³Όμ μμ μ½λμ λ³κ²½ μ¬νμ΄ λ°μλμλμ§ νμΈνκΈ° μν΄ μ»¨ν
μ΄λ μ΄λ―Έμ§λ₯Ό κ³μν΄μ λΉλνλ©΄, μ μ½λ μκ°μ μΆμ λμ΄ λμ± μ»€μ§ κ²μ
λλ€.
+
+κ·Έλ¦¬κ³ λμ `Dockerfile`μ κ±°μ λ λΆλΆμμ, λͺ¨λ μ½λλ₯Ό 볡μ¬ν©λλ€. μ΄κ²μ΄ **κ°μ₯ λΉλ²νκ² λ³κ²½**λλ λΆλΆμ΄λ©°, λλΆλΆμ κ²½μ°μ μ΄ λ€μ λ¨κ³μμλ μΊμλ₯Ό μ¬μ©ν μ μκΈ° λλ¬Έμ κ°μ₯ λ§μ§λ§μ λ‘λλ€.
+
+```Dockerfile
+COPY ./app /code/app
+```
+
+### λ컀 μ΄λ―Έμ§ μμ±νκΈ°
+
+μ΄μ λͺ¨λ νμΌμ΄ μ μ리μ μμΌλ, 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό λΉλν©λλ€.
+
+* (μ¬λ¬λΆμ `Dockerfile`κ³Ό `app` λλ ν°λ¦¬κ° μμΉν) νλ‘μ νΈ λλ ν°λ¦¬λ‘ μ΄λν©λλ€.
+* FastAPI μ΄λ―Έμ§λ₯Ό λΉλν©λλ€:
+
+<div class="termy">
+
+```console
+$ docker build -t myimage .
+
+---> 100%
+```
+
+</div>
+
+!!! ν
+ 맨 λμ μλ `.` μ μ£Όλͺ©ν©μλ€. μ΄λ `./`μ λλ±νλ©°, λ컀μκ² μ»¨ν
μ΄λ μ΄λ―Έμ§λ₯Ό λΉλνκΈ° μν λλ ν°λ¦¬λ₯Ό μλ €μ€λλ€.
+
+ μ΄ κ²½μ°μλ νμ¬ λλ ν°λ¦¬(`.`)μ κ°μ΅λλ€.
+
+### λ컀 컨ν
μ΄λ μμνκΈ°
+
+* μ¬λ¬λΆμ μ΄λ―Έμ§μ κΈ°λ°νμ¬ μ»¨ν
μ΄λλ₯Ό μ€νν©λλ€:
+
+<div class="termy">
+
+```console
+$ docker run -d --name mycontainer -p 80:80 myimage
+```
+
+</div>
+
+## 체ν¬νκΈ°
+
+μ¬λ¬λΆμ λ컀 컨ν
μ΄λ URLμμ μ€ν μ¬νμ 체ν¬ν μ μμ΅λλ€. μλ₯Ό λ€μ΄: <a href="http://192.168.99.100/items/5?q=somequery" class="external-link" target="_blank">http://192.168.99.100/items/5?q=somequery</a> λλ <a href="http://127.0.0.1/items/5?q=somequery" class="external-link" target="_blank">http://127.0.0.1/items/5?q=somequery</a> (λλ λμΌνκ², μ¬λ¬λΆμ λ컀 νΈμ€νΈλ₯Ό μ΄μ©ν΄μ 체ν¬ν μλ μμ΅λλ€).
+
+μλμ λΉμ·ν κ²μ λ³΄κ² λ κ²μ
λλ€:
+
+```JSON
+{"item_id": 5, "q": "somequery"}
+```
+
+## μΈν°λν°λΈ API λ¬Έμ
+
+μ΄μ μ¬λ¬λΆμ <a href="http://192.168.99.100/docs" class="external-link" target="_blank">http://192.168.99.100/docs</a> λλ <a href="http://127.0.0.1/docs" class="external-link" target="_blank">http://127.0.0.1/docs</a>λ‘ μ΄λν μ μμ΅λλ€(λλ, μ¬λ¬λΆμ λ컀 νΈμ€νΈλ₯Ό μ΄μ©ν μ μμ΅λλ€).
+
+μ¬λ¬λΆμ μλμΌλ‘ μμ±λ μΈν°λν°λΈ API(<a href="https://github.com/swagger-api/swagger-ui" class="external-link" target="_blank">Swagger UI</a>μμ μ 곡λ)λ₯Ό λ³Ό μ μμ΅λλ€:
+
+
+
+## λμ API λ¬Έμ
+
+λν μ¬λ¬λΆμ <a href="http://192.168.99.100/redoc" class="external-link" target="_blank">http://192.168.99.100/redoc</a> λλ <a href="http://127.0.0.1/redoc" class="external-link" target="_blank">http://127.0.0.1/redoc</a>μΌλ‘ μ΄λν μ μμ΅λλ€(λλ, μ¬λ¬λΆμ λ컀 νΈμ€νΈλ₯Ό μ΄μ©ν μ μμ΅λλ€).
+
+μ¬λ¬λΆμ μλμΌλ‘ μμ±λ λμ λ¬Έμ(<a href="https://github.com/Rebilly/ReDoc" class="external-link" target="_blank">ReDoc</a>μμ μ 곡λ)λ₯Ό λ³Ό μ μμ΅λλ€:
+
+
+
+## λ¨μΌ νμΌ FastAPIλ‘ λ컀 μ΄λ―Έμ§ μμ±νκΈ°
+
+λ§μ½ μ¬λ¬λΆμ FastAPIκ° νλμ νμΌμ΄λΌλ©΄, μλ₯Ό λ€μ΄ `./app` λλ ν°λ¦¬ μμ΄ `main.py` νμΌλ§μΌλ‘ μ΄λ£¨μ΄μ Έ μλ€λ©΄, νμΌ κ΅¬μ‘°λ λ€μκ³Ό μ μ¬ν κ²μ
λλ€:
+
+```
+.
+βββ Dockerfile
+βββ main.py
+βββ requirements.txt
+```
+
+κ·Έλ¬λ©΄ μ¬λ¬λΆλ€μ `Dockerfile` λ΄μ μλ νμΌμ 볡μ¬νκΈ° μν΄ κ·Έμ μμνλ κ²½λ‘λ₯Ό λ°κΎΈκΈ°λ§ νλ©΄ λ©λλ€:
+
+```{ .dockerfile .annotate hl_lines="10 13" }
+FROM python:3.9
+
+WORKDIR /code
+
+COPY ./requirements.txt /code/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (1)
+COPY ./main.py /code/
+
+# (2)
+CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. `main.py` νμΌμ `/code` λλ ν°λ¦¬λ‘ κ³§λ°λ‘ 볡μ¬ν©λλ€(`./app` λλ ν°λ¦¬λ κ³ λ €νμ§ μμ΅λλ€).
+
+2. Uvicornμ μ€νν΄ `app` κ°μ²΄λ₯Ό (`app.main` λμ ) `main`μΌλ‘ λΆν° λΆλ¬μ€λλ‘ ν©λλ€.
+
+κ·Έ λ€μ Uvicorn 컀맨λλ₯Ό μ‘°μ ν΄μ FastAPI κ°μ²΄λ₯Ό λΆλ¬μ€λλ° `app.main` λμ μ μλ‘μ΄ λͺ¨λ `main`μ μ¬μ©νλλ‘ ν©λλ€.
+
+## λ°°ν¬ κ°λ
+
+μ΄μ 컨ν
μ΄λμ μΈ‘λ©΄μμ [λ°°ν¬ κ°λ
](./concepts.md){.internal-link target=_blank}μμ λ€λ£¨μλ κ²κ³Ό κ°μ λ°°ν¬ κ°λ
μ λν΄ μ΄μΌκΈ°ν΄ λ³΄κ² μ΅λλ€.
+
+컨ν
μ΄λλ μ£Όλ‘ μ΄ν리μΌμ΄μ
μ λΉλνκ³ λ°°ν¬νκΈ° μν κ³Όμ μ λ¨μννλ λꡬμ΄μ§λ§, **λ°°ν¬ κ°λ
**μ λν νΉμ ν μ κ·Όλ²μ κ°μνμ§ μκΈ° λλ¬Έμ κ°λ₯ν λ°°ν¬ μ λ΅μλ μ¬λ¬κ°μ§κ° μμ΅λλ€.
+
+**μ’μ μμ**μ μλ‘ λ€λ₯Έ μ λ΅λ€μ ν¬κ΄νλ λ°°ν¬ κ°λ
μ΄ μλ€λ μ μ
λλ€. π
+
+컨ν
μ΄λ μΈ‘λ©΄μμ **λ°°ν¬ κ°λ
**μ λ¦¬λ·°ν΄ λ³΄κ² μ΅λλ€:
+
+* HTTPS
+* ꡬλνκΈ°
+* μ¬μμ
+* 볡μ (μ€ν μ€μΈ νλ‘μΈμ€ κ°μ)
+* λ©λͺ¨λ¦¬
+* μμνκΈ° μ λ¨κ³λ€
+
+## HTTPS
+
+λ§μ½ μ°λ¦¬κ° FastAPI μ΄ν리μΌμ΄μ
μ μν **컨ν
μ΄λ μ΄λ―Έμ§**μλ§ μ§μ€νλ€λ©΄ (κ·Έλ¦¬κ³ λμ€μ μ€νλ **컨ν
μ΄λ**μ), HTTPSλ μΌλ°μ μΌλ‘ λ€λ₯Έ λꡬμ μν΄ **μΈλΆμ μΌλ‘** λ€λ£¨μ΄μ§ κ² μ
λλ€.
+
+**HTTPS**μ **μΈμ¦μ**μ **μλ** μ·¨λμ λ€λ£¨λ κ²μ λ€λ₯Έ 컨ν
μ΄λκ° λ μ μλλ°, μλ₯Ό λ€μ΄ <a href="https://traefik.io/" class="external-link" target="_blank">Traefik</a>μ μ¬μ©νλ κ²μ
λλ€.
+
+!!! ν
+ Traefikμ λ컀, μΏ λ²λ€ν°μ€, κ·Έλ¦¬κ³ λ€λ₯Έ λꡬμ ν΅ν©λμ΄ μμ΄ μ¬λ¬λΆμ 컨ν
μ΄λλ₯Ό ν¬ν¨νλ HTTPSλ₯Ό μ
μ
νκ³ μ€μ νλ κ²μ΄ λ§€μ° μ½μ΅λλ€.
+
+λμμ μΌλ‘, HTTPSλ ν΄λΌμ°λ μ 곡μμ μν΄ μλΉμ€μ μΌνμΌλ‘ λ€λ£¨μ΄μ§ μλ μμ΅λλ€ (μ΄λλ μ΄ν리μΌμ΄μ
μ μ¬μ ν 컨ν
μ΄λμμ μ€νλ κ²μ
λλ€).
+
+## ꡬλκ³Ό μ¬μμ
+
+μ¬λ¬λΆμ 컨ν
μ΄λλ₯Ό **μμνκ³ μ€ννλ** λ°μ μΌλ°μ μΌλ‘ μ¬μ©λλ λꡬλ λ°λ‘ μμ΅λλ€.
+
+μ΄λ **λ컀** μμ²΄μΌ μλ μκ³ , **λ컀 μ»΄ν¬μ¦**, **μΏ λ²λ€ν°μ€**, **ν΄λΌμ°λ μλΉμ€** λ±μ΄ λ μ μμ΅λλ€.
+
+λλΆλΆ (λλ μ 체) κ²½μ°μ, 컨ν
μ΄λλ₯Ό ꡬλνκ±°λ κ³ μ₯μμ μ¬μμνλλ‘ νλ κ°λ¨ν μ΅μ
μ΄ μμ΅λλ€. μλ₯Ό λ€μ΄, λ컀μμλ, 컀맨λ λΌμΈ μ΅μ
`--restart` μ
λλ€.
+
+컨ν
μ΄λλ₯Ό μ¬μ©νμ§ μκ³ μλ, μ΄ν리μΌμ΄μ
μ ꡬλνκ³ μ¬μμνλ κ²μ΄ λ§€μ° λ²κ±°λ‘κ³ μ΄λ €μΈ μ μμ΅λλ€. νμ§λ§ **컨ν
μ΄λλ₯Ό μ¬μ©νλ€λ©΄** λλΆλΆμ κ²½μ°μ μ΄λ° κΈ°λ₯μ κΈ°λ³Έμ μΌλ‘ ν¬ν¨λμ΄ μμ΅λλ€. β¨
+
+## 볡μ - νλ‘μΈμ€ κ°μ
+
+λ§μ½ μ¬λ¬λΆμ΄ **μΏ λ²λ€ν°μ€**μ λ¨Έμ <abbr title="A group of machines that are configured to be connected and work together in some way.">ν΄λ¬μ€ν°</abbr>, λ컀 μ€μ λͺ¨λ, λ
Έλ§λ, λλ λ€λ₯Έ μ¬λ¬ λ¨Έμ μμ λΆμ° 컨ν
μ΄λλ₯Ό κ΄λ¦¬νλ 볡μ‘ν μμ€ν
μ λ€λ£¨κ³ μλ€λ©΄, μ¬λ¬λΆμ κ° μ»¨ν
μ΄λμμ (μ컀μ ν¨κ» μ¬μ©νλ Gunicorn κ°μ) **νλ‘μΈμ€ λ§€λμ ** λμ **ν΄λ¬μ€ν° λ 벨**μμ **볡μ λ₯Ό λ€λ£¨**κ³ μΆμ κ²μ
λλ€.
+
+μΏ λ²λ€ν°μ€μ κ°μ λΆμ° 컨ν
μ΄λ κ΄λ¦¬ μμ€ν
μ€ μΌλΆλ μΌλ°μ μΌλ‘ λ€μ΄μ€λ μμ²μ λν **λ‘λ λ°Έλ°μ±**μ μ§μνλ©΄μ **컨ν
μ΄λ 볡μ **λ₯Ό λ€λ£¨λ ν΅ν©λ λ°©λ²μ κ°μ§κ³ μμ΅λλ€. λͺ¨λ **ν΄λ¬μ€ν° λ 벨**μμ λ§μ΄μ£ .
+
+μ΄λ° κ²½μ°μ, μ¬λ¬λΆμ [μμμ λ¬μ¬λ κ²](#dockerfile)μ²λΌ **μ²μλΆν° λ컀 μ΄λ―Έμ§λ₯Ό** λΉλν΄μ, μμ‘΄μ±μ μ€μΉνκ³ , Uvicorn μ컀λ₯Ό κ΄λ¦¬νλ Gunicorn λμ **λ¨μΌ Uvicorn νλ‘μΈμ€**λ₯Ό μ€ννκ³ μΆμ κ²μ
λλ€.
+
+### λ‘λ λ°Έλ°μ
+
+컨ν
μ΄λλ‘ μμ
ν λ, μ¬λ¬λΆμ μΌλ°μ μΌλ‘ **λ©μΈ ν¬νΈμ μν©μ κ°μ§νλ** μμλ₯Ό κ°μ§κ³ μμ κ²μ
λλ€. μ΄λ **HTTPS**λ₯Ό λ€λ£¨λ **TLS μ’
λ£ νλ‘μ**μ κ°μ λ€λ₯Έ 컨ν
μ΄λμΌ μλ μκ³ , μ μ¬ν λ€λ₯Έ λκ΅¬μΌ μλ μμ΅λλ€.
+
+μ΄ μμκ° μμ²λ€μ **λ‘λ**λ₯Ό μ½μ΄λ€μ΄κ³ κ° μ컀μκ² (λ°λΌκ±΄λ) **κ· νμ μΌλ‘** λΆλ°°νλ€λ©΄, μ΄ μμλ μΌλ°μ μΌλ‘ **λ‘λ λ°Έλ°μ**λΌκ³ λΆλ¦½λλ€.
+
+!!! ν
+ HTTPSλ₯Ό μν΄ μ¬μ©λ **TLS μ’
λ£ νλ‘μ** μμ λν **λ‘λ λ°Έλ°μ**κ° λ μ μμ΅λλ€.
+
+λν 컨ν
μ΄λλ‘ μμ
ν λ, 컨ν
μ΄λλ₯Ό μμνκ³ κ΄λ¦¬νκΈ° μν΄ μ¬μ©ν κ²κ³Ό λμΌν μμ€ν
μ μ΄λ―Έ ν΄λΉ **λ‘λ λ°Έλ°μ**λ‘ λΆν° μ¬λ¬λΆμ μ±μ ν΄λΉνλ 컨ν
μ΄λλ‘ **λ€νΈμν¬ ν΅μ **(μλ₯Ό λ€μ΄, HTTP μμ²)μ μ μ‘νλ λ΄λΆμ μΈ λꡬλ₯Ό κ°μ§κ³ μμ κ²μ
λλ€ (μ¬κΈ°μλ λ‘λ λ°Έλ°μλ **TLS μ’
λ£ νλ‘μ**μΌ μ μμ΅λλ€).
+
+### νλμ λ‘λ λ°Έλ°μ - λ€μ€ μ컀 컨ν
μ΄λ
+
+**μΏ λ²λ€ν°μ€**λ λλ λ€λ₯Έ λΆμ° 컨ν
μ΄λ κ΄λ¦¬ μμ€ν
μΌλ‘ μμ
ν λ, μμ€ν
λ΄λΆμ λ€νΈμνΉ λ©μ»€λμ¦μ μ΄μ©ν¨μΌλ‘μ¨ λ©μΈ **ν¬νΈ**λ₯Ό κ°μ§νκ³ μλ λ¨μΌ **λ‘λ λ°Έλ°μ**λ μ¬λ¬λΆμ μ±μμ μ€νλκ³ μλ **μ¬λ¬κ°μ 컨ν
μ΄λ**μ ν΅μ (μμ²λ€)μ μ μ‘ν μ μκ² λ©λλ€.
+
+μ¬λ¬λΆμ μ±μμ μ€νλκ³ μλ κ°κ°μ 컨ν
μ΄λλ μΌλ°μ μΌλ‘ **νλμ νλ‘μΈμ€**λ§ κ°μ§ κ²μ
λλ€ (μλ₯Ό λ€μ΄, FastAPI μ΄ν리μΌμ΄μ
μμ μ€νλλ νλμ Uvicorn νλ‘μΈμ€μ²λΌ). μ΄ μ»¨ν
μ΄λλ€μ λͺ¨λ κ°μ κ²μ μ€ννλ μ μμ **λμΌν 컨ν
μ΄λ**μ΄μ§λ§, νλ‘μΈμ€, λ©λͺ¨λ¦¬ λ±μ 곡μ νμ§ μμ΅λλ€. μ΄ λ°©μμΌλ‘ μ¬λ¬λΆμ CPUμ **μλ‘ λ€λ₯Έ μ½μ΄λ€** λλ **μλ‘ λ€λ₯Έ λ¨Έμ λ€**μ **λ³λ ¬ν**νλ μ΄μ μ μ»μ μ μμ΅λλ€.
+
+λν **λ‘λ λ°Έλ°μ**κ° μλ λΆμ° 컨ν
μ΄λ μμ€ν
μ μ¬λ¬λΆμ μ±μ μλ 컨ν
μ΄λ κ°κ°μ **μ°¨λ‘λλ‘ μμ²μ λΆμ°**μν¬ κ² μ
λλ€. λ°λΌμ κ° μμ²μ μ¬λ¬λΆμ μ±μμ μ€νλλ μ¬λ¬κ°μ **볡μ λ 컨ν
μ΄λλ€** μ€ νλμ μν΄ λ€λ£¨μ΄μ§ κ² μ
λλ€.
+
+κ·Έλ¦¬κ³ μΌλ°μ μΌλ‘ **λ‘λ λ°Έλ°μ**λ μ¬λ¬λΆμ ν΄λ¬μ€ν°μ μλ *λ€λ₯Έ* μ±μΌλ‘ κ°λ μμ²λ€λ λ€λ£° μ μμΌλ©° (μλ₯Ό λ€μ΄, λ€λ₯Έ λλ©μΈμΌλ‘ κ°κ±°λ λ€λ₯Έ URL κ²½λ‘ μ λμ¬λ₯Ό κ°μ§λ κ²½μ°), μ΄ ν΅μ λ€μ ν΄λ¬μ€ν°μ μλ *λ°λ‘ κ·Έ λ€λ₯Έ* μ΄ν리μΌμ΄μ
μΌλ‘ μ λλ‘ μ μ‘ν μ μμ΅λλ€.
+
+### λ¨μΌ νλ‘μΈμ€λ₯Ό κ°μ§λ 컨ν
μ΄λ
+
+μ΄ μλ리μ€μ κ²½μ°, μ¬λ¬λΆμ μ΄λ―Έ ν΄λ¬μ€ν° λ 벨μμ 볡μ λ₯Ό λ€λ£¨κ³ μμ κ²μ΄λ―λ‘ **컨ν
μ΄λ λΉ λ¨μΌ (Uvicorn) νλ‘μΈμ€**λ₯Ό κ°μ§κ³ μ ν κ²μ
λλ€.
+
+λ°λΌμ, μ¬λ¬λΆμ Gunicorn μ΄λ Uvicorn μ컀, λλ Uvicorn μ컀λ₯Ό μ¬μ©νλ Uvicorn λ§€λμ μ κ°μ νλ‘μΈμ€ λ§€λμ λ₯Ό κ°μ§κ³ μΆμ΄νμ§ **μμ** κ²μ
λλ€. μ¬λ¬λΆμ 컨ν
μ΄λ λΉ **λ¨μΌ Uvicorn νλ‘μΈμ€**λ₯Ό κ°μ§κ³ μΆμ΄ν κ²μ
λλ€ (κ·Έλ¬λ μλ§λ λ€μ€ 컨ν
μ΄λλ₯Ό κ°μ§ κ²μ
λλ€).
+
+μ΄λ―Έ μ¬λ¬λΆμ΄ ν΄λ¬μ€ν° μμ€ν
μ κ΄λ¦¬νκ³ μμΌλ―λ‘, (Uvicorn μ컀λ₯Ό κ΄λ¦¬νλ Gunicorn μ΄λ Uvicorn μ²λΌ) 컨ν
μ΄λ λ΄μ λ€λ₯Έ νλ‘μΈμ€ λ§€λμ λ₯Ό κ°μ§λ κ²μ **λΆνμν 볡μ‘μ±**λ§ λνκ² λ κ²μ
λλ€.
+
+### λ€μ€ νλ‘μΈμ€λ₯Ό κ°μ§λ 컨ν
μ΄λμ νΉμν κ²½μ°λ€
+
+λΉμ°ν λ§μ΄μ§λ§, μ¬λ¬λΆμ΄ λ΄λΆμ μΌλ‘ **Uvicorn μ컀 νλ‘μΈμ€λ€**λ₯Ό μμνλ **Gunicorn νλ‘μΈμ€ λ§€λμ **λ₯Ό κ°μ§λ λ¨μΌ 컨ν
μ΄λλ₯Ό μνλ **νΉμν κ²½μ°**λ μμ κ²μ
λλ€.
+
+κ·Έλ° κ²½μ°μ, μ¬λ¬λΆλ€μ **Gunicorn**μ νλ‘μΈμ€ λ§€λμ λ‘ ν¬ν¨νλ **곡μ λ컀 μ΄λ―Έμ§**λ₯Ό μ¬μ©ν μ μμ΅λλ€. μ΄ νλ‘μΈμ€ λ§€λμ λ λ€μ€ **Uvicorn μ컀 νλ‘μΈμ€λ€**μ μ€ννλ©°, λν΄νΈ μΈν
μΌλ‘ νμ¬ CPU μ½μ΄μ κΈ°λ°νμ¬ μλμΌλ‘ μ컀 κ°μλ₯Ό μ‘°μ ν©λλ€. μ΄ μ¬νμ λν΄μλ μλμ [Gunicornκ³Ό ν¨κ»νλ 곡μ λ컀 μ΄λ―Έμ§ - Uvicorn](#official-docker-image-with-gunicorn-uvicorn)μμ λ λ€λ£¨κ² μ΅λλ€.
+
+μ΄λ° κ²½μ°μ ν΄λΉνλ λͺκ°μ§ μμκ° μμ΅λλ€:
+
+#### λ¨μν μ±
+
+λ§μ½ μ¬λ¬λΆμ μ΄ν리μΌμ΄μ
μ΄ **μΆ©λΆν λ¨μ**ν΄μ (μ μ΄λ μμ§μ) νλ‘μΈμ€ κ°μλ₯Ό νμΈ-ν ν νμκ° μκ±°λ ν΄λ¬μ€ν°κ° μλ **λ¨μΌ μλ²**μμ μ€ννκ³ μλ€λ©΄, μ¬λ¬λΆμ 컨ν
μ΄λ λ΄μ νλ‘μΈμ€ λ§€λμ λ₯Ό μ¬μ©νκ±°λ (곡μ λ컀 μ΄λ―Έμ§μμ) μλμΌλ‘ μ€μ λλ λν΄νΈ κ°μ μ¬μ©ν μ μμ΅λλ€.
+
+#### λ컀 ꡬμ±
+
+μ¬λ¬λΆμ **λ컀 μ»΄ν¬μ¦**λ‘ (ν΄λ¬μ€ν°κ° μλ) **λ¨μΌ μλ²λ‘** λ°°ν¬ν μ μμΌλ©°, μ΄ κ²½μ°μ 곡μ λ λ€νΈμν¬μ **λ‘λ λ°Έλ°μ±**μ ν¬ν¨νλ (λ컀 μ»΄ν¬μ¦λ‘) 컨ν
μ΄λμ 볡μ λ₯Ό κ΄λ¦¬νλ λ¨μν λ°©λ²μ΄ μμ μλ μμ΅λλ€.
+
+κ·Έλ λ€λ©΄ μ¬λ¬λΆμ **νλ‘μΈμ€ λ§€λμ **μ ν¨κ» λ΄λΆμ **λͺκ°μ μ컀 νλ‘μΈμ€λ€**μ μμνλ **λ¨μΌ 컨ν
μ΄λ**λ₯Ό νμλ‘ ν μ μμ΅λλ€.
+
+#### Prometheusμ λ€λ₯Έ μ΄μ λ€
+
+μ¬λ¬λΆμ **λ¨μΌ νλ‘μΈμ€**λ₯Ό κ°μ§λ **λ€μ€ 컨ν
μ΄λ** λμ **λ€μ€ νλ‘μΈμ€**λ₯Ό κ°μ§λ **λ¨μΌ 컨ν
μ΄λ**λ₯Ό μ±ννλ **λ€λ₯Έ μ΄μ **κ° μμ μ μμ΅λλ€.
+
+μλ₯Ό λ€μ΄ (μ¬λ¬λΆμ μ₯μΉ μ€μ μ λ°λΌ) Prometheus μ΅μ€ν¬ν°μ κ°μ΄ κ°μ 컨ν
μ΄λμ λ€μ΄μ€λ **κ° μμ²μ λν΄** μ κ·ΌκΆνμ κ°μ§λ λꡬλ₯Ό μ¬μ©ν μ μμ΅λλ€.
+
+μ΄ κ²½μ°μ μ¬λ¬λΆμ΄ **μ¬λ¬κ°μ 컨ν
μ΄λλ€**μ κ°μ§κ³ μλ€λ©΄, Prometheusκ° **λ©νΈλ¦μ μ½μ΄ λ€μΌ λ**, λν΄νΈλ‘ **λ§€λ² νλμ 컨ν
μ΄λ**(νΉμ 리νμ€νΈλ₯Ό κ΄λ¦¬νλ λ°λ‘ κ·Έ 컨ν
μ΄λ)λ‘ λΆν° μ½μ΄λ€μΌ κ²μ
λλ€. μ΄λ λͺ¨λ 볡μ λ 컨ν
μ΄λμ λν΄ **μΆμ λ λ©νΈλ¦λ€**μ μ½μ΄λ€μ΄λ κ²κ³Ό λλΉλ©λλ€.
+
+κ·Έλ λ€λ©΄ μ΄ κ²½μ°μλ **λ€μ€ νλ‘μΈμ€**λ₯Ό κ°μ§λ **νλμ 컨ν
μ΄λ**λ₯Ό λμ΄μ κ°μ 컨ν
μ΄λμμ λͺ¨λ λ΄λΆ νλ‘μΈμ€μ λν Prometheus λ©νΈλ¦μ μμ§νλ λ‘컬 λꡬ(μλ₯Ό λ€μ΄ Prometheus μ΅μ€ν¬ν° κ°μ)λ₯Ό λμ΄μ μ΄ λ©κ·Έλ¦λ€μ νλμ 컨ν
μ΄λμ λ΄μμ 곡μ νλ λ°©λ²μ΄ λ λ¨μν κ²μ
λλ€.
+
+---
+
+μμ μ, μ΄ μ€μ **μ΄λκ²λ** μ¬λ¬λΆλ€μ΄ λ°λμ λ°λΌμΌνλ **νμ λ μ¬μ€**μ΄ μλλΌλ κ²μ
λλ€. μ¬λ¬λΆμ μ΄ μμ΄λμ΄λ€μ **μ¬λ¬λΆμ κ³ μ ν μ΄μ© μ¬λ‘λ₯Ό νκ°**νλλ° μ¬μ©νκ³ , μ¬λ¬λΆμ μμ€ν
μ κ°μ₯ μ ν©ν μ κ·Όλ²μ΄ μ΄λ€ κ²μΈμ§ κ²°μ νλ©°, λ€μμ κ°λ
λ€μ κ΄λ¦¬νλ λ°©λ²μ νμΈν μ μμ΅λλ€:
+
+* 보μ - HTTPS
+* ꡬλνκΈ°
+* μ¬μμ
+* 볡μ (μ€ν μ€μΈ νλ‘μΈμ€ κ°μ)
+* λ©λͺ¨λ¦¬
+* μμνκΈ° μ λ¨κ³λ€
+
+## λ©λͺ¨λ¦¬
+
+λ§μ½ μ¬λ¬λΆμ΄ **컨ν
μ΄λ λΉ λ¨μΌ νλ‘μΈμ€**λ₯Ό μ€ννλ€λ©΄, μ¬λ¬λΆμ κ° μ»¨ν
μ΄λ(볡μ λ κ²½μ°μλ μ¬λ¬κ°μ 컨ν
μ΄λλ€)μ λν΄ μ μ μλκ³ , μμ μ μ΄λ©°, μ νλ μ©λμ λ©λͺ¨λ¦¬ μλΉλμ κ°μ§κ³ μμ κ²μ
λλ€.
+
+κ·Έλ¬λ©΄ μ¬λ¬λΆμ 컨ν
μ΄λ κ΄λ¦¬ μμ€ν
(μλ₯Ό λ€μ΄ **μΏ λ²λ€ν°μ€**) μ€μ μμ μμ μ μλ κ²κ³Ό κ°μ λ©λͺ¨λ¦¬ μ νκ³Ό μꡬμ¬νμ μ€μ ν μ μμ΅λλ€. μ΄λ° λ°©λ²μΌλ‘ **κ°μ© λ¨Έμ **μ΄ νμλ‘νλ λ©λͺ¨λ¦¬μ ν΄λ¬μ€ν°μ μλ κ°μ© λ¨Έμ λ€μ μΌλμ λκ³ **컨ν
μ΄λλ₯Ό 볡μ **ν μ μμ΅λλ€.
+
+λ§μ½ μ¬λ¬λΆμ μ΄ν리μΌμ΄μ
μ΄ **λ¨μ**νλ€λ©΄, μ΄κ²μ **λ¬Έμ κ° λμ§ μμ** κ²μ΄κ³ , κ³ μ λ λ©λͺ¨λ¦¬ μ νμ ꡬ체νν νμλ μμ κ²μ
λλ€. νμ§λ§ μ¬λ¬λΆμ μ΄ν리μΌμ΄μ
μ΄ (μλ₯Ό λ€μ΄ **λ¨Έμ λ¬λ** λͺ¨λΈκ°μ΄) **λ§μ λ©λͺ¨λ¦¬λ₯Ό μμνλ€λ©΄**, μ΄ν리μΌμ΄μ
μ΄ μΌλ§λ λ§μ μμ λ©λͺ¨λ¦¬λ₯Ό μ¬μ©νλμ§ νμΈνκ³ **κ° λ¨Έμ μμ** μ¬μ©νλ **컨ν
μ΄λμ μ**λ₯Ό μ‘°μ ν νμκ° μμ΅λλ€ (κ·Έλ¦¬κ³ νμμ λ°λΌ μ¬λ¬λΆμ ν΄λ¬μ€ν°μ λ¨Έμ μ μΆκ°ν μ μμ΅λλ€).
+
+λ§μ½ μ¬λ¬λΆμ΄ **컨ν
μ΄λ λΉ μ¬λ¬κ°μ νλ‘μΈμ€**λ₯Ό μ€ννλ€λ©΄ (μλ₯Ό λ€μ΄ 곡μ λ컀 μ΄λ―Έμ§ μ²λΌ), μ¬λ¬λΆμ μμλ νλ‘μΈμ€ κ°μκ° κ°μ©ν κ² λ³΄λ€ **λ λ§μ λ©λͺ¨λ¦¬λ₯Ό μλΉ**νμ§ μλμ§ νμΈν΄μΌ ν©λλ€.
+
+## μμνκΈ° μ λ¨κ³λ€κ³Ό 컨ν
μ΄λ
+
+λ§μ½ μ¬λ¬λΆμ΄ 컨ν
μ΄λ(μλ₯Ό λ€μ΄ λ컀, μΏ λ²λ€ν°μ€)λ₯Ό μ¬μ©νλ€λ©΄, μ¬λ¬λΆμ΄ μ κ·Όν μ μλ μ£Όμ λ°©λ²μ ν¬κ² λκ°μ§κ° μμ΅λλ€.
+
+### λ€μ€ 컨ν
μ΄λ
+
+λ§μ½ μ¬λ¬λΆμ΄ **μ¬λ¬κ°μ 컨ν
μ΄λ**λ₯Ό κ°μ§κ³ μλ€λ©΄, μλ§λ κ°κ°μ 컨ν
μ΄λλ **νλμ νλ‘μΈμ€**λ₯Ό κ°μ§κ³ μμ κ²μ
λλ€(μλ₯Ό λ€μ΄, **μΏ λ²λ€ν°μ€** ν΄λ¬μ€ν°μμ). κ·Έλ¬λ©΄ μ¬λ¬λΆμ 볡μ λ μ컀 컨ν
μ΄λλ₯Ό μ€ννκΈ° **μ΄μ μ**, νλμ 컨ν
μ΄λμ μλ **μ΄μ μ λ¨κ³λ€μ** μννλ λ¨μΌ νλ‘μΈμ€λ₯Ό κ°μ§λ **λ³λμ 컨ν
μ΄λλ€**μ κ°μ§κ³ μΆμ κ²μ
λλ€.
+
+!!! μ 보
+ λ§μ½ μ¬λ¬λΆμ΄ μΏ λ²λ€ν°μ€λ₯Ό μ¬μ©νκ³ μλ€λ©΄, μλ§λ μ΄λ <a href="https://kubernetes.io/docs/concepts/workloads/pods/init-containers/" class="external-link" target="_blank">Init Container</a>μΌ κ²μ
λλ€.
+
+λ§μ½ μ¬λ¬λΆμ μ΄μ© μ¬λ‘μμ μ΄μ λ¨κ³λ€μ **λ³λ ¬μ μΌλ‘ μ¬λ¬λ²** μννλλ°μ λ¬Έμ κ° μλ€λ©΄ (μλ₯Ό λ€μ΄ λ°μ΄ν°λ² μ΄μ€ μ΄μ μ μ€ννμ§ μκ³ λ°μ΄ν°λ² μ΄μ€κ° μ€λΉλμλμ§ νμΈλ§ νλ κ²½μ°), λ©μΈ νλ‘μΈμ€λ₯Ό μμνκΈ° μ μ μ΄ λ¨κ³λ€μ κ° μ»¨ν
μ΄λμ λ£μ μ μμ΅λλ€.
+
+### λ¨μΌ 컨ν
μ΄λ
+
+λ§μ½ μ¬λ¬λΆμ μ
μ
μ΄ **λ€μ€ νλ‘μΈμ€**(λλ νλμ νλ‘μΈμ€)λ₯Ό μμνλ **νλμ 컨ν
μ΄λ**λ₯Ό κ°μ§λ λ¨μν μ
μ
μ΄λΌλ©΄, μ¬μ λ¨κ³λ€μ μ±μ ν¬ν¨νλ νλ‘μΈμ€λ₯Ό μμνκΈ° μ§μ μ κ°μ 컨ν
μ΄λμμ μ€νν μ μμ΅λλ€. 곡μ λ컀 μ΄λ―Έμ§λ μ΄λ₯Ό λ΄λΆμ μΌλ‘ μ§μν©λλ€.
+
+## Gunicornκ³Ό ν¨κ»νλ 곡μ λ컀 μ΄λ―Έμ§ - Uvicorn
+
+μ μ±ν°μμ μμΈνκ² μ€λͺ
λ κ² μ²λΌ, Uvicorn μ컀μ κ°μ΄ μ€νλλ Gunicornμ ν¬ν¨νλ 곡μ λ컀 μ΄λ―Έμ§κ° μμ΅λλ€: [μλ² μ컀 - Uvicornκ³Ό ν¨κ»νλ Gunicorn](./server-workers.md){.internal-link target=_blank}.
+
+μ΄ μ΄λ―Έμ§λ μ£Όλ‘ μμμ μ€λͺ
λ μν©μμ μ μ©ν κ²μ
λλ€: [λ€μ€ νλ‘μΈμ€λ₯Ό κ°μ§λ 컨ν
μ΄λμ νΉμν κ²½μ°λ€](#containers-with-multiple-processes-and-special-cases).
+
+* <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
+
+!!! κ²½κ³
+ μ¬λ¬λΆμ΄ μ΄ λ² μ΄μ€ μ΄λ―Έμ§ λλ λ€λ₯Έ μ μ¬ν μ΄λ―Έμ§λ₯Ό νμλ‘ νμ§ **μμ** λμ κ°λ₯μ±μ΄ μμΌλ©°, [μμμ μ€λͺ
λ κ²μ²λΌ: FastAPIλ₯Ό μν λ컀 μ΄λ―Έμ§ λΉλνκΈ°](#build-a-docker-image-for-fastapi) μ²μλΆν° μ΄λ―Έμ§λ₯Ό λΉλνλ κ²μ΄ λ λμ μ μμ΅λλ€.
+
+μ΄ μ΄λ―Έμ§λ κ°λ₯ν CPU μ½μ΄μ κΈ°λ°ν **λͺκ°μ μ컀 νλ‘μΈμ€**λ₯Ό μ€μ νλ **μλ-νλ** λ©μ»€λμ¦μ ν¬ν¨νκ³ μμ΅λλ€.
+
+μ΄ μ΄λ―Έμ§λ **λ―Όκ°ν λν΄νΈ** κ°μ κ°μ§κ³ μμ§λ§, μ¬λ¬λΆλ€μ μ¬μ ν **νκ²½ λ³μ** λλ μ€μ νμΌμ ν΅ν΄ μ€μ κ°μ μμ νκ³ μ
λ°μ΄νΈ ν μ μμ΅λλ€.
+
+λν μ€ν¬λ¦½νΈλ₯Ό ν΅ν΄ <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker#pre_start_path" class="external-link" target="_blank">**μμνκΈ° μ μ¬μ λ¨κ³**</a>λ₯Ό μ€ννλ κ²μ μ§μν©λλ€.
+
+!!! ν
+ λͺ¨λ μ€μ κ³Ό μ΅μ
μ λ³΄λ €λ©΄, λ컀 μ΄λ―Έμ§ νμ΄μ§λ‘ μ΄λν©λλ€: <a href="https://github.com/tiangolo/uvicorn-gunicorn-fastapi-docker" class="external-link" target="_blank">tiangolo/uvicorn-gunicorn-fastapi</a>.
+
+### 곡μ λ컀 μ΄λ―Έμ§μ μλ νλ‘μΈμ€ κ°μ
+
+μ΄ μ΄λ―Έμ§μ μλ **νλ‘μΈμ€ κ°μ**λ κ°μ©ν CPU **μ½μ΄λ€**λ‘ λΆν° **μλμΌλ‘ κ³μ°**λ©λλ€.
+
+μ΄κ²μ΄ μλ―Ένλ λ°λ μ΄λ―Έμ§κ° CPUλ‘λΆν° **μ΅λνμ μ±λ₯**μ **μ₯μ΄μ§λΈλ€**λ κ²μ
λλ€.
+
+μ¬λ¬λΆμ μ΄ μ€μ κ°μ **νκ²½ λ³μ**λ κΈ°ν λ°©λ²λ€λ‘ μ‘°μ ν μ μμ΅λλ€.
+
+κ·Έλ¬λ νλ‘μΈμ€μ κ°μκ° μ»¨ν
μ΄λκ° μ€νλκ³ μλ CPUμ μμ‘΄νλ€λ κ²μ λν **μμλλ λ©λͺ¨λ¦¬μ ν¬κΈ°** λν μ΄μ μμ‘΄νλ€λ κ²μ μλ―Έν©λλ€.
+
+κ·Έλ κΈ° λλ¬Έμ, λ§μ½ μ¬λ¬λΆμ μ΄ν리μΌμ΄μ
μ΄ λ§μ λ©λͺ¨λ¦¬λ₯Ό μꡬνκ³ (μλ₯Ό λ€μ΄ λ¨Έμ λ¬λ λͺ¨λΈμ²λΌ), μ¬λ¬λΆμ μλ²κ° CPU μ½μ΄ μλ λ§μ§λ§ **μ μ λ©λͺ¨λ¦¬**λ₯Ό κ°μ§κ³ μλ€λ©΄, μ¬λ¬λΆμ 컨ν
μ΄λλ κ°μ©ν λ©λͺ¨λ¦¬λ³΄λ€ λ§μ λ©λͺ¨λ¦¬λ₯Ό μ¬μ©νλ €κ³ μλν μ μμΌλ©°, κ²°κ΅ νΌν¬λ¨Όμ€λ₯Ό ν¬κ² λ¨μ΄λ¨λ¦΄ μ μμ΅λλ€(μ¬μ§μ΄ κ³ μ₯μ΄ λ μλ μμ΅λλ€). π¨
+
+### `Dockerfile` μμ±νκΈ°
+
+μ΄ μ΄λ―Έμ§μ κΈ°λ°ν΄ `Dockerfile`μ μμ±νλ λ°©λ²μ λ€μκ³Ό κ°μ΅λλ€:
+
+```Dockerfile
+FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
+
+COPY ./requirements.txt /app/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
+
+COPY ./app /app
+```
+
+### λ ν° μ΄ν리μΌμ΄μ
+
+λ§μ½ μ¬λ¬λΆμ΄ [λ€μ€ νμΌμ κ°μ§λ λ ν° μ΄ν리μΌμ΄μ
](../tutorial/bigger-applications.md){.internal-link target=_blank}μ μμ±νλ μΉμ
μ λ°λλ€λ©΄, μ¬λ¬λΆμ `Dockerfile`μ λμ μ΄λ κ² μκ²Όμ κ²μ
λλ€:
+
+```Dockerfile hl_lines="7"
+FROM tiangolo/uvicorn-gunicorn-fastapi:python3.9
+
+COPY ./requirements.txt /app/requirements.txt
+
+RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
+
+COPY ./app /app/app
+```
+
+### μΈμ μ¬μ©ν κΉ
+
+μ¬λ¬λΆλ€μ΄ **μΏ λ²λ€ν°μ€**(λλ μ μ¬ν λ€λ₯Έ λꡬ) μ¬μ©νκ±°λ ν΄λ¬μ€ν° λ 벨μμ λ€μ€ 컨ν
μ΄λλ₯Ό μ΄μ©ν΄ μ΄λ―Έ **μ¬λ³Έ**μ μ€μ νκ³ μλ€λ©΄, 곡μ λ² μ΄μ€ μ΄λ―Έμ§(λλ μ μ¬ν λ€λ₯Έ μ΄λ―Έμ§)λ₯Ό μ¬μ©νμ§ **μλ** κ² μ’μ΅λλ€. κ·Έλ° κ²½μ°μ μ¬λ¬λΆμ λ€μμ μ€λͺ
λ κ² μ²λΌ **μ²μλΆν° μ΄λ―Έμ§λ₯Ό λΉλνλ κ²**μ΄ λ λ«μ΅λλ€: [FastAPIλ₯Ό μν λ컀 μ΄λ―Έμ§ λΉλνκΈ°](#build-a-docker-image-for-fastapi).
+
+μ΄ μ΄λ―Έμ§λ μμ [λ€μ€ νλ‘μΈμ€λ₯Ό κ°μ§λ 컨ν
μ΄λμ νΉμν κ²½μ°λ€](#containers-with-multiple-processes-and-special-cases)μμ μ€λͺ
λ νΉμν κ²½μ°μ λν΄μλ§ μ£Όλ‘ μ μ©ν κ²μ
λλ€. μλ₯Ό λ€μ΄, λ§μ½ μ¬λ¬λΆμ μ΄ν리μΌμ΄μ
μ΄ **μΆ©λΆν λ¨μ**ν΄μ CPUμ κΈ°λ°ν λν΄νΈ νλ‘μΈμ€ κ°μλ₯Ό μ€μ νλ κ²μ΄ μ μλνλ€λ©΄, ν΄λ¬μ€ν° λ 벨μμ μλμΌλ‘ μ¬λ³Έμ μ€μ ν νμκ° μμ κ²μ΄κ³ , μ¬λ¬λΆμ μ±μμ νλ μ΄μμ 컨ν
μ΄λλ₯Ό μ€ννμ§λ μμ κ²μ
λλ€. λλ λ§μ½μ μ¬λ¬λΆμ΄ **λ컀 μ»΄ν¬μ¦**λ‘ λ°°ν¬νκ±°λ, λ¨μΌ μλ²μμ μ€ννκ±°λ νλ κ²½μ°μλ λ§μ°¬κ°μ§μ
λλ€.
+
+## 컨ν
μ΄λ μ΄λ―Έμ§ λ°°ν¬νκΈ°
+
+컨ν
μ΄λ (λ컀) μ΄λ―Έμ§λ₯Ό μμ±ν λ€μ μ΄λ₯Ό λ°°ν¬νλ λ°©λ²μλ μ¬λ¬κ°μ§ λ°©λ²μ΄ μμ΅λλ€.
+
+μλ₯Ό λ€μ΄:
+
+* λ¨μΌ μλ²μμ **λ컀 μ»΄ν¬μ¦**λ‘ λ°°ν¬νκΈ°
+* **μΏ λ²λ€ν°μ€** ν΄λ¬μ€ν°λ‘ λ°°ν¬νκΈ°
+* λ컀 μ€μ λͺ¨λ ν΄λ¬μ€ν°λ‘ λ°°ν¬νκΈ°
+* λ
Έλ§λ κ°μ λ€λ₯Έ λκ΅¬λ‘ λ°°ν¬νκΈ°
+* μ¬λ¬λΆμ 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό λ°°ν¬ν΄μ£Όλ ν΄λΌμ°λ μλΉμ€λ‘ λ°°ν¬νκΈ°
+
+## Poetryμ λ컀 μ΄λ―Έμ§
+
+λ§μ½ μ¬λ¬λΆλ€μ΄ νλ‘μ νΈ μμ‘΄μ±μ κ΄λ¦¬νκΈ° μν΄ <a href="https://python-poetry.org/" class="external-link" target="_blank">Poetry</a>λ₯Ό μ¬μ©νλ€λ©΄, λ컀μ λ©ν°-μ€ν
μ΄μ§ λΉλ©μ μ¬μ©ν μ μμ΅λλ€:
+
+```{ .dockerfile .annotate }
+# (1)
+FROM python:3.9 as requirements-stage
+
+# (2)
+WORKDIR /tmp
+
+# (3)
+RUN pip install poetry
+
+# (4)
+COPY ./pyproject.toml ./poetry.lock* /tmp/
+
+# (5)
+RUN poetry export -f requirements.txt --output requirements.txt --without-hashes
+
+# (6)
+FROM python:3.9
+
+# (7)
+WORKDIR /code
+
+# (8)
+COPY --from=requirements-stage /tmp/requirements.txt /code/requirements.txt
+
+# (9)
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+# (10)
+COPY ./app /code/app
+
+# (11)
+CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]
+```
+
+1. 첫 μ€ν
μ΄μ§λ‘, `requirements-stage`λΌκ³ μ΄λ¦ λΆμμ΅λλ€.
+
+2. `/tmp`λ₯Ό νμ¬μ μνΉ λλ ν°λ¦¬λ‘ μ€μ ν©λλ€.
+
+ μ΄ μμΉμ μ°λ¦¬λ `requirements.txt` νμΌμ μμ±ν κ²μ
λλ€.
+
+3. μ΄ λ컀 μ€ν
μ΄μ§μμ Poetryλ₯Ό μ€μΉν©λλ€.
+
+4. νμΌ `pyproject.toml`μ `poetry.lock`λ₯Ό `/tmp` λλ ν°λ¦¬λ‘ 볡μ¬ν©λλ€.
+
+ `./poetry.lock*` (`*`λ‘ λλλ) νμΌμ μ¬μ©νκΈ° λλ¬Έμ, νμΌμ΄ μμ§ μ¬μ©κ°λ₯νμ§ μλλΌλ κ³ μ₯λμ§ μμ κ²μ
λλ€.
+
+5. `requirements.txt` νμΌμ μμ±ν©λλ€.
+
+6. μ΄κ²μ΄ λ§μ§λ§ μ€ν
μ΄μ§λ‘, μ¬κΈ°μ μμΉν λͺ¨λ κ²μ΄ λ§μ§λ§ 컨ν
μ΄λ μ΄λ―Έμ§μ ν¬ν¨λ κ²μ
λλ€.
+
+7. νμ¬μ μνΉ λλ ν°λ¦¬λ₯Ό `/code`λ‘ μ€μ ν©λλ€.
+
+8. νμΌ `requirements.txt`λ₯Ό `/code` λλ ν°λ¦¬λ‘ 볡μ¬ν©λλ€.
+
+ μ΄ νμΌμ μ€μ§ μ΄μ μ λ컀 μ€ν
μ΄μ§μλ§ μ‘΄μ¬νλ©°, λλ¬Έμ 볡μ¬νκΈ° μν΄μ `--from-requirements-stage` μ΅μ
μ΄ νμν©λλ€.
+
+9. μμ±λ `requirements.txt` νμΌμ ν¨ν€μ§ μμ‘΄μ±μ μ€μΉν©λλ€.
+
+10. `app` λλ ν°λ¦¬λ₯Ό `/code` λλ ν°λ¦¬λ‘ 볡μ¬ν©λλ€.
+
+11. `uvicorn` 컀맨λλ₯Ό μ€ννμ¬, `app.main`μμ λΆλ¬μ¨ `app` κ°μ²΄λ₯Ό μ¬μ©νλλ‘ ν©λλ€.
+
+!!! ν
+ λ²λΈ μ«μλ₯Ό ν΄λ¦ν΄ κ° μ€μ΄ νλ μΌμ μμλ³Ό μ μμ΅λλ€.
+
+**λ컀 μ€ν
μ΄μ§**λ `Dockefile`μ μΌλΆλ‘μ λμ€μ μ¬μ©νκΈ° μν νμΌλ€μ μμ±νκΈ° μν **μΌμμ μΈ μ»¨ν
μ΄λ μ΄λ―Έμ§**λ‘ μλν©λλ€.
+
+첫 μ€ν
μ΄μ§λ μ€μ§ **Poetryλ₯Ό μ€μΉ**νκ³ Poetryμ `pyproject.toml` νμΌλ‘λΆν° νλ‘μ νΈ μμ‘΄μ±μ μν **`requirements.txt`λ₯Ό μμ±**νκΈ° μν΄ μ¬μ©λ©λλ€.
+
+μ΄ `requirements.txt` νμΌμ **λ€μ μ€ν
μ΄μ§**μμ `pip`λ‘ μ¬μ©λ κ²μ
λλ€.
+
+λ§μ§λ§ 컨ν
μ΄λ μ΄λ―Έμ§μλ **μ€μ§ λ§μ§λ§ μ€ν
μ΄μ§λ§** 보쑴λ©λλ€. μ΄μ μ€ν
μ΄μ§(λ€)μ λ²λ €μ§λλ€.
+
+Poetryλ₯Ό μ¬μ©ν λ **λ컀 λ©ν°-μ€ν
μ΄μ§ λΉλ**λ₯Ό μ¬μ©νλ κ²μ΄ μ’μλ°, μ¬λ¬λΆλ€μ νλ‘μ νΈ μμ‘΄μ±μ μ€μΉνκΈ° μν΄ λ§μ§λ§ 컨ν
μ΄λ μ΄λ―Έμ§μ **μ€μ§** `requirements.txt` νμΌλ§ νμνμ§, Poetryμ κ·Έ μμ‘΄μ±μ μμ νμκ° μκΈ° λλ¬Έμ
λλ€.
+
+μ΄ λ€μ (λν λ§μ§λ§) μ€ν
μ΄μ§μμ μ¬λ¬λΆλ€μ μ΄μ μ μ€λͺ
λ κ²κ³Ό λΉμ·ν λ°©μμΌλ‘ λ°©μμΌλ‘ μ΄λ―Έμ§λ₯Ό λΉλν μ μμ΅λλ€.
+
+### TLS μ’
λ£ νλ‘μμ λ°°ν - Poetry
+
+μ΄μ μ μΈκΈν κ²κ³Ό κ°μ΄, λ§μ½ μ¬λ¬λΆμ΄ 컨ν
μ΄λλ₯Ό Nginx λλ Traefikκ³Ό κ°μ TLS μ’
λ£ νλ‘μ (λ‘λ λ°Έλ°μ) λ€μμ μ€ννκ³ μλ€λ©΄, 컀맨λμ `--proxy-headers` μ΅μ
μ μΆκ°ν©λλ€:
+
+```Dockerfile
+CMD ["uvicorn", "app.main:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
+```
+
+## μμ½
+
+컨ν
μ΄λ μμ€ν
(μλ₯Ό λ€μ΄ **λ컀**λ **μΏ λ²λ€ν°μ€**)μ μ¬μ©νμ¬ λͺ¨λ **λ°°ν¬ κ°λ
**μ λ€λ£¨λ κ²μ κ½€ κ°λ¨ν©λλ€:
+
+* HTTPS
+* ꡬλνκΈ°
+* μ¬μμ
+* 볡μ (μ€ν μ€μΈ νλ‘μΈμ€ κ°μ)
+* λ©λͺ¨λ¦¬
+* μμνκΈ° μ λ¨κ³λ€
+
+λλΆλΆμ κ²½μ°μμ μ¬λ¬λΆμ μ΄λ€ λ² μ΄μ€ μ΄λ―Έμ§λ μ¬μ©νμ§ μκ³ κ³΅μ νμ΄μ¬ λ컀 μ΄λ―Έμ§μ κΈ°λ°ν΄ **μ²μλΆν° 컨ν
μ΄λ μ΄λ―Έμ§λ₯Ό λΉλ**ν κ²μ
λλ€.
+
+`Dockerfile`μ μλ μ§μ μ¬νμ **μμλλ‘** λ€λ£¨κ³ **λ컀 μΊμ**λ₯Ό μ¬μ©νλ κ²μΌλ‘ μ¬λ¬λΆμ **λΉλ μκ°μ μ΅μν**ν μ μμΌλ©°, μ΄λ‘μ¨ μμ°μ±μ μ΅λνν μ μμ΅λλ€ (κ·Έλ¦¬κ³ μ§λ£¨ν¨μ νΌν μ μμ£ ) π
+
+νΉλ³ν κ²½μ°μλ, FastAPIλ₯Ό μν 곡μ λ컀 μ΄λ―Έμ§λ₯Ό μ¬μ©ν μλ μμ΅λλ€. π€