用容器的内容覆盖卷内容

Overwrite volume contents with container's contents

我有一个卷,其中包含需要保留的数据。第一次创建卷并将其安装到我的节点容器时,所有容器内容都被复制到卷中,一切都按预期运行。问题是当我更改我的节点容器中的一些文件时,我删除了旧图像和容器,并从头开始重建它们。 运行更新容器时,容器的文件不会复制到卷中。这意味着该卷仍然包含旧文件,因此当该卷安装在容器中时,不存在更新的功能,我必须从头开始删除并重新创建该卷,因为该卷的数据我不能这样做需要坚持。

这是我的 dockerfile

FROM mcr.microsoft.com/dotnet/sdk:5.0
COPY CommandLineTool App/CommandLineTool/ 
COPY NeedBackupNodeServer App/NeedBackupNodeServer/
WORKDIR /App/NeedBackupNodeServer
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \ 
    && apt update \
    && apt install -y nodejs
EXPOSE 5001
ENTRYPOINT ["node", "--trace-warnings", "index.js"]

这是我的命令和预期输出

docker volume create nodeServer-and-commandLineTool-volume 

docker build -t need-backup-image -f Dockerfile . 

docker run -p 5001:5001 --name need-backup-container -v nodeServer-and-commandLineTool-volume:/App need-backup-image -a 

当运行宁

docker exec need-backup-container cat index.js

文件存在并且包含最新的更新,因为刚刚创建了卷。

现在当我更新一些文件时,我需要重建镜像和容器,所以我运行

docker rm need-backup-container   

docker rmi need-backup-image  

docker build -t need-backup-image -f Dockerfile . 

docker run -p 5001:5001 --name need-backup-container -v nodeServer-and-commandLineTool-volume:/App need-backup-image -a

现在我想当运行宁

docker exec need-backup-container cat index.js

我会看到更新后的文件发生了变化,但是没有,我只看到了第一次安装卷时创建的旧文件。 所以我的问题是,在创建容器时是否可以实现覆盖卷的文件?

如果您的应用程序需要持久数据,则应将其存储在与应用程序代码不同的目录中。这可以在专用的 /data 目录或应用程序的子目录中;重要的是,当你挂载一个卷来保存持久数据时,它不会隐藏你的应用程序代码。

例如,在 Node 应用程序中,您可以为数据文件引用 ./data

import { open } from 'fs/promises';
import { join } from 'path';
const dataDir = process.env.DATA_DIR || 'data';
const fh = await open(join(dataDir, 'file.txt'), 'rw');

然后在您的 Docker 文件中,您需要创建该目录。如果您设置了非 root 用户,则该目录而非您的代码应归该用户所有。

FROM node:lts

# Create the non-root user
RUN adduser --system --no-create-home nonroot

# Install the Node application normally
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY index.js .

# Create the data directory
RUN mkdir data && chown nonroot data

# Specify how to run the container
USER nonroot
CMD ["node", "index.js"]

然后当您启动容器时,将卷 挂载到数据目录,而不是整个 /app 树。

docker run \
  -p 5001:5001 \
  --name need-backup-container \
  -v nodeServer-and-commandLineTool-volume:/app/data \
  need-backup-image
#                                          ^^^^^^^^^

请注意,此处显示的 Docker 文件还允许您使用主机目录而不是 Docker 命名卷,并在 运行 容器时指定主机 uid .您无需对图像进行任何更改即可执行此操作。

docker run \
  -p 5002:5001 \
  --name same-image-with-bind-mount \
  -u $(id -u) \
  -v "$PWD/app-data:/app/data" \
  need-backup-image