Node.js 容器无法自动访问 postgres 容器
Node.js container is unable to access postgres container automatically
所以,我一直在尝试为我的“项目”创建一个 docker,它使用的是一个没有阶段和 docker-compose 的简单 docker 文件。但是,现在我正在尝试使用阶段,我认为我的更改不应该像这样影响项目。
当我用 docker-compose -f ./docker-compose.dev.yml up --build -d
构建 docker 时,所有 3 个服务都会启动,但是包含节点内容的 Web 服务会尝试执行我的 yarn migration:run
命令,该命令仅有效在第一次尝试中,之后我得到的是:
PS C:\Users\joaov\Documents\gittin> docker logs web-dev
[INFO wait] --------------------------------------------------------
[INFO wait] docker-compose-wait 2.9.0
[INFO wait] ---------------------------
[DEBUG wait] Starting with configuration:
[DEBUG wait] - Hosts to be waiting for: []
[DEBUG wait] - Paths to be waiting for: []
[DEBUG wait] - Timeout before failure: 30 seconds
[DEBUG wait] - TCP connection timeout before retry: 5 seconds
[DEBUG wait] - Sleeping time before checking for hosts/paths availability: 0 seconds
[DEBUG wait] - Sleeping time once all hosts/paths are available: 0 seconds
[DEBUG wait] - Sleeping time between retries: 1 seconds
[DEBUG wait] --------------------------------------------------------
[INFO wait] docker-compose-wait - Everything's fine, the application can now start!
[INFO wait] --------------------------------------------------------
yarn run v1.22.5
$ ts-node-dev ./node_modules/typeorm/cli.js migration:run
[INFO] 23:26:05 ts-node-dev ver. 1.1.6 (using ts-node ver. 9.1.1, typescript ver. 4.3.4)
Error during migration run:
Error: connect ECONNREFUSED 172.18.0.2:5432
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1148:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '172.18.0.2',
port: 5432
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
PS C:\Users\joaov\Documents\gittin>
现在 node.js 应用程序不是 运行ning 因为容器已停止,但如果我 运行 docker start web-dev
,我会从日志中得到:
[INFO wait] --------------------------------------------------------
[INFO wait] docker-compose-wait 2.9.0
[INFO wait] ---------------------------
[DEBUG wait] Starting with configuration:
[DEBUG wait] - Hosts to be waiting for: []
[DEBUG wait] - Paths to be waiting for: []
[DEBUG wait] - Timeout before failure: 30 seconds
[DEBUG wait] - TCP connection timeout before retry: 5 seconds
[DEBUG wait] - Sleeping time before checking for hosts/paths availability: 0 seconds
[DEBUG wait] - Sleeping time once all hosts/paths are available: 0 seconds
[DEBUG wait] - Sleeping time between retries: 1 seconds
[DEBUG wait] --------------------------------------------------------
[INFO wait] docker-compose-wait - Everything's fine, the application can now start!
[INFO wait] --------------------------------------------------------
yarn run v1.22.5
$ ts-node-dev ./node_modules/typeorm/cli.js migration:run
[INFO] 23:29:24 ts-node-dev ver. 1.1.6 (using ts-node ver. 9.1.1, typescript ver. 4.3.4)
query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = current_schema() AND "table_name" = 'migrations'
query: CREATE TABLE "migrations" ("id" SERIAL NOT NULL, "timestamp" bigint NOT NULL, "name" character varying NOT NULL, CONSTRAINT "PK_8c82d7f526340ab734260ea46be" PRIMARY KEY ("id"))
query: SELECT * FROM "migrations" "migrations" ORDER BY "id" DESC
0 migrations are already loaded in the database.
1 migrations were found in the source code.
1 migrations are new migrations that needs to be executed.
query: START TRANSACTION
query: CREATE TABLE "users" ("id" uuid NOT NULL, "name" varchar NOT NULL, "email" varchar NOT NULL, "password" varchar NOT NULL, "admin" boolean NOT NULL DEFAULT false, "created_at" timestamp NOT NULL DEFAULT now(), "updated_at" timestamp NOT NULL DEFAULT now(), CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))
query: INSERT INTO "migrations"("timestamp", "name") VALUES (, ) -- PARAMETERS: [1623957922252,"CreateUsers1623957922252"]
Migration CreateUsers1623957922252 has been executed successfully.
query: COMMIT
Done in 1.23s.
yarn run v1.22.5
$ ts-node-dev ./src/index.ts
[INFO] 23:29:25 ts-node-dev ver. 1.1.6 (using ts-node ver. 9.1.1, typescript ver. 4.3.4)
PS C:\Users\joaov\Documents\gittin>
有了它,我们可以看到连接有效,但是在构建 docker 图像时第一次尝试时它不起作用...
为了说清楚,我会把一些我认为有用的代码直接留在这里,并分享github存储库。
Github: https://github.com/joaocasarin/gittin
Package.json 脚本:
"scripts": {
"docker:dev": "docker-compose -f ./docker-compose.dev.yml up --build -d",
"docker:prod": "docker-compose -f ./docker-compose.yml up --build -d",
"docker:clear": "docker-compose down",
"dev": "ts-node-dev ./src/index.ts",
"test": "jest",
"migration:run": "ts-node-dev ./node_modules/typeorm/cli.js migration:run",
"migration:create": "ts-node-dev ./node_modules/typeorm/cli.js migration:create",
"entity:create": "ts-node-dev ./node_modules/typeorm/cli.js entity:create",
"build": "tsc",
"start": "node ."
}
可以看到node容器启动的时候,等待DB,运行 migration:run 运行 yarn dev
ts-node-dev启动.
ormconfig.js:
module.exports = {
"type": "postgres",
"ssl": process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
"url": process.env.DATABASE_URL,
"entities": ["dist/entities/*.js"], // typeorm loads entities from this directory
"migrations": ["dist/database/migrations/*.js"], // typeorm loads migrations from the directory
"cli": {
"migrationsDir": "src/database/migrations", // typeorm creates migrations in this directory
"entitiesDir": "src/entities" // typeorm creates entities in this directory
}
}
Dockerfile.dev:
FROM node:14-alpine as base
WORKDIR /usr/app
COPY package.json yarn.lock jest.config.ts tsconfig.json ormconfig.js ./
COPY src ./src
# used for waiting while database container is running to continue with node stuffs
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.9.0/wait /wait
RUN chmod +x /wait
RUN yarn install
RUN yarn build
FROM base as dev
WORKDIR /usr/app
ENV NODE_ENV=development
COPY --from=base /usr/app/dist/database/migrations ./
CMD /wait && yarn migration:run && yarn dev
EXPOSE 3000
docker-compose.dev.yml:
version: "3.8"
services:
web:
container_name: web-dev
build:
context: .
dockerfile: Dockerfile.dev
depends_on:
- db
ports:
- ${PORT}:${PORT}
environment:
DATABASE_URL: ${DATABASE_URL}
NODE_ENV: ${NODE_ENV}
PORT: ${PORT}
db:
container_name: db-dev
image: postgres:13.3-alpine
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: docker
POSTGRES_DB: gittin
ports:
- 5432:5432
volumes:
- ./postgres-dev:/var/lib/postgresql/data
pgadmin:
container_name: pgadmin-dev
image: dpage/pgadmin4:5.5
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: db@db.com
PGADMIN_DEFAULT_PASSWORD: docker
PGADMIN_PORT: 80
ports:
- 8080:80
volumes:
- pgadmin-data-dev:/var/lib/pgadmin
depends_on:
- db
volumes:
db-data:
pgadmin-data-dev:
.env:
PORT=3000
NODE_ENV=development
DATABASE_URL=postgres://postgres:docker@db:5432/gittin
如果需要请问任何问题,我真的很想知道如何解决这个问题,并且如果可能的话,请提供有关如何编写 docker 文件和 docker-compose 文件的任何建议我可以做些什么让它变得更好。
谢谢
我发现了部分问题,而不是 Dockerfile.dev,在 EXPOSE 3000
之前的 CMD
指令中,我改为 CMD \wait && yarn dev
,删除了 yarn migration:run
并且应用程序可以成功初始化,但现在我遇到了这个问题,即 docker 没有 运行 我的迁移。
现在文件是:
FROM node:14-alpine as base
WORKDIR /usr/app
COPY package.json yarn.lock jest.config.ts tsconfig.json ormconfig.js ./
COPY src ./src
# used for waiting while database container is running to continue with node stuffs
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.9.0/wait /wait
RUN chmod +x /wait
RUN yarn install
RUN yarn build
FROM base as dev
WORKDIR /usr/app
ENV NODE_ENV=development
COPY --from=base /usr/app/dist/database/migrations ./
CMD /wait && yarn dev
EXPOSE 3000
所以,我一直在尝试为我的“项目”创建一个 docker,它使用的是一个没有阶段和 docker-compose 的简单 docker 文件。但是,现在我正在尝试使用阶段,我认为我的更改不应该像这样影响项目。
当我用 docker-compose -f ./docker-compose.dev.yml up --build -d
构建 docker 时,所有 3 个服务都会启动,但是包含节点内容的 Web 服务会尝试执行我的 yarn migration:run
命令,该命令仅有效在第一次尝试中,之后我得到的是:
PS C:\Users\joaov\Documents\gittin> docker logs web-dev
[INFO wait] --------------------------------------------------------
[INFO wait] docker-compose-wait 2.9.0
[INFO wait] ---------------------------
[DEBUG wait] Starting with configuration:
[DEBUG wait] - Hosts to be waiting for: []
[DEBUG wait] - Paths to be waiting for: []
[DEBUG wait] - Timeout before failure: 30 seconds
[DEBUG wait] - TCP connection timeout before retry: 5 seconds
[DEBUG wait] - Sleeping time before checking for hosts/paths availability: 0 seconds
[DEBUG wait] - Sleeping time once all hosts/paths are available: 0 seconds
[DEBUG wait] - Sleeping time between retries: 1 seconds
[DEBUG wait] --------------------------------------------------------
[INFO wait] docker-compose-wait - Everything's fine, the application can now start!
[INFO wait] --------------------------------------------------------
yarn run v1.22.5
$ ts-node-dev ./node_modules/typeorm/cli.js migration:run
[INFO] 23:26:05 ts-node-dev ver. 1.1.6 (using ts-node ver. 9.1.1, typescript ver. 4.3.4)
Error during migration run:
Error: connect ECONNREFUSED 172.18.0.2:5432
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1148:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '172.18.0.2',
port: 5432
}
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
PS C:\Users\joaov\Documents\gittin>
现在 node.js 应用程序不是 运行ning 因为容器已停止,但如果我 运行 docker start web-dev
,我会从日志中得到:
[INFO wait] --------------------------------------------------------
[INFO wait] docker-compose-wait 2.9.0
[INFO wait] ---------------------------
[DEBUG wait] Starting with configuration:
[DEBUG wait] - Hosts to be waiting for: []
[DEBUG wait] - Paths to be waiting for: []
[DEBUG wait] - Timeout before failure: 30 seconds
[DEBUG wait] - TCP connection timeout before retry: 5 seconds
[DEBUG wait] - Sleeping time before checking for hosts/paths availability: 0 seconds
[DEBUG wait] - Sleeping time once all hosts/paths are available: 0 seconds
[DEBUG wait] - Sleeping time between retries: 1 seconds
[DEBUG wait] --------------------------------------------------------
[INFO wait] docker-compose-wait - Everything's fine, the application can now start!
[INFO wait] --------------------------------------------------------
yarn run v1.22.5
$ ts-node-dev ./node_modules/typeorm/cli.js migration:run
[INFO] 23:29:24 ts-node-dev ver. 1.1.6 (using ts-node ver. 9.1.1, typescript ver. 4.3.4)
query: SELECT * FROM "information_schema"."tables" WHERE "table_schema" = current_schema() AND "table_name" = 'migrations'
query: CREATE TABLE "migrations" ("id" SERIAL NOT NULL, "timestamp" bigint NOT NULL, "name" character varying NOT NULL, CONSTRAINT "PK_8c82d7f526340ab734260ea46be" PRIMARY KEY ("id"))
query: SELECT * FROM "migrations" "migrations" ORDER BY "id" DESC
0 migrations are already loaded in the database.
1 migrations were found in the source code.
1 migrations are new migrations that needs to be executed.
query: START TRANSACTION
query: CREATE TABLE "users" ("id" uuid NOT NULL, "name" varchar NOT NULL, "email" varchar NOT NULL, "password" varchar NOT NULL, "admin" boolean NOT NULL DEFAULT false, "created_at" timestamp NOT NULL DEFAULT now(), "updated_at" timestamp NOT NULL DEFAULT now(), CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))
query: INSERT INTO "migrations"("timestamp", "name") VALUES (, ) -- PARAMETERS: [1623957922252,"CreateUsers1623957922252"]
Migration CreateUsers1623957922252 has been executed successfully.
query: COMMIT
Done in 1.23s.
yarn run v1.22.5
$ ts-node-dev ./src/index.ts
[INFO] 23:29:25 ts-node-dev ver. 1.1.6 (using ts-node ver. 9.1.1, typescript ver. 4.3.4)
PS C:\Users\joaov\Documents\gittin>
有了它,我们可以看到连接有效,但是在构建 docker 图像时第一次尝试时它不起作用...
为了说清楚,我会把一些我认为有用的代码直接留在这里,并分享github存储库。
Github: https://github.com/joaocasarin/gittin
Package.json 脚本:
"scripts": {
"docker:dev": "docker-compose -f ./docker-compose.dev.yml up --build -d",
"docker:prod": "docker-compose -f ./docker-compose.yml up --build -d",
"docker:clear": "docker-compose down",
"dev": "ts-node-dev ./src/index.ts",
"test": "jest",
"migration:run": "ts-node-dev ./node_modules/typeorm/cli.js migration:run",
"migration:create": "ts-node-dev ./node_modules/typeorm/cli.js migration:create",
"entity:create": "ts-node-dev ./node_modules/typeorm/cli.js entity:create",
"build": "tsc",
"start": "node ."
}
可以看到node容器启动的时候,等待DB,运行 migration:run 运行 yarn dev
ts-node-dev启动.
ormconfig.js:
module.exports = {
"type": "postgres",
"ssl": process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false,
"url": process.env.DATABASE_URL,
"entities": ["dist/entities/*.js"], // typeorm loads entities from this directory
"migrations": ["dist/database/migrations/*.js"], // typeorm loads migrations from the directory
"cli": {
"migrationsDir": "src/database/migrations", // typeorm creates migrations in this directory
"entitiesDir": "src/entities" // typeorm creates entities in this directory
}
}
Dockerfile.dev:
FROM node:14-alpine as base
WORKDIR /usr/app
COPY package.json yarn.lock jest.config.ts tsconfig.json ormconfig.js ./
COPY src ./src
# used for waiting while database container is running to continue with node stuffs
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.9.0/wait /wait
RUN chmod +x /wait
RUN yarn install
RUN yarn build
FROM base as dev
WORKDIR /usr/app
ENV NODE_ENV=development
COPY --from=base /usr/app/dist/database/migrations ./
CMD /wait && yarn migration:run && yarn dev
EXPOSE 3000
docker-compose.dev.yml:
version: "3.8"
services:
web:
container_name: web-dev
build:
context: .
dockerfile: Dockerfile.dev
depends_on:
- db
ports:
- ${PORT}:${PORT}
environment:
DATABASE_URL: ${DATABASE_URL}
NODE_ENV: ${NODE_ENV}
PORT: ${PORT}
db:
container_name: db-dev
image: postgres:13.3-alpine
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: docker
POSTGRES_DB: gittin
ports:
- 5432:5432
volumes:
- ./postgres-dev:/var/lib/postgresql/data
pgadmin:
container_name: pgadmin-dev
image: dpage/pgadmin4:5.5
restart: always
environment:
PGADMIN_DEFAULT_EMAIL: db@db.com
PGADMIN_DEFAULT_PASSWORD: docker
PGADMIN_PORT: 80
ports:
- 8080:80
volumes:
- pgadmin-data-dev:/var/lib/pgadmin
depends_on:
- db
volumes:
db-data:
pgadmin-data-dev:
.env:
PORT=3000
NODE_ENV=development
DATABASE_URL=postgres://postgres:docker@db:5432/gittin
如果需要请问任何问题,我真的很想知道如何解决这个问题,并且如果可能的话,请提供有关如何编写 docker 文件和 docker-compose 文件的任何建议我可以做些什么让它变得更好。
谢谢
我发现了部分问题,而不是 Dockerfile.dev,在 EXPOSE 3000
之前的 CMD
指令中,我改为 CMD \wait && yarn dev
,删除了 yarn migration:run
并且应用程序可以成功初始化,但现在我遇到了这个问题,即 docker 没有 运行 我的迁移。
现在文件是:
FROM node:14-alpine as base
WORKDIR /usr/app
COPY package.json yarn.lock jest.config.ts tsconfig.json ormconfig.js ./
COPY src ./src
# used for waiting while database container is running to continue with node stuffs
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.9.0/wait /wait
RUN chmod +x /wait
RUN yarn install
RUN yarn build
FROM base as dev
WORKDIR /usr/app
ENV NODE_ENV=development
COPY --from=base /usr/app/dist/database/migrations ./
CMD /wait && yarn dev
EXPOSE 3000