Docker でRDB環境構築盛り合わせ

f:id:Naotsugu:20201013222311p:plain


はじめに

各種 RDB を オフィシャルな Docker イメージでサクッと環境構築する手順の盛り合わせです。


PostgreSQL

Docker Official Images で公開されています。 docker-compose.yml は以下のようになります。

version: '3.8' # 19.03.0+
services:

  db:
    image: postgres:13-alpine
    ports:
      - 5432:5432
    environment:
      - POSTGRES_PASSWORD=secret
    volumes:
      - ./db-data:/var/lib/postgresql/data
      - ./db-script:/docker-entrypoint-initdb.d


ローカルのdb-script の中に *.sql*.sql.gz*.sh としてスクリプトを置いておけば初期化時に実行されます。

environment には以下を指定することができます。

環境変数 説明
POSTGRES_PASSWORD (必須)PostgreSQLのスーパーユーザパスワードを指定
POSTGRES_USER 指定されたユーザをスーパーユーザ権限で作成し、同名のデータベースを作成。指定しない場合は postgres が使用される
POSTGRES_DB イメージ起動時に作成されるデフォルトのデータベースの名前を指定
POSTGRES_INITDB_ARGS postgres initdb コマンドに渡す引数指定
POSTGRES_INITDB_WALDIR トランザクションログ配置場所を指定
POSTGRES_HOST_AUTH_METHOD ホスト接続のauth-methodを制御
PGDATA データベースファイルの配置場所を指定


PostgreSQL への接続

コンテナを起動して bash からデータベースへ接続するには以下のようにします。

$ docker-compose up -d

$ docker-compose exec db bash

$ psql -U postgres
psql (13.0)
Type "help" for help.

postgres=#

psql コマンドに -U でロール名を指定を指定します。

-d でデータベース名を指定します。省略した場合はロール名と同名のデータベースに接続します。

外部から接続する場合は psql -h <host> -p <port> -U <role_name> -d <db_name> のように指定します。

デフォルトのロール(PostgreSQL 8.1からはユーザとグループがロールとしてまとめられた) は postgres で、データベース名を指定しない場合は同名の postgres でデータベースが作成されています。


ロールの作成

新しいロールをログイン可能として作成するには以下のようにします。

# create role myrole with login password 'password';

# \du
                                   List of roles
 Role name |                         Attributes                         | Member of
-----------+------------------------------------------------------------+-----------
 myrole    |                                                            | {}
 postgres  | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

ログイン可能なロール作成は create user で作成することも出来ます(単なるエイリアスなので結果は同じです)。

権限は、スーパーユーザー SUPERUSER、データベースを作成可能な CREATEDB、ロール作成が可能な権限CREATEROLE などがあります。

スーパーユーザー権限をロールに付与するには以下のようにします。

# alter role myrole with SUPERUSER;

ロールの切り替えは以下のようにします。

# set role myrole;


データベースの作成

新しいデータベースを作成して接続するには以下のようにします。

postgres=# create database example;
CREATE DATABASE
postgres=# \l
                                 List of databases
   Name    |  Owner   | Encoding |  Collate   |   Ctype    |   Access privileges
-----------+----------+----------+------------+------------+-----------------------
 example   | myrole   | UTF8     | en_US.utf8 | en_US.utf8 |
 postgres  | postgres | UTF8     | en_US.utf8 | en_US.utf8 |
 template0 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.utf8 | en_US.utf8 | =c/postgres          +
           |          |          |            |            | postgres=CTc/postgres
(4 rows)

postgres=# \c example

\l でデータベースの一覧を表示します。\c または \connect でデータベースに接続します。


テーブルの作成と操作

新しいテーブルの作成と操作は以下のようにします。

# create table if not exists test1 (id integer, name varchar(10));

# insert into test1 (id, name) values (1, 'foo');

# select * from test1;
 id | name
----+------
  1 | foo
(1 row)


オブジェクトの削除

テーブル削除とデータベースの削除、ロールの削除は以下のようにします。

# drop table test1;

# \c postgres

# drop database example;

# drop role saru;


psql の代表的なメタコマンド

基本的なコマンドは以下となります。

コマンド 説明
psql -U <user_name> <db_name> 指定ロールで指定データベースに接続
\du ロール一覧
\l データベース一覧
\du データベースユーザ一覧
\dt テーブル一覧
\d <table_name> テーブル定義
\q quit
\? ヘルプ


MariaDB

Docker Official Images で公開されています。docker-compose.yml は以下のようになります。

version: '3.8' # 19.03.0+
services:

  db:
    image: mariadb:10.5
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=secret
    volumes:
      - ./db-data:/var/lib/mysql
      - ./db-script:/docker-entrypoint-initdb.d


ローカルの db-script の中に *.sql*.sql.gz*.sh としてスクリプトを置いておけば初期化時に実行されます。

environment には以下を指定することができます。

環境変数 説明
MYSQL_ROOT_PASSWORD (必須)MariaDBルートスーパーユーザパスワードを指定
MYSQL_DATABASE イメージ起動時に作成されるデフォルトのデータベースの名前を指定
MYSQL_USER イメージ起動時に作成する新しいユーザー名を指定
MYSQL_PASSWORD イメージ起動時に作成する新しいユーザのパスワードを指定
MYSQL_ALLOW_EMPTY_PASSWORD yes とするとコンテナをルートユーザのパスワードが空で起動できるようになる
MYSQL_RANDOM_ROOT_PASSWORD yes とするとルートユーザのパスワードがランダムに生成される
MYSQL_INITDB_SKIP_TZINFO CONVERT_TZ() 関数に必要なタイムゾーンデータの自動ロードをスキップ


MariaDB への接続

コンテナを起動して bash からデータベース接続するには以下のようにします。

$ docker-compose up -d

$ docker-compose exec db bash

$ mysql -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.5.5-MariaDB-1:10.5.5+maria~focal mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

外部から接続する場合は mysql -h <host> -P <port> -u <user> -p とします。

初期でユーザ root と、データベース mysql が作成されています。


ユーザの作成

新しいユーザを作成するには以下のようにします。

# create user myuser identified by 'password';

接続クライアントのホストを指定する場合にはユーザ名として 'user_name'@'host_name' のように指定します。ホストを指定しない場合はワイルドカード% となり全てのホストから接続可能となります。

権限の追加は以下のようにします。

# grant all privileges on *.* to myuser with grant option;
# flush privileges;

# select user, host from mysql.user;
+-------------+-----------+
| User        | Host      |
+-------------+-----------+
| myuser      | %         |
| root        | %         |
| mariadb.sys | localhost |
| root        | localhost |
+-------------+-----------+

PRIVILEGES で特権ユーザーを指定しており、対象は全データベースとして ON *.* と指定しています。データベースやテーブルを指定する場合はON <database>.<table> のように指定します。WITH GRANT OPTION で他のユーザの権限を変更可能となります。

flush privileges でデータベースへ反映します。

作成したユーザで接続するには以下のようにします。

# quit;
$ mysql -u myuser -p


データベースの作成

データベースの作成は以下のようにします。

# create database example;

# show databases;
+--------------------+
| Database           |
+--------------------+
| example            |
| information_schema |
| mysql              |
| performance_schema |
+--------------------+

作成したデータベースに接続するには connect を使います。

# connect example;


テーブルの作成と操作

新しいテーブルの作成と操作は以下のようにします。

# create table if not exists test1 (id integer, name varchar(10));

# insert into test1 (id, name) values (1, 'foo');

# select * from test1;
+------+------+
| id   | name |
+------+------+
|    1 | foo  |
+------+------+


オブジェクトの削除

テーブル削除とデータベースの削除、ロールの削除は以下のようにします。

# drop table test1;

# drop database example;

# drop user myuser;


SQL Server

Microsoft SQL Server で Linux 版のSQL Server の公式イメージが公開されています。 docker-compose.yml は以下のようになります。

version: '3.8' # 19.03.0+
services:

  db:
    image: mcr.microsoft.com/mssql/server:2019-latest
    ports:
      - 1433:1433
    environment:
      - ACCEPT_EULA=Y
      - MSSQL_SA_PASSWORD=P@ssw0rd
      - MSSQL_PID=Express
      - MSSQL_LCID=1041
      - MSSQL_COLLATION=Japanese_CI_AS
    volumes:
      - ./db-data:/var/opt/mssql


パスワードは8文字以上で英数記号混在の強度の高い値にしておかないと起動時にエラーになります。

environment には以下のような指定があります。

環境変数 説明
ACCEPT_EULA 使用許諾への同意
MSSQL_SA_PASSWORD SA ユーザのパスワードを指定
MSSQL_PID SQL Server のエディションまたはプロダクトキーを指定
MSSQL_LCID language IDを指定
MSSQL_COLLATION 照合順序を設定(LCIDから照合順序へのマッピングをオーバーライド)
MSSQL_DATA_DIR データベースのデータファイル(.mdf)の格納場所を指定
MSSQL_LOG_DIR データベースログファイル(.ldf)の格納場所を指定

エディションには Evaluation Developer Express Web Standard Enterprise が指定できます。


SQL Server への接続

コンテナを起動して bash からデータベース接続するには以下のようにします。

$ docker-compose up -d

$ docker-compose exec db bash

# /opt/mssql-tools/bin/sqlcmd -U sa -P P@ssw0rd
1> 

-U でユーザ、-P でパスワードを指定します。 外部から接続する場合は sqlcmd -S <host>,<port> -U <user> -P <password> のように指定します。

初期ユーザとして sa などが利用できます。

データベースは以下が作成されています。

1> select name from sys.databases;
2> go
name
-------------
master
tempdb
model
msdb

sqlcmd では問い合わせ実行は必ず go と入力する必要があります。


データベースの作成

データベースの作成には create database を使います。

1> create database example;
2> go

1> use example;
2> go
データベース コンテキストが 'example' に変更されました。

use にてデータベースを指定します。


ユーザの作成

SQL Server ではログインユーザを作成してデータベースユーザにマップします。

1> create login myuser with
    password = 'password',
    check_policy = off;
2> go

1> create user myuser for login myuser;
2> go

1> alter role db_owner add member myuser;
2> go

1> setuser 'myuser';
2> go   

Login の作成は check_policy でポリシーの適用を無効化しています。


テーブルの作成と操作

新しいテーブルの作成と操作は以下のようにします。

1> create table test1 (id integer, name varchar(10));
2> go

1> select name from sys.objects where type = 'U';
2> go
name
---------------
test1

1> insert into test1 (id, name) values (1, 'foo');
2> go

1> select * from test1;
2> go
id          name
----------- ----------
          1 foo


オブジェクトの削除

テーブル削除とデータベースの削除、ユーザの削除は以下のようにします。

1> drop table test1;
2> go

1> quit

$ /opt/mssql-tools/bin/sqlcmd -U sa -P P@ssw0rd

1> drop database example;
2> go

1> drop user myuser;
2> go

1> drop login myuser;
2> go 


Oracle Express Edition

導入が簡単な Express Edition を使います。

Oracle からイメージ作成用のスクリプトが Github に公開されているのでこれを使います。

$ mkdir oracle
$ cd oracle
$ git clone https://github.com/oracle/docker-images.git

いろいろなプロダクトのスクリプトがありますが、ここでは OracleDatabase/SingleInstance を使います。

$ cd docker-images/OracleDatabase/SingleInstance/dockerfiles
$ ./buildDockerImage.sh -v 18.4.0 -x

