简体   繁体   English

Docker多级构建无法识别已安装的应用程序

[英]Docker multistage build doesn't recognise installed application

FROM some-build:latest as build

COPY / /var/www/html

WORKDIR /var/www/html
RUN cd /var/www/html && composer install

FROM some-build2:latest as run

COPY --from=build /var/www/html /var/www/html

ENV PATH ${HOME}/local/bin:${PATH}:/home/site/wwwroot

RUN cd /var/www/html && \
    npm install && \
    npm run production

ENTRYPOINT ["/bin/init_container.sh"]

The image run contains an installed npm . 图像run包含已安装的npm Despite this fact, the npm install return the error: /bin/sh: 1: npm: not found 尽管如此, npm install返回错误: /bin/sh: 1: npm: not found

How is this possible? 这怎么可能? What am I doing wrong? 我究竟做错了什么?


Edit: 编辑:

As answer to @BMitch 's comment, when I run the RUN image, in the container the node is on the PATH and I can use it. 作为对@BMitch评论的回答,当我运行RUN图像时,在容器中节点位于PATH上,我可以使用它。 The path is /root/local/bin . 路径是/root/local/bin I've attached all the Dockerfiles. 我已经附加了所有Dockerfiles。

I have 3 docker files: 我有3个泊坞文件:
APP APP
The one you've already seen before. 你以前见过的那个。

RUN

FROM php:7.2.5-apache
MAINTAINER Azure App Services Container Images <appsvc-images@microsoft.com>

COPY apache2.conf /bin/
COPY init_container.sh /bin/

RUN a2enmod rewrite expires include deflate

