我无法将使用 Docker Compose 创建的容器挂载到本地的文件夹中,这是怎么回事?

I cannot mount the container I created with Docker Compose to a folder in my local, what's wrong?

提问人:Mustafa Tunahan Tuna 提问时间:11/17/2023 最后编辑:Mustafa Tunahan Tuna 更新时间:11/19/2023 访问量:54

问:

我正在使用 Node.js 和 Express 运行一个简单的应用程序。我正在尝试创建应用程序的 Docker 映像,并使用 Docker Compose 使用该映像创建容器。我想将工作区中的文件挂载到生成的容器(在本例中为 index.js、package.json 和其他文件)到 docker-compose.yml 文件所在目录中的 ./test,但我收到错误。

源代码

索引.js

const express = require("express");
const app = express();
const port = 3000;

app.get("/", (req, res) => {
  res.send("Hello Docker Compose!");
});

app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});

package.json

{
  "name": "my-node-app",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "express": "^4.17.1"
  },
  "scripts": {
    "start": "node index.js"
  }
}

Docker文件

FROM node:14

WORKDIR /app

COPY package.json /app
COPY index.js /app
RUN npm install

EXPOSE 3000

CMD ["npm", "start"]

我正在使用以下命令构建应用程序:

docker build -t express-app:latest .

在另一个名为 test-app 的文件夹中,我使用命令运行以下 docker-compose.yml 文件。docker compose up

容器中 workdir 中的文件没有进入 ./test 文件夹,我收到以下错误。

Attaching to test-app-express-app-1
test-app-express-app-1  | npm ERR! code ENOENT
test-app-express-app-1  | npm ERR! syscall open
test-app-express-app-1  | npm ERR! path /app/package.json
test-app-express-app-1  | npm ERR! errno -2
test-app-express-app-1  | npm ERR! enoent ENOENT: no such file or directory, open '/app/package.json'
test-app-express-app-1  | npm ERR! enoent This is related to npm not being able to find a file.
test-app-express-app-1  | npm ERR! enoent
test-app-express-app-1  |
test-app-express-app-1  | npm ERR! A complete log of this run can be found in:
test-app-express-app-1  | npm ERR!     /root/.npm/_logs/2023-11-17T15_23_04_691Z-debug.log
test-app-express-app-1 exited with code 254

我不明白我做错了什么。你可以帮我吗?

docker-compose.yml

这个yml文件是我想运行的

version: '3'

services:
  express-app:
    container_name:test
    image: express-app:latest
    ports:
      - 3000:3000
    volumes:
      - ./test:/app

这个yml文件有效,但它没有在我工作的目录中执行挂载操作:

version: '3'

services:
  express-app:
    container_name:test
    image: express-app:latest
    ports:
      - 3000:3000
    volumes:
      - test:/app
volumes:
   test:

此 yaml 文件是名为 Strapi 的 nodejs 无头 cms 应用程序映像的 docker-compose.yml 文件

version: '3'

services:
  strapi:
    container_name: strapi
    image: strapi/strapi
    environment:
      - NODE_ENV=production
      - DATABASE_CLIENT=postgres
      - DATABASE_HOST=db
      - DATABASE_PORT=5432
      - DATABASE_NAME=strapi
      - DATABASE_USERNAME=strapi
      - DATABASE_PASSWORD=strapi
    ports:
      - 1337:1337
    volumes:
      - ./app:/srv/app
    depends_on:
      - db
    command: 'strapi start'

  db:
    container_name: postgres
    image: postgres
    restart: always
    volumes:
      - ./db:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: strapi
      POSTGRES_PASSWORD: strapi
      POSTGRES_DB: strapi

docker-compose dockerfile docker-volume docker-image

评论

