Open1

【docker-compose × express × PostgreSQL】データ永続化確認、ボリュームマウントとバインドマウントなど

tech_mwtech_mw

・docker-compose × express × PostgreSQL
・データ永続化確認、ボリュームマウントとバインドマウント
についての手順とメモです

ここでは Docker Compose v2 を想定し、docker compose 表記に統一しています。
v1系を使う場合は docker-compose に読み替えてください

環境

pc:MacBook Pro(2019)
os:macos Sequoia
docker:Docker version 20.10.6, build 370c289
docker-compose:Docker Compose version 2.0.0-beta.1
docker desktop 利用

構成

PJはcompose-express-db-appとしていますが何でも大丈夫です
以降のコマンドなど適宜変更してお試しください

PJ(compose-express-db-app)
├── app.js
├── docker-compose.yml
├── Dockerfile
├── package-lock.json(セットアップで自動生成)
└── package.json(セットアップで自動生成)
app.js
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});
docker-compose.yml
version: "3"
services:
  web:
    # 同階層にexpress用のDockerfileがある事前提
    build: .
    container_name: my-node-app
    # コンテナ側dirの指定
    working_dir: /usr/src/app
    # ローカル:コンテナ
    volumes:
      - .:/usr/src/app
    ports:
      - "3000:3000"
    # dbという名前のサービスが起動してからwebを起動
    depends_on:
      - db

  db:
    image: postgres:13
    container_name: postgres-db
    environment:
      POSTGRES_PASSWORD: mysecretpassword
    # 永続化
    # pgdataボリュームをコンテナの /var/lib/postgresql/data にマウント
    volumes:
      - pgdata:/var/lib/postgresql/data

# 永続化
volumes:
  pgdata:
Dockerfile
FROM node:20

WORKDIR /usr/src/app

COPY package*.json .

RUN npm install

COPY app.js .

CMD ["node", "app.js"]

npm + express セットアップ

expressアプリ用のpackage.jsonを生成し、expressをインストール

npm init -y
npm i express

起動

docker compose up -d

永続化のポイント

  • volumes: [pgdata:/var/lib/postgresql/data] でコンテナ停止/削除してもデータは残る
  • データが消えるのは volume を削除したときだけ

ボリュームマウントとバインドマウント比較

ボリュームマウント(named volume)

  • Dockerが自動管理
  • ホスト側にフォルダ不要
  • 例:
    volumes:
      - pgdata:/var/lib/postgresql/data
    

バインドマウント(bind mount)

  • ホスト側の指定フォルダをマウント
  • ホストに事前にフォルダが必要
  • 例:
    volumes:
      - ./pgdata:/var/lib/postgresql/data
    

DBデータ作成 → 停止 → 再起動しても残る流れ

1.DB接続

docker exec -it postgres-db psql -U postgres

2.デフォルトDB一覧

\list

3.新規DB作成

CREATE DATABASE sampledb;

4.DB切替

\c sampledb

5.テーブル作成

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

6.データ挿入

INSERT INTO users (name) VALUES ('Alice');
INSERT INTO users (name) VALUES ('Bob');

7.データ確認

SELECT * FROM users;

出力例:

 id | name
----+-------
  1 | Alice
  2 | Bob

8.コンテナ停止

docker compose stop

9.コンテナ再起動

docker compose up -d

10.再接続して確認

docker exec -it postgres-db psql -U postgres -d sampledb
SELECT * FROM users;

出力例:

 id | name
----+-------
  1 | Alice
  2 | Bob

ローカル側のボリューム確認

ボリューム情報取得

docker inspect compose-express-db-app_pgdata

例(抜粋):

"Mountpoint": "/var/lib/docker/volumes/compose-express-db-app_pgdata/_data",
"Name": "compose-express-db-app_pgdata"

Alpineコンテナで中身を確認

  • 確認はできるが直接編集は推奨されない
docker run --rm -it -v compose-express-db-app_pgdata:/data alpine sh
ls /data/

Docker Desktop(Mac/Windows)の場合、ホストOSに /var/lib/docker は存在しない

  • Docker Desktop(Mac/Windows)のホストOSには /var/lib/docker/volumes/ というディレクトリ自体が存在しない(内部VMで管理しているため)
cd /var/lib/docker/volumes/03-compose-express-db-app_pgdata/

別のPostgreSQLコンテナでボリュームをマウントして確認

docker run --rm -it \
  -v compose-express-db-app_pgdata:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=mysecretpassword postgres:13

docker exec -it [コンテナID] psql -U postgres

バインドマウントを使う場合

volumes:
  - ./pgdata:/var/lib/postgresql/data

プロジェクト直下の「./pgdata」フォルダをコンテナ内にマウント

事前にホスト側に作成

mkdir pgdata

起動

docker compose up -d

./pgdata にDBファイル群がそのまま保存され、停止後も内容保持