Rocky Linux 9 に Nuxt3 + FastAPI + PostgreSQL + NGINX を構築する手順

Linux Server

Rocky Linux の基本セットアップ

システムのアップデート

$ sudo dnf update -y

必要なパッケージのインストール

開発に必要なツールをインストールします。

$ sudo dnf install -y git wget curl nano epel-release

※wget curl nanoにつきましては既にインストールされている場合、以下のメッセージが表示されます。
パッケージ wget-1.21.1-8.el9_4.x86_64 は既にインストールされています。
パッケージ curl-7.76.1-31.el9.x86_64 は既にインストールされています。
パッケージ nano-5.6.1-6.el9.x86_64 は既にインストールされています。


PostgreSQL のインストール

SELinuxの設定(無効化)

PostgreSQLのデータベースクラスタを標準パス(/var/lib/pgsql)以外の場所(例:/data/pgsql)に作成する場合は、SELinuxのコンテキストを適切に設定する必要があります。本番環境では面倒でも有効で使うべきですが、開発環境では無効のほうが楽ですのでここでは無効に変更します。

## 最初にSELinuxが有効か確認します。出力がEnforcingならSELinuxが有効です。出力がPermissiveやDisabledなら、一時的または恒久的に無効になっています。
$ sudo getenforce 

## 恒久的に無効に変更します。
$ sudo vi /etc/selinux/config 
$ SELINUX=disabled 

## 再起動します。
$ sudo init 6 

PostgreSQL のリポジトリ追加

現在のAppStreamの追加可能なPostgreSQLモジュールを確認します。

$ sudo dnf module list postgresql
メタデータの期限切れの最終確認: 0:11:11 前の 2025年02月27日 15時08分46秒 に実施しました。
Rocky Linux 9 - AppStream
Name       Stream  Profiles            Summary                                                                 
postgresql 15      client, server [d]  PostgreSQL server and client module                                     
postgresql 16      client, server [d]  PostgreSQL server and client module                                     
ヒント: [d]efault, [e]nabled, [x]disabled, [i]nstalled

postgresql16パッケージをインストールします。インストール時に PostgreSQL のスーパーユーザ postgresが存在しなければ、作成されます。

$ sudo dnf -y module install postgresql:16
・・・中間省略・・・
インストール済み:
  postgresql-16.8-1.module+el9.5.0+30638+72f697e1.x86_64
  postgresql-private-libs-16.8-1.module+el9.5.0+30638+72f697e1.x86_64
  postgresql-server-16.8-1.module+el9.5.0+30638+72f697e1.x86_64 
完了しました!

## 自動的に作成されたPostgreSQLのスーパーユーザpostgresを確認します。
$ cat /etc/passwd| grep postgres
postgres:x:26:26:PostgreSQL Server:/var/lib/pgsql:/bin/bash
$ id postgres
uid=26(postgres) gid=26(postgres) groups=26(postgres)

## のスーパーユーザpostgresのホームディレクトリを確認します。
$ tree /var/lib/pgsql -a
/var/lib/pgsql
├── .bash_profile
├── .cache
├── backups
└── data

PostgreSQL の初期化

PostgreSQLのスーパーユーザpostgresにログインします。※スーパーユーザpostgresはpostgresql16パッケージインストール時に自動作成され、パスワードが分かりません。sudoコマンドを使用するか”sudo passwd postgres“コマンドでパスワードを変更して使うことも可能です。

$ sudo su - postgres
$ pwd
/var/lib/pgsql
$ cat .bash_profile
[ -f /etc/profile ] && source /etc/profile
PGDATA=/var/lib/pgsql/data
export PGDATA

データベースクラスタを作成時のデータベース管理ユーザpostgresのパスワードを格納して置くp.txtファイルを作成します。※PostgreSQLのスーパーユーザpostgres(OSユーザー)データベース名postgresデータベース管理ユーザpostgresは名称が同一なので注意が必要です。

$ echo postgres > p.txt
$ tree . -a
・・・中間省略・・・
└── p.txt
3 directories, 2 files

