更新Docker容器内服务器应用程序的源代码,而不涉及现有的已保存数据

zbsbpyhn  于 2022-11-22  发布在  Docker
关注(0)|答案(1)|浏览(69)

我有以下Docker Compose项目(文件内容如下):

.
|-- .dockerignore
|-- Dockerfile
|-- docker-compose.yml
|-- messages
    |-- 20221120-010625.txt
    |-- 20221120-010630.txt
    `-- 20221120-010641.txt
|-- package.json
`-- server.js

使用以下命令运行Docker Compose项目时:

$ docker-compose up -d

您可以转到URL:http://localhost/?message=<message>并在服务器上录制多条消息。
这里有一个例子:

目前为止一切顺利,但是...

**我的用例是:**有时我需要更新网站的源代码。例如,假设我需要在上面的屏幕截图中添加页面文本的前缀:Created file ...,其中:###,例如:

创建的文件:“/var/www/html/messages/20221120-010641.txt”,内容包括:“这是一个测试”。

但是我不能修改现有的消息,因为这些消息对服务器应用程序来说是有价值的数据。

我尝试使用以下命令:

$ docker-compose down --volumes
$ docker-compose up -d --force-recreate --build

**我的问题是:**在相应地更新源代码后,即使页面文本得到了正确的更新,所有的消息都丢失了,这是不好的。

您能告诉我如何才能做到这一点吗?
我尝试在docker-compose.yml中定义一个命名卷,如下所示:

services:
  serverapp:
    ...
    volumes:
      - messages:/var/www/html/messages

volumes:
  messages:

......希望在销毁服务器应用程序时消息仍然存在,但这不起作用,因为该命名卷由用户root拥有,而消息由用户创建:node,它没有在该目录上创建文件的权限,这会导致错误。
以下是所涉及文件的内容:

.停靠忽略

/node_modules/
/messages/
/npm-debug.log

停靠文件

FROM node:16-alpine

RUN mkdir -p /var/www/html && chown -R node:node /var/www/html

WORKDIR /var/www/html

COPY --chown=node:node . .

USER node

RUN npm i

EXPOSE 8080

CMD [ "npm", "run", "start" ]

# ENTRYPOINT ["tail", "-f", "/dev/null"]

停靠-撰写.yml

version: '3'

services:
  serverapp:
    image: alpine:3.14
    build:
      dockerfile: Dockerfile
    container_name: serverapp
    restart: unless-stopped
    ports:
      - "80:80"

包.json

{
    "name": "docker-compose-tester",
    "version": "1.0.0",
    "main": "server.js",
    "scripts": {
        "start": "cross-env NODE_ENV=debug nodemon --exec babel-node server.js"
    },
    "dependencies": {
        "express": "^4.16.1",
        "moment": "^2.29.4"
    },
    "devDependencies": {
        "@babel/node": "^7.20.2",
        "cross-env": "^7.0.3",
        "nodemon": "^2.0.20"
    }
}

服务器.js

const express = require('express');
const moment = require('moment');
const path = require('path');
const fs = require('fs');

const PORT = 80;

const app = express();

app.use('/messages/', express.static(path.join(__dirname, 'messages')));

app.get('/', (req, res) => {
  const message = req.query.message;
  if (!message) {
    return res.send('<pre>Please use a query like: "/?message=Hello+World"</pre>');
  }
  const dirPathMessages = path.join(__dirname, 'messages');
  const date = moment(new Date()).format('YYYYMMDD-HHmmss');
  const fileNameMessage = `${date}.txt`;
  const filePathMessage = path.join(dirPathMessages, fileNameMessage);
  fs.mkdirSync(dirPathMessages, { recursive: true });
  fs.writeFileSync(filePathMessage, message);
  const filesList = fs.readdirSync(dirPathMessages);
  const filesListStr = filesList.reduce((output, fileNameMessage) => {
    const filePathMessage = path.join(dirPathMessages, fileNameMessage);
    const message = fs.readFileSync(filePathMessage);
    return output + `<div><a href="/messages/${fileNameMessage}">/messages/${fileNameMessage}</a> -> ${message}</div>` + "\n";
  }, '');
  res.send(`<pre>${filesListStr}\nCreated file: "${filePathMessage}" with content: "${message}".</pre>`);
});

app.listen(PORT, () => {
  console.log(`TCP Server is running on port: ${PORT}`);
});
ni65a41a

ni65a41a1#

您使用命名卷的方法是正确的。要解决权限问题,请在切换到node用户之前,更改Dockerfile中messages文件夹的所有者。

FROM node:16-alpine

RUN mkdir -p /var/www/html && chown -R node:node /var/www/html

WORKDIR /var/www/html

COPY --chown=node:node . .

RUN mkdir -p messages && chown node:node messages

USER node

...

相关问题