挂载卷会覆盖存储在Docker映像中的文件

时间:2020-05-04 04:18:21

标签: docker nginx docker-compose dockerfile lets-encrypt

我正在尝试将网站的前端容器化并自动进行部署。我的目标是能够在推送更改时生成并托管一个新映像,并让服务器自动获取它并重新启动容器。这是我要采取的步骤:

  1. 我首先通过构建Node应用程序,然后将发行版和nginx配置文件捆绑到最新的linuxserver/letsencrypt映像中来创建映像。这是Dockerfile:

    # Use the NodeJS image as builder
    FROM node:alpine AS builder
    
    # Create the workspace
    RUN mkdir -p /usr/src/app
    WORKDIR /usr/src/app
    
    # Copy the package file and source code
    COPY package.json /usr/src/app
    COPY . ./
    
    # Install dependencies
    RUN npm install
    
    # Build the application
    RUN npm run build
    
    # The nginx server, this builds the final image
    FROM linuxserver/letsencrypt
    
    # Copy the nginx configuration
    COPY ./config/nginx.conf /config
    
    # Copy the output of the builder
    COPY --from=builder /usr/src/app/dist /config/www
    
    # Inform Docker to listen on port 443 and 80
    EXPOSE 443 80  
    
  2. 此图像已上传到GitHub's package registry,我使用Watchtower轮询更新。

  3. 使用此docker-compose文件启动图像:

    version: "3"
    services:
      ...
      frontend:
        image: [IMAGE]
        container_name: frontend
        cap_add:
          - NET_ADMIN
        environment:
          - PUID=1000
          - PGID=1000
          - TZ=[TIMEZONE]
          - URL=[URL]
          - SUBDOMAINS=www,
          - VALIDATION=http
        ports:
          - 443:443
          - 80:80
        volumes:
          - ./frontend:/config
        restart: unless-stopped
      ...  
    

问题是,当我在docker-compose中使用以下行时,使用COPY指令打包到映像中的文件将被覆盖:

volumes:
  - ./frontend:/config  

如果我从docker-compose文件中删除该部分,则一切正常,但是这不是解决方案,因为该文件夹存储了重要数据。

我已经读到,装入卷会完全覆盖以前的所有数据,但是我喜欢这样的事实,即我可以轻松地将映像加载到服务器上并已嵌入所有必需的文件。有什么我可以解决的问题,还是我滥用/误解了Docker映像?

我尝试按照建议的here将卷设置为只读,但是这没有用,而是导致映像不断停止并重新启动。

我还简要了解了bind mounts,并想知道它们是否会有用。

2 个答案:

答案 0 :(得分:1)

此行为是预期的。 Docker挂载的工作方式与Linux挂载相同,即用源目录的内容覆盖目标目录的内容。

我的建议是为卷使用另一个目标目录,例如

volumes:
 - ./frontend:/someotherdir 

然后调整您的nginx配置以在其中查找JS文件。

答案 1 :(得分:0)

我发现我可以通过首先创建一个named volume来保留图像中的数据:

volumes:
  frontend_data:

然后将容器安装到该体积:

services:
  frontend:
    ...
    volumes:
      - frontend_data:/config
    ...