【问题标题】:Why are there differences in container contents depending on whether I `docker run ...`or `docker-compose run ...`?为什么容器内容会因我是 `docker run ...` 还是 `docker-compose run ...` 而有所不同?
【发布时间】:2021-09-05 08:12:43
【问题描述】:

根据我是通过docker run -i -t <container> bash 还是docker-compose run <container> bash 打开 bash shell,我遇到了容器内容的差异,但我不知道/不明白这怎么可能。

为了帮助解释,请查看我终端上的this 截图。在这两种情况下,我都在运行名为blaze 的图像,它是从我的代码中的Dockerfile 构建的。构建过程中的步骤之一是创建一个名为venv 的virutalenv,但是当我通过docker-compose 打开一个bash shell 时,这个virtualenv 似乎并不存在,不像我运行docker run ... 时那样。

我对使用 Docker 设置自己的构建相对较新,但如果它们都引用相同的图像,那么 bash shell 中 ls 的输出肯定是一样的吗?我将非常感谢任何可以解释这里到底出了什么问题的资源的帮助或指导......

另外一点,运行 docker images 表明两个命令必须使用相同的图像...

提前致谢!

这是我的Dockerfile

FROM blaze-base-image:latest

# add an URL that PIP automatically searches (e.g., Azure Artifact Store URL)
ARG INDEX_URL
ENV PIP_EXTRA_INDEX_URL=$INDEX_URL

# Copy source code to docker image
RUN mkdir /opt/app
COPY . /opt/app
RUN ls /opt/app

# Install Blaze pip dependencies
WORKDIR /opt/app
RUN python3.7 -m venv /opt/app/venv
RUN /opt/app/venv/bin/python -m pip install --upgrade pip
RUN /opt/app/venv/bin/python -m pip install keyring artifacts-keyring
RUN touch /opt/app/venv/pip.conf
RUN echo $'[global]\nextra-index-url=https://www.index.com' > /opt/app/venv/pip.conf
RUN /opt/app/venv/bin/python -m pip install -r /opt/app/requirements.txt
RUN /opt/app/venv/bin/python -m spacy download en_core_web_sm

# Comment
CMD ["echo", "Container build complete"]

这是我的docker-compose.yml

version: '3'

services:
    blaze:
        build: .
        image: blaze
        volumes:
            - .:/opt/app

【问题讨论】:

    标签: python bash docker docker-compose virtualenv


    【解决方案1】:

    这里有两件相交的事情:

    1. 当您使用 Compose volumes:docker run -v 选项将主机内容挂载到容器目录上时,主机内容将完全替换映像中的内容。如果主机上没有./venv 目录,那么容器中就不会有/opt/app/venv 目录。这就是为什么,当你docker-compose run blaze ...时,虚拟环境不见了。

    2. 如果您 docker run 一个容器,则唯一考虑的选项是该特定 docker run 命令中的选项。 docker run 不知道 docker-compose.yml 文件并且不会从那里获取选项。这意味着在docker run 情况下没有此卷挂载,这就是虚拟环境重新出现的原因。

    通常在 Docker 中,您根本不需要虚拟环境:Docker 镜像与其他镜像和 Python 安装是隔离的,因此将您的应用程序安装到“系统”Python 中是安全且正常的。您通常还希望您的图像是独立的,不依赖于主机的内容,因此您通常不需要您显示的绑定挂载。

    这会将您的 Dockerfile 简化为:

    FROM blaze-base-image:latest
    
    # Any ARG will automatically appear as an environment variable to
    # RUN directives; this won't be needed at run time
    ARG PIP_EXTRA_INDEX_URL
    
    # Creates the directory if it doesn't exist
    WORKDIR /opt/app
    
    # Install the Python-level dependencies
    RUN pip install --upgrade pip
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    # The requirements.txt file should list every required package
    
    # Install the rest of the application
    COPY . .
    
    # Set the main container command to run the application
    CMD ["./app.py"]
    

    docker-compose.yml 文件可以类似地简化为

    version: '3.8' # '3' means '3.0'
    services:
      blaze:
        build: .
        # Compose picks its own image name
        # Do not need volumes:, the image is self-contained
    

    然后它将与docker rundocker-compose run(或docker-compose up)保持一致。

    【讨论】:

    • 非常感谢您的评论,这真的很有帮助。至于从docker-compose.yml 文件中删除卷部分,我的印象是该部分允许代码更新实时反映在容器中 - 不是这样吗?理想情况下,我希望能够看到实时变化,而不必每次都重建图像......
    • 可以使用基于主机的虚拟环境进行实时开发,使用Docker进行部署。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    相关资源
    最近更新 更多