使用容器進行 Python 開發
先決條件
完成 將 Python 應用程式容器化。
概觀
在本節中,您將學習如何為您的容器化應用程式設定開發環境。 這包含
- 新增本地資料庫並保存資料
- 設定 Compose 以在您編輯和儲存程式碼時自動更新正在執行的 Compose 服務
取得範例應用程式
您需要複製一個新的儲存庫以取得包含連接到資料庫邏輯的範例應用程式。
切換到您要複製儲存庫的目錄並執行以下命令。
$ git clone https://github.com/estebanx64/python-docker-dev-example
在複製的儲存庫目錄中,手動建立 Docker 資產或執行
docker init
以建立必要的 Docker 資產。在複製的儲存庫目錄中,執行
docker init
。 參考以下範例來回答docker init
的提示。$ docker init Welcome to the Docker Init CLI! This utility will walk you through creating the following files with sensible defaults for your project: - .dockerignore - Dockerfile - compose.yaml - README.Docker.md Let's get started! ? What application platform does your project use? Python ? What version of Python do you want to use? 3.11.4 ? What port do you want your app to listen on? 8001 ? What is the command to run your app? python3 -m uvicorn app:app --host=0.0.0.0 --port=8001
建立一個名為
.gitignore
的檔案,並包含以下內容。.gitignore# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/
如果您沒有安裝 Docker Desktop 或偏好手動建立資產,您可以在您的專案目錄中建立以下檔案。
建立一個名為
Dockerfile
的檔案,並包含以下內容。Dockerfile# syntax=docker/dockerfile:1 # Comments are provided throughout this file to help you get started. # If you need more help, visit the Dockerfile reference guide at # https://docker-docs.dev.org.tw/go/dockerfile-reference/ # Want to help us make this template better? Share your feedback here: https:// forms.gle/ybq9Krt8jtBL3iCk7 ARG PYTHON_VERSION=3.11.4 FROM python:${PYTHON_VERSION}-slim as base # Prevents Python from writing pyc files. ENV PYTHONDONTWRITEBYTECODE=1 # Keeps Python from buffering stdout and stderr to avoid situations where # the application crashes without emitting any logs due to buffering. ENV PYTHONUNBUFFERED=1 WORKDIR /app # Create a non-privileged user that the app will run under. # See https://docker-docs.dev.org.tw/go/dockerfile-user-best-practices/ ARG UID=10001 RUN adduser \ --disabled-password \ --gecos "" \ --home "/nonexistent" \ --shell "/sbin/nologin" \ --no-create-home \ --uid "${UID}" \ appuser # Download dependencies as a separate step to take advantage of Docker's caching. # Leverage a cache mount to /root/.cache/pip to speed up subsequent builds. # Leverage a bind mount to requirements.txt to avoid having to copy them into # into this layer. RUN --mount=type=cache,target=/root/.cache/pip \ --mount=type=bind,source=requirements.txt,target=requirements.txt \ python -m pip install -r requirements.txt # Switch to the non-privileged user to run the application. USER appuser # Copy the source code into the container. COPY . . # Expose the port that the application listens on. EXPOSE 8001 # Run the application. CMD python3 -m uvicorn app:app --host=0.0.0.0 --port=8001
建立一個名為
compose.yaml
的檔案,並包含以下內容。compose.yaml# Comments are provided throughout this file to help you get started. # If you need more help, visit the Docker Compose reference guide at # https://docker-docs.dev.org.tw/go/compose-spec-reference/ # Here the instructions define your application as a service called "server". # This service is built from the Dockerfile in the current directory. # You can add other services your application may depend on here, such as a # database or a cache. For examples, see the Awesome Compose repository: # https://github.com/docker/awesome-compose services: server: build: context: . ports: - 8001:8001 # The commented out section below is an example of how to define a PostgreSQL # database that your application can use. `depends_on` tells Docker Compose to # start the database before your application. The `db-data` volume persists the # database data between container restarts. The `db-password` secret is used # to set the database password. You must create `db/password.txt` and add # a password of your choosing to it before running `docker compose up`. # depends_on: # db: # condition: service_healthy # db: # image: postgres # restart: always # user: postgres # secrets: # - db-password # volumes: # - db-data:/var/lib/postgresql/data # environment: # - POSTGRES_DB=example # - POSTGRES_PASSWORD_FILE=/run/secrets/db-password # expose: # - 5432 # healthcheck: # test: [ "CMD", "pg_isready" ] # interval: 10s # timeout: 5s # retries: 5 # volumes: # db-data: # secrets: # db-password: # file: db/password.txt
建立一個名為
.dockerignore
的檔案,並包含以下內容。.dockerignore# Include any files or directories that you don't want to be copied to your # container here (e.g., local build artifacts, temporary files, etc.). # # For more help, visit the .dockerignore file reference guide at # https://docker-docs.dev.org.tw/go/build-context-dockerignore/ **/.DS_Store **/__pycache__ **/.venv **/.classpath **/.dockerignore **/.env **/.git **/.gitignore **/.project **/.settings **/.toolstarget **/.vs **/.vscode **/*.*proj.user **/*.dbmdl **/*.jfm **/bin **/charts **/docker-compose* **/compose.y*ml **/Dockerfile* **/node_modules **/npm-debug.log **/obj **/secrets.dev.yaml **/values.dev.yaml LICENSE README.md
建立一個名為
.gitignore
的檔案,並包含以下內容。.gitignore# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ cover/ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/
新增本地資料庫並保存資料
您可以使用容器來設定本地服務,例如資料庫。 在本節中,您將更新 compose.yaml
檔案以定義資料庫服務和保存資料的磁碟區。
在複製的儲存庫目錄中,使用 IDE 或文字編輯器開啟 compose.yaml
檔案。 docker init
處理了大部分指令的建立,但您需要根據您的應用程式進行更新。
在 compose.yaml
檔案中,您需要取消註釋所有資料庫指令。 此外,您需要將資料庫密碼檔案作為環境變數新增到伺服器服務,並指定要使用的密鑰檔案。
以下是更新後的 compose.yaml
檔案。
services:
server:
build:
context: .
ports:
- 8001:8001
environment:
- POSTGRES_SERVER=db
- POSTGRES_USER=postgres
- POSTGRES_DB=example
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
depends_on:
db:
condition: service_healthy
secrets:
- db-password
db:
image: postgres
restart: always
user: postgres
secrets:
- db-password
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=example
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
expose:
- 5432
healthcheck:
test: ["CMD", "pg_isready"]
interval: 10s
timeout: 5s
retries: 5
volumes:
db-data:
secrets:
db-password:
file: db/password.txt
注意事項
要瞭解更多 Compose 檔案中的指令,請參閱 Compose 檔案參考。
在您使用 Compose 執行應用程式之前,請注意此 Compose 檔案指定了一個 password.txt
檔案來存放資料庫的密碼。 您必須建立此檔案,因為它不包含在原始碼儲存庫中。
在複製的儲存庫目錄中,建立一個名為 db
的新目錄,並在該目錄內建立一個名為 password.txt
的檔案,其中包含資料庫的密碼。 使用您慣用的 IDE 或文字編輯器,將以下內容新增到 password.txt
檔案中。
mysecretpassword
儲存並關閉 password.txt
檔案。
您現在應該在 python-docker-dev-example
目錄中有以下內容。
├── python-docker-dev-example/
│ ├── db/
│ │ └── password.txt
│ ├── app.py
│ ├── config.py
│ ├── requirements.txt
│ ├── .dockerignore
│ ├── .gitignore
│ ├── compose.yaml
│ ├── Dockerfile
│ ├── README.Docker.md
│ └── README.md
現在,執行以下 docker compose up
命令來啟動您的應用程式。
$ docker compose up --build
現在測試您的 API 端點。 開啟一個新的終端機,然後使用 curl 命令向伺服器發出請求
讓我們使用 post 方法建立一個物件
$ curl -X 'POST' \
'https://#:8001/heroes/' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"id": 1,
"name": "my hero",
"secret_name": "austing",
"age": 12
}'
您應該收到以下回應
{
"age": 12,
"id": 1,
"name": "my hero",
"secret_name": "austing"
}
讓我們使用下一個 curl 命令發出 get 請求
curl -X 'GET' \
'https://#:8001/heroes/' \
-H 'accept: application/json'
您應該收到與上面相同的回應,因為它是我們在資料庫中唯一的物件。
{
"age": 12,
"id": 1,
"name": "my hero",
"secret_name": "austing"
}
在終端機中按下 ctrl+c
以停止您的應用程式。
自動更新服務
使用 Compose Watch 在您編輯和儲存程式碼時自動更新正在執行的 Compose 服務。 有關 Compose Watch 的更多詳細資訊,請參閱 使用 Compose Watch。
在 IDE 或文字編輯器中開啟您的 compose.yaml
檔案,然後新增 Compose Watch 指令。 以下是更新後的 compose.yaml
檔案。
services:
server:
build:
context: .
ports:
- 8001:8001
environment:
- POSTGRES_SERVER=db
- POSTGRES_USER=postgres
- POSTGRES_DB=example
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
depends_on:
db:
condition: service_healthy
secrets:
- db-password
develop:
watch:
- action: rebuild
path: .
db:
image: postgres
restart: always
user: postgres
secrets:
- db-password
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=example
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
expose:
- 5432
healthcheck:
test: ["CMD", "pg_isready"]
interval: 10s
timeout: 5s
retries: 5
volumes:
db-data:
secrets:
db-password:
file: db/password.txt
執行以下命令以使用 Compose Watch 執行您的應用程式。
$ docker compose watch
在終端機中,使用 curl 呼叫應用程式以取得回應。
$ curl https://#:8001
Hello, Docker!
現在,您在本機機器上對應用程式原始碼檔案所做的任何變更都會立即反映在正在執行的容器中。
在 IDE 或文字編輯器中開啟 python-docker-dev-example/app.py
並更新 Hello, Docker!
字串,方法是新增更多驚嘆號。
- return 'Hello, Docker!'
+ return 'Hello, Docker!!!'
儲存對 app.py
的變更,然後等待幾秒鐘讓應用程式重新建置。 再次使用 curl 呼叫應用程式,並驗證更新的文字是否出現。
$ curl https://#:8001
Hello, Docker!!!
在終端機中按下 ctrl+c
以停止您的應用程式。
摘要
在本節中,您瞭解了如何設定 Compose 檔案以新增本地資料庫並保存資料。 您還學習了如何使用 Compose Watch 在更新程式碼時自動重新建置和執行您的容器。
相關資訊
後續步驟
在下一節中,您將瞭解如何使用 GitHub Actions 設定 CI/CD 管線。