首页 > 解决方案 > 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 捆绑之后)以使用正确的实体文件夹。

标签: node.jstypescriptdockerwebpacktypeorm

解决方案


我没有尝试在我的末端链接 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 创建新的图像层,它们应该尽可能少。如果需要,请尝试创建多阶段构建。


推荐阅读