Docker+PostgreSQL报错ENOENT:找不到/run/secrets/db-password文件求助
问题描述
跟随Docker官方Node.js容器化教程操作,执行docker compose up --build命令时出现ENOENT错误:找不到/run/secrets/db-password文件。已按教程在项目根目录创建db文件夹及其中的password.txt文件,但问题仍存在。
环境信息
操作系统
Linux Mint 21.2 Cinnamon
Docker版本
Client: Docker Engine - Community Version: 24.0.7 Context: desktop-linux
错误日志
[+] Running 2/0 ✔ Container docker-nodejs-sample-db-1 Created 0.0s ✔ Container docker-nodejs-sample-server-1 Created 0.0s Attaching to docker-nodejs-sample-db-1, docker-nodejs-sample-server-1 docker-nodejs-sample-db-1 | docker-nodejs-sample-db-1 | PostgreSQL Database directory appears to contain a database; Skipping initialization docker-nodejs-sample-db-1 | docker-nodejs-sample-db-1 | 2023-11-13 08:37:09.857 UTC [1] LOG: starting PostgreSQL 16.0 (Debian 16.0-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit docker-nodejs-sample-db-1 | 2023-11-13 08:37:09.857 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432 docker-nodejs-sample-db-1 | 2023-11-13 08:37:09.857 UTC [1] LOG: listening on IPv6 address "::", port 5432 docker-nodejs-sample-db-1 | 2023-11-13 08:37:09.859 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432" docker-nodejs-sample-db-1 | 2023-11-13 08:37:09.864 UTC [16] LOG: database system was shut down at 2023-11-13 08:35:29 UTC docker-nodejs-sample-db-1 | 2023-11-13 08:37:09.868 UTC [1] LOG: database system is ready to accept connections docker-nodejs-sample-server-1 | Error: ENOENT: no such file or directory, open '/run/secrets/db-password' docker-nodejs-sample-server-1 | at Object.openSync (node:fs:603:3) docker-nodejs-sample-server-1 | at Object.readFileSync (node:fs:471:35) docker-nodejs-sample-server-1 | at Object.init (/usr/src/app/src/persistence/postgres.js:21:41) docker-nodejs-sample-server-1 | at Object.<anonymous> (/usr/src/app/src/index.js:17:4) docker-nodejs-sample-server-1 | at Module._compile (node:internal/modules/cjs/loader:1256:14) docker-nodejs-sample-server-1 | at Module._extensions..js (node:internal/modules/cjs/loader:1310:10) docker-nodejs-sample-server-1 | at Module.load (node:internal/modules/cjs/loader:1119:32) docker-nodejs-sample-server-1 | at Module._load (node:internal/modules/cjs/loader:960:12) docker-nodejs-sample-server-1 | at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:86:12) docker-nodejs-sample-server-1 | at node:internal/main/run_main_module:23:47 { docker-nodejs-sample-server-1 | errno: -2, docker-nodejs-sample-server-1 | syscall: 'open', docker-nodejs-sample-server-1 | code: 'ENOENT', docker-nodejs-sample-server-1 | path: '/run/secrets/db-password' docker-nodejs-sample-server-1 | } docker-nodejs-sample-server-1 exited with code 1 docker-nodejs-sample-db-1 | 2023-11-13 08:42:10.000 UTC [14] LOG: checkpoint starting: time docker-nodejs-sample-db-1 | 2023-11-13 08:42:10.025 UTC [14] LOG: checkpoint complete: wrote 3 buffers (0.0%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.006 s, sync=0.002 s, total=0.025 s; sync files=2, longest=0.001 s, average=0.001 s; distance=0 kB, estimate=0 kB; lsn=0/1954D78, redo lsn=0/1954D40
配置文件
Dockerfile
# syntax=docker/dockerfile:1 # Comments are provided throughout this file to help you get started. # If you need more help, visit the Dockerfile reference guide at # https://docs.docker.com/engine/reference/builder/ ARG NODE_VERSION=18.18.2 FROM node:${NODE_VERSION}-alpine # Use production node environment by default. ENV NODE_ENV production WORKDIR /usr/src/app # Download dependencies as a separate step to take advantage of Docker's caching. # Leverage a cache mount to /root/.npm to speed up subsequent builds. # Leverage a bind mounts to package.json and package-lock.json to avoid having to copy them into # into this layer. RUN --mount=type=bind,source=package.json,target=package.json \ --mount=type=bind,source=package-lock.json,target=package-lock.json \ --mount=type=cache,target=/root/.npm \ npm ci --omit=dev # Run the application as a non-root user. USER node # Copy the rest of the source files into the image. COPY . . # Expose the port that the application listens on. EXPOSE 3000 # Run the application. CMD node src/index.js
compose.yaml
services: server: build: context: . environment: NODE_ENV: production POSTGRES_HOST: db POSTGRES_USER: postgres POSTGRES_PASSWORD_FILE: /run/secrets/db-password POSTGRES_DB: example ports: - 3000:3000 depends_on: db: condition: service_healthy db: image: postgres restart: always user: postgres secrets: - db-password volumes: - db-data:/var/lib/postgresql/data environment: - POSTGRES_DB=example - POSTGRES_PASSWORD_FILE=/run/secrets/db-password expose: - 5432 healthcheck: test: [ "CMD", "pg_isready" ] interval: 10s timeout: 5s retries: 5 volumes: db-data: secrets: db-password: file: db/password.txt
解决方案
问题出在server服务没有配置secrets挂载。虽然你在compose.yaml里定义了全局的db-password密钥,并且给db服务挂载了这个密钥,但server服务并没有挂载,导致其容器内不存在/run/secrets/db-password文件,而你的Node.js代码又在尝试读取这个文件。
修改compose.yaml,给server服务添加secrets字段:
services: server: build: context: . environment: NODE_ENV: production POSTGRES_HOST: db POSTGRES_USER: postgres POSTGRES_PASSWORD_FILE: /run/secrets/db-password POSTGRES_DB: example ports: - 3000:3000 depends_on: db: condition: service_healthy secrets: - db-password db: image: postgres restart: always user: postgres secrets: - db-password volumes: - db-data:/var/lib/postgresql/data environment: - POSTGRES_DB=example - POSTGRES_PASSWORD_FILE=/run/secrets/db-password expose: - 5432 healthcheck: test: [ "CMD", "pg_isready" ] interval: 10s timeout: 5s retries: 5 volumes: db-data: secrets: db-password: file: db/password.txt
修改后重新执行docker compose up --build即可。
另外可以做以下额外检查:
- 确认
db/password.txt文件确实存在于项目根目录,且文件路径没有拼写错误 - 确保
password.txt文件有可读权限(可以执行chmod 644 db/password.txt调整权限)
内容的提问来源于stack exchange,提问作者Elom Atsou Agboka
相关产品推荐
相关产品推荐