パスワードファイル指定してデータベースクラスタを作成の場合のコマンド

$ initdb -U postgres -E utf8 --locale=ja_JP.utf8 -A password --pwfile=p.txt -D $PGDATA
データベースシステム内のファイルの所有者はユーザー"postgres"となります。
このユーザーをサーバープロセスの所有者とする必要があります。

データベースクラスタはロケール"ja_JP.utf8"で初期化されます。
initdb: ロケール"ja_JP.utf8"用の適切なテキスト検索設定が見つかりませんでした
デフォルトのテキスト検索構成は simple に設定されます。

データベージのチェックサムは無効です。

ディレクトリ/var/lib/pgsql/dataの権限を設定しています ... ok
サブディレクトリを作成しています ... ok
動的共有メモリの実装を選択しています ... posix
デフォルトのmax_connectionsを選択しています ... 100
デフォルトのshared_buffersを選択しています ... 128MB
デフォルトの時間帯を選択しています ... Asia/Tokyo
設定ファイルを作成しています ... ok
ブートストラップスクリプトを実行しています ... ok
ブートストラップ後の初期化を実行しています ... ok
データをディスクに同期しています ... ok

成功しました。以下のようにしてデータベースサーバーを起動できます:
    pg_ctl -D /var/lib/pgsql/data -l ログファイル start
#パスワード入力してデータベースクラスタを作成の場合のコマンド
$ initdb -U postgres -E utf8 --locale=ja_JP.utf8 -A password -W -D $PGDATA

作成結果は以下のとおりです。

$ tree . -a
.
├── .bash_profile
├── .cache
├── backups
├── data
│   ├── PG_VERSION
・・・中間省略・・・
│   ├── pg_hba.conf
│   ├── pg_ident.conf
│   ├── postgresql.auto.conf
│   └── postgresql.conf
└── p.txt

28 directories, 970 files

#管理者ユーザに戻ります。
$ exit

PostgreSQLの起動と自動起動設定

PostgreSQLサーバを起動し、システムサービスの自動起動設定を行います。

$ sudo systemctl enable --now postgresql
Created symlink /etc/systemd/system/multi-user.target.wants/postgresql.service → /usr/lib/systemd/system/postgresql.service.

PostgreSQLの状態を確認します。

$ sudo systemctl status postgresql 
● postgresql.service - PostgreSQL database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; preset: disabled)
     Active: active (running) since Tue 2025-03-11 12:04:30 JST; 5 days ago
・・・中間省略・・・

ロケール情報を確認

