node.js - Typrom postgres 与 typescript 和 docker 的连接
问题描述
我正在尝试在我的节点项目中使用 typeorm。所以数据库是通过 docker 启动的。现在,当容器停止并重新启动时,ip 不断变化,因此更好的可能性是在我的配置中使用容器名称。
现在真正的混乱开始了,所以我尝试使用 env 变量配置连接选项,它似乎无法解析主机(当作为 docker 容器给出时)。
这是我的示例 .env 文件
TYPEORM_HOST=postgres-container
TYPEORM_POSTGRES_USERNAME=postgres
TYPEORM_POSTGRES_PASSWORD=XXXXXX
TYPEORM_TYPE=postgres
TYPEORM_LOGGING=true
TYPEORM_SYNCHRONIZE=true
TYPEORM_DATABASE=XXXXX
PINO_ENABLE_LOGGING= true
当我尝试在我的应用程序中使用它时,这引发了一个错误,指出无法找到主机并因此恢复为 ip 并且它可以工作
const databaseConfigParams = DatabaseConfigInstance.getConnectionParams();
......
try {
const connec = await createConnection({
name: DB_CONNECTION_NAME,
type: DatabaseConnectionEnum.POSTGRES,
host: databaseConfigParams.getHost(),
port: parseInt(databaseConfigParams.getPort()),
username: databaseConfigParams.getUsername(),
password: databaseConfigParams.getPassword(),
database: databaseConfigParams.getDatabase(),
logging: databaseConfigParams.isLogging(),
synchronize: databaseConfigParams.isSynchronize(),
entities: [XXXEntity, XXEntity, XXXEntity]
});
res(connec);
} catch (err){
console.log('error in creating connection:', err);
rej(err);
}
现在,如果将配置作为环境变量提供,则无法解析容器名称,因此我决定将配置移至 ormconfig.js 文件。
现在我可以在哪里指定要使用的实体?. 由于我使用 webpack 来捆绑我的应用程序,因此即使捆绑了应用程序,我也需要识别实体。
这是我的 webpack 配置
const path = require('path');
const webpack = require('webpack');
const nodeExternals = require('webpack-node-externals');
const dotEnvPlugin = require('dotenv-webpack');
const TerserPlugin = require('terser-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
'use strict';
module.exports = {
entry: './src/app/server.ts',
mode: 'development',
optimization: {
minimizer: [
new UglifyJsPlugin({
uglifyOptions: {
keep_classnames: true,
keep_fnames: true
}
})
],
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js'
},
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: [
'ts-loader',
]
},
{
test: /\.handlebars$/,
loader: 'handlebars-loader',
options: {
knownHelpersOnly: false,
inlineRequires: /\/assets\/(:?images|audio|video)\//ig,
partialDirs: [path.join(__dirname, './src/views/email/partials')],
},
}
]
},
externals: [ nodeExternals() ],
plugins: [
new dotEnvPlugin({
path: './config/development/.env',
safe: true,
systemvars: true,
silent: true,
defaults: false
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': 'development',
'process.env.DEBUG': 'false'
}),
// need this plugin for the maps to be generated
new webpack.EvalSourceMapDevToolPlugin({
filename: '[name].map.js'
}),
new webpack.WatchIgnorePlugin([
path.join(__dirname, "node_modules")
]),
]
};
编辑:
我尝试在 oemconfig.js 中使用指定实体。它适用于 ts-node 编译,但不适用于 webpack。
module.exports = {
name: 'postgresConnection',
type: 'postgres',
host: '172.17.0.3',
port: 5432,
username: 'postgres',
password: 'XXX',
database: 'XXX',
synchronize: true,
logging: true,
"entities": [
"src/app/modules/database/entities/*.ts"
],
};
所以我有两个问题。不确定我应该采取哪种方法。我需要链接 postgres-container (docker) 并在我的 typeorm 中使用它。我还需要制作捆绑代码(在 webpack 捆绑之后)以使用正确的实体文件夹。
解决方案
我没有尝试在我的末端链接 postgres 容器,这导致了问题。道歉,因为我没有尝试在我的最后链接容器。我的错。现在它完美地工作了。我可以恢复在 env 文件中声明 typeorm 连接选项,并在 ts 文件本身中声明适合 webpack 配置的实体
也许如果有人也面临类似的问题,这将帮助他们我的 .env 文件
TYPEORM_HOST=postgres-container
TYPEORM_POSTGRES_USERNAME=postgres
TYPEORM_POSTGRES_PASSWORD=XXXXXX
TYPEORM_TYPE=postgres
TYPEORM_LOGGING=true
TYPEORM_SYNCHRONIZE=true
TYPEORM_DATABASE=XXXXX
我的 Dockerfile(FROM 映像是我自己的节点映像。显然 dockerhub 中的映像 12.9.0 存在并发问题,并且旧版本似乎不支持 atob 模块 base64 解析,因此从 UBUNTU 创建了我自己的作为基础并推送到私人码头中心)
FROM vijayakumarpsg587/node-12:1.01
# install pm2 and link the image using environment variables
RUN npm install pm2 -g
# Create a seperate node user
RUN useradd -ms /bin/bash node-user
RUN mkdir -p /home/node/app
# RUN chown -R node-user:node-user /home/node/app && chmod -R u+rwx,go+rwx /home/node/app
WORKDIR /home/node/app
# USER node-user
COPY package*.json ./
RUN npm install
COPY . ./
RUN npm run build:webpack:dev
ENV PM2_PUBLIC_KEY XXX
ENV PM2_SECRET_KEY XXX
暴露 3002
CMD ["pm2-runtime", "./dist/main.js"]
它是相同的 webpack 配置。此外,用于从 .env 检索内容的 ts 文件也是相同的。
真正的问题是我没有将postgres-container链接到我构建的新应用程序容器。
所以首先我创建一个新的应用程序映像并启动一个容器
码头工人构建 -t XXXX/XXX: .
- (.) 指示从当前 Dockerfile 位置构建映像。使用给定标签构建图像
从图像中启动一个容器,同时链接 postgres-container
docker run -d -p 3002:3002 --name <name of the container> --link postgres-container <image that you created earlier with the prev command>
编辑:请在编写 dockerfile 时遵循 dockerfile 指南中的最佳实践。说明 RUN,COPY ADD 创建新的图像层,它们应该尽可能少。如果需要,请尝试创建多阶段构建。
推荐阅读
- java - 这些对象存储在内存中的什么位置?
- jquery - 插件 daterangepicker 不检查日期有效值
- ef-core-3.0 - EF Core 3.0 映射 IEnumerable 与私有列表
- python - 我无法让 if 循环在 tkinter 代码中工作
- mongodb - 更新嵌入文档数组中的字段时出现问题 Mongoose?
- mysql - 在不使用 MySQL Workbench 的情况下创建新数据库
- django-viewflow - 带有芹菜的 django-viewflow:许可问题
- java - SpringData 和 mongoDb 超时
- java - 解析 XML 失败
- python - pyspark的fold函数中的中性零值是什么意思?