为 NodeJS + PostgreSQL Web 应用程序创建 Docker 映像
Posted
技术标签:
【中文标题】为 NodeJS + PostgreSQL Web 应用程序创建 Docker 映像【英文标题】:Create Docker image for NodeJS + PostgreSQL web application 【发布时间】:2016-08-21 01:46:38 【问题描述】:我一直在阅读 Docker 的文档,但无法创建一个可以工作的镜像。
我有一个使用 PostgreSQL 作为数据库的 NodeJS 应用程序:
var connectionString = process.env.DATABASE_URL || 'postgres://localhost:5432/db';
var pg = require('pg');
var pgp = require('pg-promise')();
var db = pgp(connectionString);
db.func('some_storedProcedure').then(//...)
//...
我先根据Node's documentation为它创建了一个Dockerfile:
FROM node:argon
# Create app directory
RUN mkdir -p /app
WORKDIR /app
# Install app dependencies
COPY package.json /app
RUN npm install
# Bundle app source
COPY . /app
EXPOSE 5000
CMD [ "npm", "start" ]
然后我关注this post 使用 docker-compose 将数据库连接到它。 docker-compose.yml
文件看起来像:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/app
links:
- db
environment:
DATABASE_URL: postgres://myuser:mypass@db:5432/db
db:
image: postgres
environment:
POSTGRES_USER: myuser
POSTGRES_PASSWORD: mypass
这是创建图像后使用这些文件运行 docker-compose up
时返回的(部分)内容。
npm info ok
---> 87dbbae35721
Removing intermediate container c73f826a0b3d
Step 6 : COPY . /app
---> ec56bfc11d3c
Removing intermediate container 745ddf82d742
Step 7 : EXPOSE 5000
---> Running in b2be5aecd9d6
---> a7d126a7ea5e
Removing intermediate container b2be5aecd9d6
Step 8 : CMD npm start
---> Running in 0379d512c688
---> 266517f47311
Removing intermediate container 0379d512c688
Successfully built 266517f47311
WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Starting imagename_db_1
Creating imagename_web_1
Attaching to imagename_db_1, imagename_web_1
web_1 | npm info it worked if it ends with ok
web_1 | npm info using npm@2.15.1
web_1 | npm info using node@v4.4.3
web_1 | npm info prestart SharedServer@5.8.0
web_1 | npm info start SharedServer@5.8.0
web_1 |
web_1 | > SharedServer@5.8.0 start /app
web_1 | > node index.js
web_1 |
web_1 | Wed, 27 Apr 2016 00:41:19 GMT body-parser deprecated bodyParser: use individual json/urlencoded middlewares at index.js:13:9
web_1 | Wed, 27 Apr 2016 00:41:19 GMT body-parser deprecated undefined extended: provide extended option at node_modules/body-parser/index.js:105:29
web_1 | Node app is running on port 5000
db_1 | LOG: database system was interrupted; last known up at 2016-04-25 00:17:59 UTC
db_1 | LOG: database system was not properly shut down; automatic recovery in progress
db_1 | LOG: invalid record length at 0/17076E8
db_1 | LOG: redo is not required
db_1 | LOG: MultiXact member wraparound protections are now enabled
db_1 | LOG: database system is ready to accept connections
db_1 | LOG: autovacuum launcher started
当我访问 http://localhost:5000 时,我看到 Web 应用程序正在运行,但每当我启动尝试访问数据库的东西时,我都会收到 HTTP 500 错误,正文如下
code: "28P01"
file: "auth.c"
length: 98
line: "285"
name: "error"
routine: "auth_failed"
severity: "FATAL"
我做错了什么?我不确定我是否了解我在使用 Docker 做什么,我唯一的文档是构建特定环境的简单配方(或者至少,这是我所理解的)
谢谢。
【问题讨论】:
该错误表明您对数据库服务器的身份验证详细信息失败。您可以从您的应用程序成功连接到服务器吗?你可以检查这个:***.com/questions/36120435/…。如果运气不好,你可以试试这个:***.com/questions/35807792/…。此外,当您已经获得pg-promise
时,您不需要包含 pg
;)
@vitaly:如果我在我的主机系统中运行我的应用程序,我完全没有连接问题。它正在通过引发此问题的图像运行应用程序
可能是 docker 配置的问题。您没有指定数据库端口,可能是您的用户名或密码错误。
5000 是 node.js 应用程序端口,对吧?您是否构建了 postgres 数据库 docker,它是否正在侦听 5432 端口?
@ThanhNguyenVan:不,我认为 PostgreSQL 已经使用 docker-compose 安装在映像中
【参考方案1】:
检查 $PGDATA 中的 pg_hba.conf 是否允许来自 node.js 的连接。
默认情况下 pg_hba.conf 是这样的:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
这对于通过操作系统所有者的标准 psql 连接来说很好,因为它允许本地连接受信任的本地连接 IP 地址 127.0.0.1。但是,如果您在服务器上设置了 IP 地址,我猜您这样做了,那么您需要允许一个条目,因为在您的 node.js 配置中,您指的是“DB”主机。因此 ping "DB" 并添加该 IP 地址:
# TYPE DATABASE USER ADDRESS METHOD
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
host db myuser <ip-for-db-host> md5
更改该文件后,您需要执行 pg_ctl 重新加载。
【讨论】:
如何在图像中检查?例如,在 Ubuntu 中安装 PostgreSQL 时,配置文件的路径是否与我可以找到的路径相同? 是的,一旦您使用 initdb 创建了一个实例,pg_hba.conf 始终位于数据目录中。默认情况下,如果你没有明确告诉它安装在哪里,它可能会在 /var/lib/pgsql-9.5/data 之类的地方。以上是关于为 NodeJS + PostgreSQL Web 应用程序创建 Docker 映像的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 PostgreSQL 将数据从 AngularJS 前端传递到 Nodejs 后端?
NodeJS,将来自 MySQL 和 PostgreSQL 的数据存储在 SQLite 中
nodejs之我的开源module 使用express搭建web服务器,代码即文档的实现。