Home > front end >  Overwrite volume contents with container's contents
Overwrite volume contents with container's contents

Time:12-03

I have a volume which contains data that needs to stay persisted. When creating the volume for the first time, and mounting it to my node container, all container contents are copied to the volume, and everything behaves as expected. The issue is that when I change a few files in my node container, I remove the old image and container, and rebuild them from scratch. When running the updated container, the container's files don't get copied into the volume. This means that the volume still contains the old files, and therefore when the volume is mounted in the container, no updated functionality is present, and I have to remove and recreate the volume from scratch, which I can't do since the volume's data needs to be persisted.

Here is my 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"]

Here are my commands and expected output

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 

when running

docker exec need-backup-container cat index.js

the file is present and contains the latest updates, since the volume was just created.

Now when I update some files, I need to rebuild the image and the container, so I run

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

Now I thought that when running

docker exec need-backup-container cat index.js

I'd see the updated file changes, but nope, I only see the old files that were first created when the volume was mounted for the first time. So my question is, is there anyway to achieve overwriting the volume's files when creating a container?

CodePudding user response:

If your application needs persistent data, it should be stored in a different directory from the application code. This can be in a dedicated /data directory or in a subdirectory of your application; the important thing is that, when you mount a volume to hold the persistent data, it does not hide your application code.

In a Node application, for example, you could refer to a ./data for your data files:

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');

Then in your Dockerfile you'd need to create that directory. If you set up a non-root user, that directory, but not your code, should be owned by the user.

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"]

Then when you launch the container, mount the volume only on the data directory, not over the entire /app tree.

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

Note that the Dockerfile as shown here would also let you use a host directory instead of a Docker named volume, and specify the host uid when you run the container. You do not need to make any changes to the image to do this.

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