Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
1
Help us understand the problem. What is going on with this article?
@basio

DockerでNode.js+PostgreSQLの環境を構築する

はじめに

Docker上でNode.js(Express)とPostgreSQLの環境を構築しようとしたのですが、正しく動作する簡潔な記事が見当たらなかったので、本記事を投稿します。
データベースの情報を取得するWebアプリケーションを作成し、実際にデータを追加してみて正しく動作することの確認を行っていきます。

環境概要

Webサーバー (Node.js)
image : node:15-slim
データベース (PostgreSQL)
image : postgres:13

プロジェクト

ディレクトリ構成

project/
  ├─app/                  # Node.jsアプリケーション
  │  ├─node_modules/
  │  ├─Dockerfile
  │  ├─index.js
  │  ├─package.json
  |  └─yarn.lock
  ├─initdb/               # PostgreSQL初期化ファイル
  │   └─setup.sql
  └─docker-compose.yaml 

docker-compose

下記のように記載します。
PostgreSQLのデータはdb_dataボリュームで永続化しています。

docker-compose.yaml
version: "3"
services:
  node:
    container_name: node_express
    build: ./app
    volumes:
      - ./app:/app
    tty:  true
    ports:
      - 3000:3000

  postgres:
    container_name: postgres
    image: postgres:13
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: postgres_db
    volumes:
      - db_data:/var/lib/posrgresql/data
      - ./initdb:/docker-entrypoint-initdb.d

volumes:
  db_data: {}

app:Node.jsアプリケーション

Expressを使用して、PostgreSQLのデータを取得するWebアプリケーションを作成します。

index.js
const express = require('express');
const app = express();

// PostgreSQLの設定
const { Pool } = require('pg')
const pool = new Pool({
  user: 'postgres',
  host: 'postgres',
  database: 'postgres_db',
  password: 'password',
  port: 5432,
})

// ルーティングの設定
app.get('/', async(req, res) => {
  const { rows } = await pool.query('select * from users')
  res.send(rows)
});

const port = 3000;

app.listen(port, () => {
    console.log(`server started on port ${port}`);
}); 

pacakge.jsonは下記のように手書きするか、npm initなどで作成します。

package.json
{
  "name": "app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node index.js"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "pg": "^8.5.1"
  }
}

Dockerfileを下記のように作成し、ビルド時に必要なパッケージをインストールして起動するようにします。

Dockerfile
FROM node:15-slim

RUN yarn install

WORKDIR /app

CMD ["yarn", "start"]

initdb:PostgreSQL初期化ファイル

postgresイメージでは、初期化時にdocker-entrypoint-initdb.d内のsqlファイルが実行されるため、ここで初期化を行います。
Node.jsアプリケーション内でも記載していますが、usersというテーブルをこのファイル内で作成します。

setup.sql
set client_encoding = 'UTF8';

create table users(
    id serial primary key,
    name varchar not null,
    age integer not null
)

動作確認

コンテナの立ち上げ

docker-composeコマンドでコンテナを立ち上げます。

docker-compose up

http://localhost:3000 にブラウザでアクセスすると、空のデータが取得できていると思います。
image.png

データの追加

postgresコンテナに入ってデータを追加してみましょう。
下記コマンドで実行中のpostgresコンテナに入れます。

docker exec -i -t postgres bash

ターミナルに入れたら、psqlコマンドでPostgreSQLに接続します。

psql -U postgres -d postgres_db

この状態でSQLコマンドを入れれるようになるので、下記コマンドを実行します。

insert into users (name, age) values ('MY NAME', 20);

再度http://localhost:3000 にブラウザでアクセスすると、先ほど追加されたデータが帰ってきます。
image.png

おわりに

Docker上でNode.jsとPostgreSQLの環境を構築し、実際に動作確認を行いました。

1
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
basio
業務ではC#/C++によるWindowsアプリケーション開発をメインとしているエンジニア。趣味でWeb系、クラウド系の学習をしている。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
1
Help us understand the problem. What is going on with this article?