FastApi 应用程序中是否可以使用多级 docker

问题描述 投票:0回答:1

我只是在我的基本 CRUD 应用程序中创建一个单阶段 dockerfile。 我想要多阶段,因为减少了我的泊坞窗图像的空间。 Dockerfile

FROM python:3.9-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set the working directory in the container
WORKDIR /app

# Copy the dependencies file to the working directory
COPY requirements.txt .

RUN apt-get update && apt-get install -y default-mysql-client netcat-traditional && rm -rf /var/lib/apt/lists/*

# Install dependencies
RUN pip3 install -r requirements.txt

# Copy the content of the local src directory to the working directory
COPY . .
COPY wait-for.sh .
# Expose port 8000 to the outside world
EXPOSE 8000
RUN chmod +x wait-for.sh
CMD ["uvicorn", "index:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]

所以我在我的 Dockerfile 中执行此操作 Dockerfile.dev

FROM python:3.9-slim as BUILD
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
WORKDIR /app

COPY requirements.txt .
RUN pip install -r requirements.txt
RUN apt-get update && apt-get install -y default-mysql-client netcat-traditional && rm -rf /var/lib/apt/lists/*
COPY . .

#CMD
FROM python:3.9-slim

COPY --from=BUILD . .
COPY wait-for.sh .
# Expose port 8000 to the outside world
EXPOSE 8000

RUN chmod +x wait-for.sh
CMD ["uvicorn", "index:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]

但是第二步放不下index.py文件。

docker-compose.yml

version: '3.8'

services:
  app:
    build: 
      context: .
      dockerfile: Dockerfile.dev #Here change the Dockerfile and Dockerfile.dev 
                                 #Dockerfile for single stage and Dockerfile.dev for multistage
    ports:
      - 8000:8000
    # restart: on-failure
    environment:
      DATABASE_HOST: db
      DATABASE_USER: root
      DATABASE_PASSWORD: 12345678
      DATABASE_NAME: Student
    depends_on:
      - db
    entrypoint: [ "./wait-for.sh", "db:3306", "--", "uvicorn", "index:app", "--reload", "--host", "0.0.0.0", "--port", "8000" ]
  db:
    image: mysql:5.7
    volumes:
      - ./my.cnf:/etc/mysql/my.cnf
    environment:
      MYSQL_USER: user
      MYSQL_ROOT_PASSWORD: 12345678
      MYSQL_DATABASE: Student
      MYSQL_PASSWORD: 12345678
    ports:
      - "3307:3306"
 

我的问题是“是否可以使用多级 docker 来 dockerize 我的 fastapi 应用程序?” 如果可能的话我该怎么做。另外,如果不可能那么为什么我不能这样做。 这个的切入点是什么?

docker docker-compose dockerfile
1个回答
0
投票

您显示的图像不会受益于多阶段构建。

多阶段构建可以节省空间的设置是,如果您需要一些工具来构建映像,但不需要实际运行容器。对于 Python 应用程序,具有 C 扩展的库需要 C 编译器,该编译器相当大,但仅在安装时才需要。对于这类应用程序,第一阶段可以安装编译器和C头文件,但第二阶段只需要相应的运行时库。

基于 Python 的 Dockerfile 示例可能如下所示。请注意,我们在构建和运行时阶段使用完全相同的基础映像,并且虚拟环境位于同一目录中。第一阶段安装

build-essential
,其中包含完整的C工具链,但相当大;第二阶段不需要那个。

ARG PYTHON=python:3.12-slim
FROM $PYTHON AS build

# Install (large) build-time dependencies
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      build-essential \
      libpq-dev

# Create a virtual environment that can be copied into the next stage
RUN python -m venv /venv

# Install packages into it
WORKDIR /app
COPY requirements.txt ./
RUN /venv/bin/pip install -r requirements.txt

FROM $PYTHON

# Install only the libraries you need to run the application
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      libpq5

# Copy the virtual environment from the first stage
COPY --from=build /venv/ /venv/
ENV PATH=/venv/bin:$PATH

# The rest of your Dockerfile as before
...
CMD ["uvicorn", ...]

您还询问了入口点的正确值。这在多阶段构建中不会改变,请注意仅使用最终图像的值。

您通常不需要覆盖 Compose 文件中的

entrypoint:
,而且很多情况下也不需要覆盖
command:
。我可能会将对
wait-for.sh
的调用移至 Dockerfile

ENTRYPOINT ["./wait-for.sh", "db:3306", "--"]
CMD ["uvicorn", ...]

更强大的解决方案可能是将其包装在专用的 shell 脚本中,该脚本遵循部署时数据库主机名

#!/bin/sh

# Wait for the database to be ready
if [ -n "$DATABASE_HOST" ]; then
  ./wait-for.sh "$DATABASE_HOST:3306"
fi

# Switch to the main container command
exec "$@"

此脚本可以是图像的

ENTRYPOINT
(确保使用JSON数组语法),并且您不需要在Compose文件中放置任何特殊内容。

© www.soinside.com 2019 - 2024. All rights reserved.