简体   繁体   English

启动 docker 容器并安装卷后如何保留编译文件?

[英]How to keep compiled files after starting a docker container with volume mounted?

I have an image with multi-stage build for compiling some files and copy them into my final image.我有一个多阶段构建的图像,用于编译一些文件并将它们复制到我的最终图像中。

I also set a volume between the directory of my app on the host machine and inside the container.我还在主机上的应用程序目录和容器内设置了一个卷。

But when I start the container, the compiled files are not here.但是当我启动容器时,编译的文件不在这里。 As I understand how volumes work, it makes perfect sense: the container replaces the content of his directory with the content of the directory on the host machine, where the compiled files are not generated as they are generated by the container when it is building.据我了解卷是如何工作的,它非常有意义:容器用主机上目录的内容替换他的目录的内容,编译文件不会生成,因为它们是由容器在构建时生成的。

But I am wondering if there is a way to keep the volume and have the compiled files in the container when it starts.但是我想知道是否有一种方法可以在容器启动时保持音量并将编译后的文件放在容器中。 I assume that I am doing it wrong.我认为我做错了。

To give you more info about my need, I want to compile .css files from .scss inside a nodejs image and I copy the compiled .css to /app/<my_app>/static/css/ folder of my app docker image.为了向您提供有关我的需求的更多信息,我想从.scss图像中的 .scss 编译.css文件,并将编译后的.css复制到我的应用程序 docker 图像的/app/<my_app>/static/css/文件夹中。

Here is my project's structure:这是我的项目结构:

- docker-compose.yml
- production.env
- web/
- - Dockerfile
- - build/
- - - scss/
- - app/
- - - <my_app>/
- - - - static/
- - - - - css/

docker-compose.yml docker-compose.yml

version: '3'

services:
  web:
    build: web/
    ports:
      - "5000:5000"
    env_file: 
      - ./production.env
    volumes:
      - ./web/app:/app

Dockerfile Dockerfile

FROM node:alpine as builder

WORKDIR /build

COPY build/ .

RUN npm install && mkdir -p css

RUN npm run scss # Compile .scss files to .css into /build/css/ folder

FROM python:alpine

WORKDIR /app

COPY app/ .

COPY --from=builder /build/css ./<my_app>/static/css

/* ... Some instructions ... */

CMD flask run

Here, when I build the container the css files do not exist yet, they are compiled, copied to the final image.在这里,当我构建容器时,css 文件还不存在,它们被编译,复制到最终图像。 When I start the image, as there is a volume between./web/app:/app, the content of the image is replaced with the content in the host machine and so the.css files are missing.当我启动图像时,由于./web/app:/app 之间有一个卷,图像的内容被主机中的内容替换,因此缺少.css 文件。

The volume mounting occurs only at runtime;卷安装仅在运行时发生; after the Dockerfile has been built.在构建Dockerfile之后。

The volume mounts aren't applied to the container image while it's being built.在构建容器映像时,卷安装不会应用于容器映像。

The eg WORKDIR /app in the Dockerfile assumes the existence of (or creates) /app in the python:alpine build step as the image is built. Dockerfile中的 eg WORKDIR /app假设在构建映像时python:alpine构建步骤中存在(或创建) /app It appears that this is created as empty in the Dockerfile and the subsequent COPY /app.看起来这是在Dockerfile和随后的COPY /app. does nothing.什么也没做。

The /app volume mount is then applied after the image has been built and when it is used to create a container. /app volume mount 会在镜像构建完成后用于创建容器时应用。

Finally I have found a solution by myself, so I post the answer here hoping it will help someone else.最后我自己找到了解决方案,所以我把答案贴在这里希望它能帮助别人。

I abandoned the multi-stage build and try to create an image dedicated to scss compiling.我放弃了多阶段构建并尝试创建一个专门用于 scss 编译的图像。

Here is the Dockerfile of this image:这是这张图片的Dockerfile

FROM node:alpine

WORKDIR /build

COPY package.json ./

RUN mkdir -p ./scss ./css

RUN npm install

CMD npm run scss

Note that I use the module node-sass for compiling scss in a nodejs environment.请注意,我使用模块 node-sass 在 nodejs 环境中编译 scss。

For now, it just compiles files from scss/ and puts the output into css/ .现在,它只是从scss/编译文件并将 output 放入css/ But there is nothing in those folders yet.但是这些文件夹中还没有任何内容。

I edit my docker-compose.yml to run this new image at start and set two volumes from static folders of my app to scss/ and css/ folder in the container of this new image called scss .我编辑我的docker-compose.yml以在开始时运行这个新图像,并将我应用程序的 static 文件夹中的两个卷设置到这个名为scss的新图像容器中的scss/css/文件夹。 So when web will start, static/css will be filled by this new service using files from static/scss as source.因此,当web启动时,这个新服务将使用static/scss中的文件作为源来填充static/css

version: '3'

services:
  web:
    build: web/
    ports:
      - "5000:5000"
    depends_on:
      - scss
    env_file: 
      - ./production.env
    volumes:
      - ./web/app:/app
  scss:
    build: scss/
    env_file:
      - ./production.env
    volumes:
      - ./web/app/<my_app>/static/css:/build/css
      - ./web/app/<my_app>/static/scss:/build/scss  

Finally, it works.最后,它起作用了。

After running $ docker-compose up -d , css files are here.运行$ docker-compose up -d后,这里有 css 个文件。 The container of scss image is not running as it is a one-shot command, not a proper service running, but you can run it again if you made some changes to your .scss files and you want to compile .css again. scss图像的容器没有运行,因为它是一个一次性命令,而不是一个正确的服务运行,但是如果你对你的.scss文件做了一些更改并且你想再次编译.css ,你可以再次运行它。

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

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