0赞 David Maze 11/18/2023
您似乎实际上没有在问题中包含 Compose 文件。如果你使用来自主机的代码替换映像的整个目录,那么你根本没有真正测试映像中的任何内容,你可能会发现在没有 Docker 的情况下使用 Node 来运行这样的测试更容易。volumes:/app
0赞 Mustafa Tunahan Tuna 11/18/2023
我将docker-compose.yml文件附加到问题中
0赞 David Maze 11/18/2023
在这两种 Compose 设置中,该块都会隐藏目录中的所有内容,包括其文件。我建议删除它。如果你正在考虑运行单元测试,我会使用你的非 Docker 开发环境来做到这一点,然后再使用映像。volumes:/apppackage.jsondocker build
0赞 Mustafa Tunahan Tuna 11/18/2023
那么,为什么当我使用Strapi的旧示例yaml文件时没有这样的问题呢?它将应用程序和数据库文件挂载到本地目录中?我正在将该示例 yaml 文件附加到该主题。

答:

0赞 Jeong Yo Han 11/18/2023 #1

您构建的映像中似乎没有。
键入 时。 你没有在构建docker镜像时遇到错误吗?
package.jsondocker build -t express-app:latest

就像控制台中的以下错误一样。

 => ERROR [3/4] COPY package.json /app   

您可以修改 Dockerfile 以找出 Docker 编写时内部的内容。

FROM node:14

WORKDIR /app

COPY package.json /app
COPY test.js /app

CMD "tail -f /dev/null"

docker compose up后,键入以查看正在运行的docker进程,

键入以获取sh 。
docker psdocker exec -it [docker-name] /bin/sh

更新细节的答案

  1. 创建测试包.json和测试.js
{
    "hi" : "hello"
}
console.log('hi')
  1. 创建 Dockerfile
FROM node:14

WORKDIR /app

COPY package.json /app
COPY test.js /app
  1. 构建映像并运行它 确保使用自定义标签不是最新的(为方便起见)。
docker build -f dockerfile -t express-app:local . 
docker run -dit --name express express-app:local

docker ps 
## check container's running 

执行容器的 bin/sh 并检查应用程序是否具有包,test.js

docker exec -it express /bin/sh
# ls
package.json  test.js
# pwd
/app
  1. 现在从映像构建 docker-compose

为了不混淆应用程序,我将另一个挂载卷更改为已加载

version: '3'

services:
  mycustom:
    container_name: mycustom
    image: express-app:local
    volumes:
      - ./loaded:/app/loaded
    command: "tail -f /dev/null"
  1. 检查容器包含文件夹和 test.js、package.json
docker-compose -f docker-copmose.yaml up 
// go to another terminal
docker exec -it mycustom /bin/sh

docker exec -it mycustom /bin/sh

# pwd
/app
# ls
loaded  package.json  test.js

评论

0赞 Mustafa Tunahan Tuna 11/18/2023
docker 镜像没有问题。当我运行“docker run -p 3000:3000 express-app:latest”时,cantainer 工作正常。我的问题是我无法将workdir中的文件挂载到本地文件
0赞 Jeong Yo Han 11/18/2023
test-app-express-app-1 | npm ERR! path /app/package.json test-app-express-app-1 | npm ERR! errno -2 test-app-express-app-1 | npm ERR! enoent ENOENT: no such file or directory, open '/app/package.json'您的日志显示容器内没有文件。
0赞 Mustafa Tunahan Tuna 11/18/2023
我的目标是使用 Docker 创建一个映像。我成功创建了这个映像,有了这个映像,我可以在不分配卷的情况下创建一个容器并成功使用它。我无法将我使用 docker compose 创建的卷连接到本地文件夹,文件没有来。Jeong Yo Han先生,你能在自己的电脑上试试我的源代码吗?我相信你会得到同样的错误。
0赞 Jeong Yo Han 11/19/2023
@MustafaTunahanTuna我更新了我的答案
0赞 Mustafa Tunahan Tuna 11/19/2023
感谢您的回复。您显示的方法有效。至少是你想做的方式。它将名为 loaded 的文件夹连接到容器。我想问你以下问题:我可以将容器中的文件传输到我的本地文件夹吗,例如将“test.js、package.json、node_modules”文件链接到我目录中的 test 文件夹。
0赞 Jeong Yo Han 11/19/2023
@MustafaTunahanTuna你的意思是.. 或者您只想在主机上挂载容器的卷而不将其替换为主机卷??docker cp