You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker Compose中运行Sequelize迁移失败及容器问题求助

解决方案:修复Node+Postgres容器的权限与数据库连接问题

咱们一步步来解决你遇到的两个核心问题:


问题1:修复chmod: /docker-entrypoint.sh: Operation not permitted错误

这个问题的根源是你切换到node用户后,没有权限修改根目录/下的文件。Docker镜像的根目录默认属于root用户,node作为普通用户无法修改这里的文件。

调整后的Dockerfile(两种可行方案)

方案1:把脚本放到node用户有权限的目录

FROM node:lts-alpine
RUN mkdir -p /home/node/api/node_modules && chown -R node:node /home
WORKDIR /home/node/api

# 先复制脚本到node用户的工作目录
COPY ./docker-entrypoint.sh ./
COPY package.json ./

# 切换到node用户后,再给脚本加执行权限(工作目录属于node,有权限操作)
USER node
RUN npm i
RUN chmod +x docker-entrypoint.sh

COPY --chown=node:node . .
EXPOSE 3000
ENTRYPOINT ["./docker-entrypoint.sh"]

方案2:切换用户前完成脚本权限配置

FROM node:lts-alpine
RUN mkdir -p /home/node/api/node_modules && chown -R node:node /home
WORKDIR /home/node/api

COPY ./docker-entrypoint.sh /docker-entrypoint.sh
# 还在root用户时,先给脚本加权限
RUN chmod +x /docker-entrypoint.sh

COPY package.json ./
USER node
RUN npm i
COPY --chown=node:node . .

EXPOSE 3000
ENTRYPOINT ["/docker-entrypoint.sh"]

问题2:修复getaddrinfo ENOTFOUND postgres数据库连接错误

这个错误有两个触发原因,咱们逐一解决:

原因1:Sequelize配置的数据库主机名错误

Docker容器之间通过服务名通信,你的docker-compose.yml里Postgres服务名叫postgres-app,但Sequelize配置里写的是postgres,导致找不到主机。

修改你的src/config/database.js(development环境):

module.exports = {
  development: {
    username: process.env.DB_USER,
    password: process.env.DB_PASS,
    database: process.env.DATABASE,
    host: 'postgres-app', // 这里必须和docker-compose里的服务名一致
    dialect: 'postgres'
  }
}

原因2:数据库容器未完全就绪就执行迁移

depends_on只是保证Postgres容器先启动,但Postgres服务需要时间完成初始化。咱们需要在entrypoint脚本里加等待逻辑,确保数据库能正常连接后再执行迁移。

修改后的docker-entrypoint.sh(带等待逻辑)

#!/bin/sh
# 等待Postgres服务就绪(需要先安装postgres客户端工具)
until pg_isready -h postgres-app -U ${DB_USER}; do
  echo "Waiting for Postgres to start..."
  sleep 2
done

# 执行数据库迁移
npx sequelize-cli db:migrate
# 启动开发服务
npm run dev

补充:安装Postgres客户端工具

在Dockerfile里加入(切换到root用户安装,再切回node):

# 加入到USER node之前
USER root
RUN apk add --no-cache postgresql-client
USER node

替代方案:用Netcat等待端口(如果不想装Postgres客户端)

修改entrypoint脚本:

#!/bin/sh
# 等待5432端口开放
until nc -z postgres-app 5432; do
  echo "Waiting for Postgres port 5432..."
  sleep 2
done

npx sequelize-cli db:migrate
npm run dev

同时Dockerfile里安装Netcat:

USER root
RUN apk add --no-cache netcat-openbsd
USER node

额外配置:确保环境变量传递到Node容器

在docker-compose.yml的app-app服务里添加环境变量,让Sequelize能读取到数据库配置:

services:
  app-app:
    container_name: app-app
    build: '.'
    volumes:
      - .:/home/node/api
      - /home/node/api/node_modules
    depends_on:
      - postgres-app
    networks:
      - app-connect
    ports:
      - '3000:3000'
    # 新增:传递环境变量
    environment:
      - NODE_ENV=development
      - DATABASE=${DATABASE}
      - DB_USER=${DB_USER}
      - DB_PASS=${DB_PASS}

内容的提问来源于stack exchange,提问作者Develop_SP

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 08:27:46