# install the PHP extensions we need
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
     libpng-dev \
     libjpeg-dev \
     libpq-dev \
     libldap2-dev \
     libldb-dev \
     libicu-dev \
     libgmp-dev \
     mysql-client \
     libmagickwand-dev \
     openssh-server vim curl wget tcptraceroute \
    && chmod 755 /bin/init_container.sh \
    && echo "root:Docker!" | chpasswd \
    && echo "cd /home" >> /etc/bash.bashrc \
    && ln -s /usr/lib/x86_64-linux-gnu/libldap.so /usr/lib/libldap.so \
    && ln -s /usr/lib/x86_64-linux-gnu/liblber.so /usr/lib/liblber.so \
    && ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h \
    && rm -rf /var/lib/apt/lists/* \
    && pecl install imagick-beta \
    && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr \
    && docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \
    && docker-php-ext-configure mysqli --with-mysqli=mysqlnd \
    && docker-php-ext-install gd \
     mysqli \
     opcache \
     pdo \
     pdo_mysql \
     pdo_pgsql \
     pgsql \
     ldap \
     intl \
     gmp \
     zip \
     bcmath \
     mbstring \
     pcntl \
     xml \
     xmlrpc \
    && docker-php-ext-enable imagick

###################
# Installing node #
###################

RUN apt-get update -yq && apt-get upgrade -yq && \
apt-get install -yq g++ libssl-dev apache2-utils curl git python make nano

# setting up npm for global installation without sudo
# http://stackoverflow.com/a/19379795/580268
RUN MODULES="local" && \
    echo prefix = ~/$MODULES >> ~/.npmrc && \
    echo "export PATH=\$HOME/$MODULES/bin:\$PATH" >> ~/.bashrc && \
    . ~/.bashrc && \
    mkdir ~/$MODULES && \
\
# install Node.js and npm
# https://gist.github.com/isaacs/579814#file-node-and-npm-in-30-seconds-sh
    mkdir ~/node-latest-install && cd $_ && \
    curl http://nodejs.org/dist/v8.11.3/node-v8.11.3.tar.gz | tar xz --strip-components=1 && \
    ./configure --prefix=~/$MODULES && \
    make install && \
    curl -L https://www.npmjs.org/install.sh | sh

# optional, check locations and packages are correct
# RUN which node; node -v; which npm; npm -v; \
#   npm ls -g --depth=0

# Remove unnecessary packages
# RUN apt-get -yq purge g++ libssl-dev curl git python make nano
# RUN apt-get -yq autoremove

###################

RUN   \
   rm -f /var/log/apache2/* \
   && rmdir /var/lock/apache2 \
   && rmdir /var/run/apache2 \
   && rmdir /var/log/apache2 \
   && chmod 777 /var/log \
   && chmod 777 /var/run \
   && chmod 777 /var/lock \
   && chmod 777 /bin/init_container.sh \
   && cp /bin/apache2.conf /etc/apache2/apache2.conf \
   && rm -rf /var/www/html \
   && rm -rf /var/log/apache2 \
   && mkdir -p /home/LogFiles \
   && ln -s /home/LogFiles /var/log/apache2 


RUN { \
        echo 'opcache.memory_consumption=128'; \
        echo 'opcache.interned_strings_buffer=8'; \
        echo 'opcache.max_accelerated_files=4000'; \
        echo 'opcache.revalidate_freq=60'; \
        echo 'opcache.fast_shutdown=1'; \
        echo 'opcache.enable_cli=1'; \
    } > /usr/local/etc/php/conf.d/opcache-recommended.ini

RUN { \
        echo 'error_log=/var/log/apache2/php-error.log'; \
        echo 'display_errors=Off'; \
        echo 'log_errors=On'; \
        echo 'display_startup_errors=Off'; \
        echo 'date.timezone=UTC'; \
    } > /usr/local/etc/php/conf.d/php.ini


COPY sshd_config /etc/ssh/

EXPOSE 2222 8080

ENV APACHE_RUN_USER www-data
ENV PHP_VERSION 7.2.5

ENV PORT 8080
ENV WEBSITE_ROLE_INSTANCE_ID localRoleInstance
ENV WEBSITE_INSTANCE_ID localInstance
ENV PATH ${PATH}:/home/site/wwwroot

ENTRYPOINT ["/bin/init_container.sh"]

BUILD 建立

FROM composer:latest as composer

FROM php:7.2.5-apache as apache

COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN apt-get update && \
apt-get install git zip unzip -y

Edit 2: 编辑2:
It is important that if I remove the RUN npm... commands, then the whole build is a success and the result image contains the npm and I can use it (I've verified by using a container in interactive mode). 重要的是,如果我删除RUN npm...命令,那么整个构建是成功的,结果图像包含npm,我可以使用它(我已经通过在交互模式下使用容器进行了验证)。


Edit 3: 编辑3:
Here's a lot lot simpler solution that can be tried out instantly: 这里有很多简单的解决方案可以立即尝试:

FROM alpine as img1
RUN echo "$HOME" > $HOME/test.txt

FROM alpine as img2
RUN cat $HOME/test.txt

The result is: cat: can't open '/root/test.txt': No such file or directory 结果是: cat: can't open '/root/test.txt': No such file or directory

Two issues going on here. 这里有两个问题。 The "php:7.2.5-apache" image won't have /root/local/bin in the path, and you did not add it to the path during your build. “php:7.2.5-apache”映像在路径中没有/ root / local / bin,并且在构建期间没有将它添加到路径中。 The npm commands will work when you login interactively likely because of some changes to the shell login scripts that setup the environment. 由于对设置环境的shell登录脚本进行了一些更改,因此当您以交互方式登录时,npm命令将起作用。 You'll need to run these environment setup scripts before running any npm commands, and that must be done within the same RUN command. 在运行任何npm命令之前,您需要运行这些环境设置脚本,并且必须在相同的RUN命令中完成。 To verify for yourself, you can check your .bashrc for variables or commands run to setup the npm environment. 要自己验证,可以检查.bashrc中的变量或命令运行以设置npm环境。 And you can verify the environment is different by comparing the PATH value with an env command in the interactive shell and in your build, you should see two different outputs if this is your issue. 您可以通过在交互式shell和构建中将PATH值与env命令进行比较来验证环境是否不同,如果这是您的问题,您应该看到两个不同的输出。 When I ran part of your run image, I saw the following in the .bashrc: 当我运行部分运行映像时,我在.bashrc中看到以下内容:

export PATH=$HOME/local/bin:$PATH

So you'll want to update the line in your Dockerfile for the run image: 因此,您需要更新Dockerfile中用于运行映像的行:

ENV PATH /root/local/bin:${PATH}:/home/site/wwwroot

Per your edit 3, that's an entirely different issue. 根据您的编辑3,这是一个完全不同的问题。 You created a file in one new image, and then went back to the base image where the file doesn't exist. 您在一个新映像中创建了一个文件,然后返回到该文件不存在的基本映像。 If you wanted to see the file in a multi-stage build, then you either need to copy it between the stages, or use the previous image as your "from". 如果您想在多阶段构建中查看文件,则需要在阶段之间复制它,或者使用上一个图像作为“from”。

FROM alpine as img1
RUN echo "$HOME" > $HOME/test.txt

FROM alpine as img2
COPY --from=img1 /root/test.txt /root/test.txt
RUN cat $HOME/test.txt

or 要么

FROM alpine as img1
RUN echo "$HOME" > $HOME/test.txt

FROM img1 as img2
RUN cat $HOME/test.txt

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM