【箸休め】EC2にPostgreSQLサーバを立ててみた

## 概要
- サーバ構築の中で比較的簡単そうなものを触ってみたいと考えた
- 普段MySQLやMongoDBなので、せっかくなので普段触っていないPostgreSQLを試してみようと思った

## 流れ
https://code-kakikaki.com/amazon-linux-2-postgresql-server/

上記の参考サイトをメインに雑にまとめていこうと思う。
詰まりがある部分をメインでまとめる。

## 環境
- AmazonLinux2023 64bit
- ＤＢサーバということで、外部アクセス用にTCP 5432を開放する

## 実際の内容
### コマンドが見つからない
参考サイトでは以下のコマンドを実行し、パッケージのインストール等々を行っているが、AmazonLinux2とAmazonLinux2023はパッケージの使用が変わっているため利用ができない、、

    amazon-linux-extras list
    sudo amazon-linux-extras install postgresql14
    sudo yum install postgresql-server

>Q: AL2023 は AL2 のような Amazon-Linux-Extras を搭載していますか?
>
>A: いいえ。AL2023 には extras はありません。言語ランタイムなどの高レベルのソフトウェアパッケージの場合、四半期ごとのリリースを使用して、リポジトリで提供されるデフォルトパッケージに加えて、個別の名前空間化されたパッケージとしてメジャー/マイナー更新をパッケージに追加します。 例えば、Amazon Linux 2023 のデフォルトの Python バージョンは 3.8 である可能性がありますが、Python 3.9 (python39) が利用可能になると、別の名前空間化されたパッケージとして追加されます。これらの追加パッケージは、アップストリームリリース頻度とサポートモデルに厳密に従います。また、それらのサポートポリシーは、コンプライアンスとセキュリティのユースケースのために、パッケージマネージャーによってアクセスされることがあります。デフォルトパッケージは、AL2023 の存続期間を通じてサポート対象であり続けます。(https://aws.amazon.com/jp/linux/amazon-linux-2023/faqs/)

## AmazonLinx2023の参考サイトに切り替える
https://www.cloudbuilders.jp/articles/1108/

今回1から公式でコマンド調べるほどモチベーションが高くないため、素直にAmazonLinux2023を利用しているサイトから拝借する

## 実施
    $ sudo dnf install -y postgresql15-server

Complete!
と出れば大丈夫です

サイトによれば初期化が必要らしいので、initする

```bash
$ sudo postgresql-setup initdb
WARNING: using obsoleted argument syntax, try --help
WARNING: arguments transformed to: postgresql-setup --initdb --unit postgresql
 * Initializing database in '/var/lib/pgsql/data'
 * Initialized, logs are in /var/lib/pgsql/initdb_postgresql.log
```
ということで警告を出し名が実行した。

どうやら自動的に、`postgresql-setup --initdb --unit postgresql`に変換されて実行されたようだ
今後新しくPostgreSQLを初期化する場合はこちらのコマンドを利用するのが良いだろう

また、DB管理用のユーザーがLinuxのほうに登録されるが、パスワードが設定されていないらしいのでそちらの設定を行う

    $ sudo passwd postgres

初期設定はこれでおわり、PostgreSQLの起動を行う

    # 起動
    $ sudo systemctl start postgresql
    # ステータスの確認
    $ sudo systemctl status postgresql
    # 自動起動の設定
    $ sudo systemctl enable postgresql
    
    ● postgresql.service - PostgreSQL database server
         Loaded: loaded (/usr/lib/systemd/system/postgresql.service; disabled; pres>
         Active: active (running) since Sat 2024-02-10 13:47:41 UTC; 9s ago
         …

緑の感を出しててActiveとなっていたら問題なしです

PostgreSQLを操作して、dbを作成する
```bash
# postgres userに切り替える（pwdはさっき設定した奴）
$ su - postgres
# PostgresSQLにshellに入る
$psql -U postgres

postgres-# \l
                                             List of databases
   Name    |  Owner   | Encoding | Collate |  Ctype  | ICU Locale | Locale Provider |   Access privileges
-----------+----------+----------+---------+---------+------------+-----------------+-----------------------
 postgres  | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            |
 template0 | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres          +
           |          |          |         |         |            |                 | postgres=CTc/postgres
 template1 | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres          +
           |          |          |         |         |            |                 | postgres=CTc/postgres
(3 rows)
postgres=# create database test;
CREATE DATABASE
postgres=# \l
                                             List of databases
   Name    |  Owner   | Encoding | Collate |  Ctype  | ICU Locale | Locale Provider |   Access privileges
-----------+----------+----------+---------+---------+------------+-----------------+-----------------------
 postgres  | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            |
 template0 | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres          +
           |          |          |         |         |            |                 | postgres=CTc/postgres
 template1 | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            | =c/postgres          +
           |          |          |         |         |            |                 | postgres=CTc/postgres
 test      | postgres | UTF8     | C.UTF-8 | C.UTF-8 |            | libc            |
(4 rows)
```
こんな感じで、DBの作成が完了した

## DBサーバとしての設定を行う
```bash
$ sudo vi  /var/lib/pgsql/data/postgresql.conf
```
設定ファイルで次のように設定する
```conf: /var/lib/pgsql/data/postgresql.conf
listen_addresses =  '*'
```

また、
```bash
$ sudo vi  /var/lib/pgsql/data/pg_hba.conf
# 自宅のIPなどに変えて追記
host    test            postgres        XXX.XXX.XXX.XXXX/32        md5
```

上の設定で、アクセスできるはずだったが、logを見たところpostgresというユーザーにパスワードが設定されていないと言っている。

:::note alert
postgresで設定したパスワードはあくまでもLinux上のユーザーのパスワードである、、
postgreSQL側のユーザーでパスワードを設定する必要がある
:::

```
# psqlにアクセス
sudo -u postgres psql
# パスワードを設定する
ALTER USER postgres WITH PASSWORD '新しいパスワード';
# 設定の反映
sudo systemctl restart postgresql
```

```js:testscript
const { Client } = require('pg');

// PostgreSQLクライアントの設定
const client = new Client({
  host: '自分のIP',
  database: 'test',
  user: 'your_username',
  password: 'your_password',
  port: 5432,
});

async function ensureTableExists() {
  const createTableText = `
    CREATE TABLE IF NOT EXISTS your_table_name (
      id SERIAL PRIMARY KEY,
      column1 VARCHAR(255),
      column2 VARCHAR(255)
    );
  `;

  await client.query(createTableText);
  console.log('Table checked/created successfully');
}

async function insertData() {
  try {
    // データベースへの接続
    await client.connect();
    console.log('Connected to PostgreSQL');

    // テーブルの存在を確認し、必要に応じて作成
    await ensureTableExists();

    // データの追加
    const insertText = 'INSERT INTO your_table_name (column1, column2) VALUES ($1, $2) RETURNING *';
    const values = ['value1', 'value2'];
    const result = await client.query(insertText, values);
    console.log('Inserted data:', result.rows[0]);

    // クライアントの切断
    await client.end();
    console.log('Disconnected from PostgreSQL');
  } catch (err) {
    console.error('An error occurred:', err);
    await client.end();
  }
}

insertData();

```

これらの設定で自分はうまくいきました。
もし、うまくいかなかった場合は、下のLogファイルを見ると解決できるかもしれません。
```
$ sudo cat /var/lib/pgsql/data/log/postgresql-Sat.log
```



## 今回一番の衝撃
**AmazonDB系に無料枠あるのかよ！！！！！**

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.PostgreSQL.html

## まとめ
AmazonRDSに無料枠があることを初めて知った、、、
これまで、EC2に突っ込んでいたので、可能であればこちらを利用したいと思う
また、今回はDBが落ちてしまった場合に自動で再起動する設定などを行っていないが、本番環境などでは設定が必要だろう。参考にする方はそこに注意してほしい。
また、外部からアクセスできるように設定する部分で、postgresユーザーにパスワードがついていないということに気が付くのに時間がかかり、箸休めのつもりが意外と時間がかかってしまった、、、

## 参考サイト
AmazonLinux2だったやつ

https://code-kakikaki.com/amazon-linux-2-postgresql-server/

インストールまで

https://www.cloudbuilders.jp/articles/1108/

自動起動

https://engineer-milione.com/tips/centos7postgres.html