-v でビルドするイメージのバージョンを指定します。-x を指定すれば Express Edition となります。

以下のように出力されればイメージのビルドが完了です。

  Oracle Database Docker Image for 'xe' version 18.4.0 is ready to be extended:

    --> oracle/database:18.4.0-xe

  Build completed in 1457 seconds.

以前はOTNから別途インストーラをダウンロードして配備する必要がありましたが、現在はスクリプトを実行するだけで良くなり、導入が楽になりました。


docker-compose.yml は以下のようになります。

version: '3.8' # 19.03.0+
services:

  db:
    image: oracle/database:18.4.0-xe
    ports:
      - 1521:1521
      - 5500:5500
    environment:
      - ORACLE_PWD=secret
    volumes:
      - ./db-data:/opt/oracle/oradata
      - ./db-script:/opt/oracle/scripts/setup

ローカルの db-script の中に .sql や .sh としてスクリプトを置いておけば初期化時に実行されます。


Oracle Express Edition への接続

コンテナを起動して bash からコンテナデータベース(CDB)へ接続するには以下のようにします。

$ docker-compose up -d

$ docker-compose exec db bash

# sqlplus sys/secret@//localhost:1521/XE as sysdba

SQL*Plus: Release 18.0.0.0.0 - Production on Tue Oct 13 12:23:24 2020
Version 18.4.0.0.0

Copyright (c) 1982, 2018, Oracle.  All rights reserved.


Connected to:
Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production
Version 18.4.0.0.0

SQL>

ログインできない場合はこちらのIssue を参考にしてください。

system によるログインは sqlplus system/secret@//localhost:1521/XE で可能です。


PDB への接続

Oracle 12c よりデータベースのマルチテナント化が行われており、先程ログインした先(CDB)はテナントのベース(仮想環境で言うローカルマシン)になります。実際のデータベースは CDB の上にプラッガブルデータベース(PDB)として作成されます。

プラッガブルデータベースの一覧は以下のように参照できます。

SQL> show pdbs

    CON_ID CON_NAME           OPEN MODE  RESTRICTED
---------- ------------------------------ ---------- ----------
     2 PDB$SEED           READ ONLY  NO
     3 XEPDB1             READ WRITE NO

XEPDB1 というプラッガブルデータベースが作成されています。

XEPDB1 へ接続するには以下のようにします。

SQL> alter session set container = XEPDB1;
Session altered.

なお、XEPDB1 には pdbadmin ユーザがデフォルトで作成されています。


ユーザの作成

新しいユーザをDBAロールで作成するには以下のようにします。

SQL> CREATE USER myuser IDENTIFIED BY password DEFAULT TABLESPACE users TEMPORARY TABLESPACE temp;
SQL> GRANT DBA TO myuser;
SQL> ALTER USER myuser QUOTA UNLIMITED ON users;

合わせて表領域の制限を QUOTA UNLIMITED で無制限としました。

開発環境では以下のようにパスワードの有効期限を無制限にしておくと便利です。

SQL> ALTER PROFILE DEFAULT LIMIT password_life_time UNLIMITED;

作成したユーザで以下のようにPDBに接続できます。

# sqlplus myuser/password@//localhost:1521/XEPDB1


テーブルの作成と操作

新しいテーブルの作成と操作は以下のようにします。

SQL> create table test1 (id integer, name varchar(10));

# insert into test1 (id, name) values (1, 'foo');

# select * from test1;
    ID NAME
---------- ----------
     1 foo


オブジェクトの削除

テーブル削除とユーザの削除は以下のようにします。

SQL> drop table test1;
SQL> quit

# sqlplus sys/secret@//localhost:1521/XE as sysdba

SQL> alter session set container = XEPDB1;

SQL> drop user myuser cascade;


まとめ

各種 RDB による開発環境を Docker で構築する手順と、簡単な操作手順について説明しました。

商用プロダクトにおいても簡単に導入することができるようになっており、良い時代になったものです。