【问题标题】:How to run any commands in docker volumes?如何在 docker 卷中运行任何命令?
【发布时间】:2018-07-25 19:27:34
【问题描述】:

经过几天的 docker 测试和工作(我通常尝试从 vagrant 迁移到 docker),我遇到了一个巨大的问题,我不知道如何或在哪里解决它。

docker-compose.yml

version: "3"
services:
  server:
    build: .
    volumes:
      - ./:/var/www/dev
    links:
      - database_dev
      - database_testing
      - database_dev_2
      - mail
      - redis
    ports:
      - "80:8080"
    tty: true
    #the rest are only images of database redis and mailhog with ports

Dockerfile

示例_1

FROM ubuntu:latest
LABEL Yamen Nassif
SHELL ["/bin/bash", "-c"]
RUN apt-get install vim mc net-tools iputils-ping zip curl git  -y
RUN curl -sS https://getcomposer.org/installer |  php -- --install-dir=/usr/local/bin --filename=composer
RUN cd /var/www/dev
RUN composer install 

Dockerfile

示例_2

....
RUN apt-get install apache2 openssl php7.2 php7.2-common libapache2-mod-php7.2 php7.2-fpm php7.2-mysql php7.2-curl php7.2-dom php7.2-zip php7.2-gd php7.2-json php7.2-opcache php7.2-xml php7.2-cli php7.2-intl php7.2-mbstring php7.2-redis -y

# basically 2 files with just rooting to /var/www/dev
COPY docker/config/vhosts /etc/apache2/sites-available/
RUN service apache2 restart
....

现在找不到 example_1 composer.json 文件/目录 并且 example_2 apache 会说找不到根目录 文件/目录 = /var/www/dev 我猜它是因为它是一个卷,并且在容器完全启动之前它不会启动,因为如果我在没有 prev 命令的情况下启动容器会导致错误,那么我可以登录到容器并从命令行执行命令而不会出现任何错误

如何解决这个问题?

【问题讨论】:

    标签: docker docker-compose


    【解决方案1】:

    在您的第一个 Dockerfile 中,使用 COPY 指令将您的应用程序复制到映像中,然后再执行 RUN composer install 之类的操作。它看起来像

    FROM php:7.0-cli
    COPY . /usr/src/app
    WORKDIR /usr/src/app
    RUN composer install
    

    (抄自php image documentation;该图像可能没有预装作曲家)。

    在这两个 Dockerfile 中,请记住每个 RUN 命令都会创建一个新的空容器,运行它的命令,然后自行清理。这意味着像RUN cd ... 这样的命令无效,并且您不能在一个RUN 命令中在后台启动服务并使其稍后可用;它会在 Dockerfile 移动到下一行之前停止。

    在第二个 Dockerfile 中,像 servicesystemctlinitctl 这样的命令在 Docker 中不起作用,您不应该尝试使用它们。标准做法是在容器通过默认的CMD 指令启动时将服务器进程作为前台进程启动。不利的一面是,由于服务器要到docker run 时间才会启动,因此您的卷将在那时可用。我可能会在 Dockerfile 中 RUN mkdir 以确保它存在。

    【讨论】:

    • 关于 RUN 命令的很棒的信息,但是复制文件和通过卷提供它们有什么区别?
    • 如果您复制它们,它们就在镜像中,您可以将其推送到注册表,并且执行此操作的说明在 Dockerfile 中,您可以将其提交到源代码管理。如果它们在一个卷中,则序列的重现性要差得多。
    • 是的,我想我想念我的问题,我想问的是:不是从实际上不在服务器上但(链接或阴影)的卷中提供文件让生活更轻松吗?我的意思是关于编码、更改等
    • 恕我直言,这让生活变得更加艰难;我的意思是自动构建、可重复构建、对不同主机的部署、源代码控制、可审计性等。但是您可以在 SO 和其他地方找到许多使用绑定安装的主机目录来存放应用程序代码的示例。
    【解决方案2】:

    问题似乎是执行顺序。在映像构建时 /var/www/dev 可用。当您从该映像启动容器时,容器 /var/www/dev 将被您的本地挂载覆盖。

    如果您不需要主机访问,您可以简单地跳过额外的卷。 如果您想在其他容器中使用它,您应该使用符号链接。

    【讨论】:

    • 这正是我写的问题because its a volume and it wont be up until the container is fully up
    猜你喜欢
    • 2020-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-24
    • 2020-05-21
    相关资源
    最近更新 更多