$ sudo -u postgres psql -l
ユーザー postgres のパスワード: postgres
                                   データベース一覧
   名前    |  所有者  | エン |  照合順序  | Ctype(変換 |     アクセス権限      
-----------+----------+------+------------+------------+-----------------------
 postgres  | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | 
 template0 | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | =c/postgres          +
           |          |      |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | =c/postgres          +
           |          |      |            |            | postgres=CTc/postgres

PostgreSQL のユーザーとデータベースの作成

既存の/var/lib/pgsql以外にユーザが作成するテーブルスペースの格納場所/opt/sadari/pgsqlを指定します。

##  再度SELinuxが無効の状態か確認します。SELinux 無効化を実施しないとCREATE TABLESPACEで/opt/sadari/pgsql/dataのフォルダ作成に権限エラーが発生します。
$ sudo getenforce
Diabled
$ sudo mkdir -p /opt/sadari/pgsql/data
$ sudo mkdir -p /opt/sadari/pgsql/index
$ sudo tree /opt -a
/opt
└── sadari
    └── pgsql
        ├── data
        └── index
4 directories, 0 files
$ sudo chown -R postgres:postgres /opt/sadari
$ sudo chmod -R 700 /opt/sadari
$ sudo chown postgres:postgres /opt/sadari/pgsql/..
$ sudo chmod 700 /opt/sadari/pgsql/..
$ sudo chmod 700 /opt/sadari/..
$ sudo ls -l /opt/sadari
drwx------. 2 postgres postgres   6  2月 27 17:50 pgsql
$ sudo ls -l /var/lib | grep pgsql
drwx------. 5 postgres postgres 123  2月 27 16:57 pgsql

PostgreSQLのDBサーバが起動中であるか確認します。

$ sudo ps -ef | grep postgres
postgres    1045       1  0 18:23 ?        00:00:00 /usr/bin/postgres -D /var/lib/pgsql/data
postgres    1104    1045  0 18:23 ?        00:00:00 postgres: logger 
postgres    1106    1045  0 18:23 ?        00:00:00 postgres: checkpointer 
postgres    1107    1045  0 18:23 ?        00:00:00 postgres: background writer 
postgres    1115    1045  0 18:23 ?        00:00:00 postgres: walwriter 
postgres    1116    1045  0 18:23 ?        00:00:00 postgres: autovacuum launcher 
postgres    1117    1045  0 18:23 ?        00:00:00 postgres: logical replication launcher 
root        5608    5512  0 18:24 pts/0    00:00:00 grep --color=auto postgres

デフォルトのpostgresユーザーでPostgreSQLにログインし、新しいDB管理ユーザーと新規データベースを作成します。

$ su - postgres
$ psql 
-- prompt -- ユーザ作成
CREATE ROLE sadariadmin LOGIN PASSWORD  'sadari1234!'
  SUPERUSER INHERIT CREATEDB CREATEROLE NOREPLICATION;

-- prompt -- 表領域作成 ( SADARI_DATA )
CREATE TABLESPACE sadaridb_data LOCATION '/opt/sadari/pgsql/data';
COMMENT ON TABLESPACE sadaridb_data IS 'sadaridb_data';
-- prompt -- 表領域作成 ( SADARIDB_INDEX )
CREATE TABLESPACE sadaridb_index LOCATION '/opt/sadari/pgsql/index';
COMMENT ON TABLESPACE sadaridb_index IS 'sadaridb_index';

ALTER TABLESPACE sadaridb_data OWNER TO sadariadmin;
ALTER TABLESPACE sadaridb_index OWNER TO sadariadmin; 

CREATE DATABASE sadaridb WITH OWNER = sadariadmin ENCODING = 'UTF8' TABLESPACE = sadaridb_data
     LC_COLLATE = 'ja_JP.utf8' LC_CTYPE = 'ja_JP.utf8' CONNECTION LIMIT = -1;

COMMENT ON DATABASE sadaridb IS 'sadari repository manager database';

ALTER SCHEMA public OWNER TO sadariadmin;
GRANT  ALL ON DATABASE sadaridb TO sadariadmin;
REVOKE ALL ON DATABASE sadaridb FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM PUBLIC;
\l
                                   データベース一覧
   名前    |  所有者  | エン |  照合順序  | Ctype(変換 |     アクセス権限      
-----------+----------+------+------------+------------+-----------------------
 sadaridb     | sadariadmin | UTF8 | ja_JP.utf8 | ja_JP.utf8 | sadariadmin=CTc/sadariadmin
 postgres  | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | 
 template0 | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | =c/postgres          +
           |          |      |            |            | postgres=CTc/postgres
 template1 | postgres | UTF8 | ja_JP.utf8 | ja_JP.utf8 | =c/postgres          +
           |          |      |            |            | postgres=CTc/postgres
-- 終了
\q

外部アクセス許可の設定

$ sudo vim /var/lib/pgsql/data/pg_hba.conf

以下を追加:

host  all  all  192.168.0.0/16  trust

PostgreSQL の設定ファイルを編集:

$ sudo vim /var/lib/pgsql/data/postgresql.conf

以下の行を変更:

listen_addresses = '*'

変更を適用:

$ sudo systemctl restart postgresql

Python & FastAPI のセットアップ

Python 3.10 以上のインストール

sudo dnf install -y python3 python3-pip python3-virtualenv

仮想環境の作成

mkdir -p ~/fastapi_app
cd ~/fastapi_app
python3 -m venv venv
source venv/bin/activate

FastAPIと依存関係のインストール

pip install fastapi uvicorn psycopg2 sqlalchemy databases

FastAPI アプリの作成

backend/main.py

from fastapi import FastAPI
from databases import Database
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String

DATABASE_URL = "postgresql://myuser:mypassword@localhost/mydatabase"

database = Database(DATABASE_URL)
metadata = MetaData()

users = Table(
"users", metadata,
Column("id", Integer, primary_key=True),
Column("name", String(100)),
)

engine = create_engine(DATABASE_URL)
metadata.create_all(engine)

app = FastAPI()

@app.on_event("startup")
async def startup():
await database.connect()

@app.on_event("shutdown")
async def shutdown():
await database.disconnect()

@app.get("/")
async def root():
return {"message": "Hello, FastAPI with PostgreSQL"}

@app.get("/users")
async def get_users():
query = users.select()
return await database.fetch_all(query)

FastAPI の起動

uvicorn backend.main:app --host 0.0.0.0 --port 8000 --reload

Node.js & Nuxt3 のセットアップ

Node.js のインストール

sudo dnf module install -y nodejs:18

バージョン確認:

shコピーする編集するnode -v
npm -v

4.2 Nuxt 3 プロジェクトの作成

mkdir -p ~/nuxt3_app
cd ~/nuxt3_app
npx nuxi init frontend
cd frontend
npm install

Nuxt 3 から FastAPI にリクエストを送る

frontend/pages/index.vue

<script setup>
import { ref, onMounted } from 'vue'

const users = ref([])

onMounted(async () => {
const res = await fetch('http://localhost:8000/users')
users.value = await res.json()
})
</script>

<template>
<div>
<h1>Users</h1>
<ul>
<li v-for="user in users" :key="user.id">{{ user.name }}</li>
</ul>
</div>
</template>

Nuxt 3 の起動

npm run dev

CORS 設定(Nuxt 3 ⇔ FastAPI)

FastAPI で CORS(クロスオリジンリクエスト)を許可する必要があります。

backend/main.py

from fastapi.middleware.cors import CORSMiddleware

app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"], # Nuxt 3 のURL
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)

FastAPI を再起動:

uvicorn backend.main:app --host 0.0.0.0 --port 8000 --reload

システムの自動起動設定

本番運用する場合、FastAPI や Nuxt 3 を systemd で管理するのが一般的です。

FastAPI の systemd 設定

sudo nano /etc/systemd/system/fastapi.service

以下を記述:

[Unit]
Description=FastAPI Application
After=network.target

[Service]
User=yourusername
WorkingDirectory=/home/yourusername/fastapi_app
ExecStart=/home/yourusername/fastapi_app/venv/bin/uvicorn backend.main:app --host 0.0.0.0 --port 8000
Restart=always

[Install]
WantedBy=multi-user.target

保存して適用:

sudo systemctl daemon-reload
sudo systemctl enable fastapi
sudo systemctl start fastapi

6.2 Nuxt 3 の systemd 設定

sudo nano /etc/systemd/system/nuxt3.service

以下を記述:

[Unit]
Description=Nuxt 3 Application
After=network.target

[Service]
User=yourusername
WorkingDirectory=/home/yourusername/nuxt3_app/frontend
ExecStart=/usr/bin/npm run dev
Restart=always

[Install]
WantedBy=multi-user.target

適用:

sudo systemctl daemon-reload
sudo systemctl enable nuxt3
sudo systemctl start nuxt3

本番運用(NGINX + SSL 設定)

sudo dnf install -y nginx certbot python3-certbot-nginx

NGINX のリバースプロキシ設定

sudo nano /etc/nginx/nginx.conf

以下を追加:

server {
listen 80;
server_name example.com;

location / {
proxy_pass http://localhost:3000;
}

location /api/ {
proxy_pass http://localhost:8000/;
}
}

適用:

sudo systemctl restart nginx

コメント

タイトルとURLをコピーしました