DockerでNextcloudと併用しつつ OJS（OpenJournalSystems）を構築する

## はじめに
現在プライベートクラウドとしてDockerでNextCloudを運用しています。
今回それにOJSというジャーナルシステムを稼働するオープンソースソフトウェアを導入した話です。
意外や意外！OJSはQiitaの記事では１つも見つかりませんでした。（私の探し方が悪い？）

### OJS (Open Journal Systems) とは？
OJS は、Public Knowledge Project (PKP) によって開発されたオープンソースの学術誌管理システムです。
論文の投稿や査読、編集、公開を一元管理でき、多言語対応やオープンアクセス支援機能を備えています。
大学や学会、出版社で広く利用されており、カスタマイズ性も高いため、様々な学術運営に対応可能です。

Docker による構築が公式にサポートされているため、Nextcloud などと組み合わせて効率的な運用環境を構築することが可能。


### 環境:
* Ubuntu Server (24.04)
* Docker / Docker Compose
* Nextcloud（apache + mariadb）と OJS（pkpofficial/ojs:latest + mariadb）を共存

この記事では、Docker Compose ファイル一つで Nextcloud と OJS を同じサーバー上で動かす方法を紹介します。

## 1. 構成概要

### 1.1 アーキテクチャ

```
[Ubuntu Server]
 ├─ Docker
 │   ├─ nextcloud-db (MariaDB)
 │   ├─ nextcloud (Apache, Nextcloud本体)
 │   ├─ ojs-db (MariaDB)
 │   └─ ojs-app (Apache + OJS)
 └─ 80/443 ポート
```

**Nextcloud:**
* ポート 80/443 をホストに割り当て（0.0.0.0:80->80, 0.0.0.0:443->443）
* データボリューム + MariaDB

**OJS:**
* ポートはホスト側で 8081 などを使い、コンテナ 80 にマッピング
* 別の MariaDB コンテナ (ホスト側 3307 → コンテナ 3306) を用意して競合を避ける

### 1.2 メリット・デメリット

**メリット**
* 1台のサーバで学術誌管理 (OJS) とファイル共有 (Nextcloud) を同時に運用
* Docker Compose でコンテナ管理しやすい
* SSL 証明書などもまとめて管理できる（Nginx リバースプロキシを挟む場合はさらに便利）

**デメリット**
* ホストポートが競合しないようポート設計が必要
* コンテナが増えるぶんメモリなどリソースに余裕が必要（8GBあれば余裕）
* Nextcloud と OJS のどちらもデータが肥大化するとバックアップ管理が大変

## 2. Docker Compose 設定例

以下はあくまで個人の一例です。

```yaml
version: '3.3'

volumes:
  nextcloud:
  nextcloud_db:
  ojs_db:
  ojs_files:
  ojs_logs:
  # 必要に応じて config なども

services:
  #--- Nextcloud 用 MariaDB --------------------------------
  nextcloud-db:
    image: mariadb:11.4
    container_name: nextcloud-db
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=NextcloudRootPass
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=NextcloudPass
    volumes:
      - nextcloud_db:/var/lib/mysql
    ports:
      - "3306:3306"  # Nextcloud用DBはホストの3306使う

  #--- Nextcloud アプリ ------------------------------------
  nextcloud:
    image: nextcloud:latest
    container_name: nextcloud-app
    depends_on:
      - nextcloud-db
    restart: always
    ports:
      - "80:80"     # ホスト80にバインド
      - "443:443"   # ホスト443にバインド
    volumes:
      - nextcloud:/var/www/html
      # もしホスト直下にデータ保存したいなら:
      # - /media/hoge/data:/var/www/html/data
    environment:
      - MYSQL_HOST=nextcloud-db
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=NextcloudPass
      - MYSQL_DATABASE=nextcloud

  #--- OJS 用 MariaDB --------------------------------------
  ojs-db:
    image: mariadb:latest
    container_name: ojs-db
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=OjsRootPass
      - MYSQL_DATABASE=ojs
      - MYSQL_USER=ojs
      - MYSQL_PASSWORD=OjsPass
    volumes:
      - ojs_db:/var/lib/mysql
    ports:
      - "3307:3306"  # ポート競合しないように

  #--- OJS アプリ ------------------------------------------
  ojs-app:
    image: pkpofficial/ojs:latest
    container_name: ojs-app
    depends_on:
      - ojs-db
    restart: always
    ports:
      - "8081:80"    # ホストの8081でアクセス (コンテナ80)
    volumes:
      - ojs_files:/var/www/files
      - ojs_logs:/var/log/apache2
    environment:
      # OJS用に必要:
      - SERVERNAME=ojs.example.com
      - OJS_DB_HOST=ojs-db
      - OJS_DB_USER=ojs
      - OJS_DB_PASSWORD=OjsPass
      - OJS_DB_NAME=ojs
```

### 2.1 ポイント解説

**Nextcloud と OJS それぞれに MariaDB を別途用意**
* Nextcloud 用: 3306
* OJS 用: 3307 → 3306 (ホスト→コンテナ)
* 1つにまとめても良いが、スキーマ管理やバージョン違いの衝突を防ぐために分離が無難。

**ポート競合回避**
* Nextcloud は 80,443
* OJS は 8081 (必要なら 8443 などで SSL 対応も検討)

**volumes**
* Nextcloud: nextcloud, nextcloud_db
* OJS: ojs_db, ojs_files, ojs_logs
* データを永続化しておき、コンテナ再作成しても消えないようにする。（重要）

https://qiita.com/yu_uk/items/82d1ec6543c736fe0836

**環境変数**
* OJS_DB_HOST は ojs-db、MYSQL_HOST は nextcloud-db
* Docker Compose が内部 DNS を提供するため、コンテナ名でアクセスできる。

## 3. 起動〜アクセス手順

1. **docker-compose.yml を準備**
   * 上記内容を docker-compose.yml として保存。

2. **コンテナ起動**
```bash
docker-compose up -d
```
しばらく待つと各コンテナが立ち上がります。

3. **状態確認**
```bash
docker ps
```
* nextcloud-db, nextcloud-app, ojs-db, ojs-app が Up になっているか
* 0.0.0.0:80->80, 0.0.0.0:443->443, 0.0.0.0:8081->80, 0.0.0.0:3307->3306 などが表示されればOK

4. **Nextcloud へのアクセス**
* ブラウザで http://<サーバーIP>
* インストール画面やログイン画面が出るので、設定を行う。

5. **OJS へのアクセス**
* ブラウザで http://<サーバーIP>:8081
* OJS のインストール画面が表示されるはず。
* DB 接続（ojs-db:3306、ユーザ名: ojs、パス: OjsPass）を入力してセットアップ。

## 4. SSL (Let's Encrypt) 設定について

### 4.1 Nextcloud だけ SSL
* とりあえず Nextcloud は 443 で自動更新の Let's Encrypt 証明書を設定し、OJS は HTTP のみ (ポート 8081) というケース。
* Nextcloud で Apache の default-ssl.conf を書き換えたり、certbot --apache を使う。
* OJS はローカルアクセスや VPN (Tailscale) 経由なら HTTP でもいいかもしれない。

### 4.2 OJS にも SSL を付けたい
* ホストの 443 を Nextcloud が使っているなら、別のポート (8443 など) を OJS に割り当てる。
* あるいは Nginx や Traefik のリバースプロキシを立てて、ドメインやパスごとに振り分ける。
* 例:
  * https://nextcloud.hogehoge.com → Nextcloud コンテナへ
  * https://ojs.hogehoge.com → OJS コンテナへ
* リバースプロキシ を挟むと、証明書・SSL ターミネーションを一元管理できて便利。ただし多少手間は増える。

## 5. トラブルシューティング

### 5.1 ポートが既に使用中で起動できない
* 80 や 443 を別のサービス (Apache/Nginx) が使っている場合、先に停止するか ポートを変える。
* `sudo systemctl stop apache2` などで既存のサービスを止めておく。

### 5.2 OJS のインストールがうまくいかない
**DB エラー:**
* 「SQLSTATE[HY000] [2002] No such file or directory」 → OJS_DB_HOST が間違っているか、ojs-db コンテナが起動していない。
* `docker logs ojs-db` でエラーログ確認。

**mysql コマンドが見つからない:**
* コンテナ内に MariaDB クライアントがないケース。
* `apt install mariadb-client` (Debian系イメージなら) で追加。

### 5.3 Nextcloud が動かない or SSL が変
* `docker logs nextcloud-app` で Apache/PHP エラーを確認。
* config.php や trusted_domains の設定がずれているとアクセス拒否される。
* SSL は certbot コマンドや a2enmod ssl, a2ensite default-ssl.conf など Apache で有効化を要確認。

### 5.4 "同じファイルサーバで運用するのって大丈夫？"
* リソースが足りるなら問題ない（と思ってます）
* 同時アクセスが多いジャーナルサイト (OJS) と大容量ファイルを共有する Nextcloud だと、DB 負荷やネットワーク帯域に注意する。
* 高負荷ならサーバ増設やリバースプロキシ分離を検討。

## 6. 運用上のヒント

### バックアップ
* Nextcloud は /var/www/html 直下に data ディレクトリ、OJS は /var/www/files がデフォルト。
* マリアDB 側は定期 mysqldump。
* コンテナ設定を見直す際は `docker-compose down --volumes` などで誤ってデータを消さないよう注意。

https://qiita.com/yu_uk/items/82d1ec6543c736fe0836

### アップデート
* `docker pull nextcloud:latest` / `docker pull pkpofficial/ojs:latest`
* `docker-compose up -d --build` で再起動するとイメージ更新 → それぞれのアップグレードを実行。

### ドメイン振り分け（リバースプロキシ）
* 1つのサーバで複数ドメインを持つなら、Nginx (or Traefik) で HTTPS 化 & サブドメイン振り分けが王道。
* docker-compose でリバースプロキシコンテナを追加し、virtual host の設定をする。

## まとめ

以上、Nextcloud と併用しつつ OJS を Docker で同居させる手順を紹介しました。

* Docker Compose 一発で Nextcloud + OJS + MariaDB をそれぞれ起動可能
* ポート競合を避けるために Nextcloud は 80/443、OJS は 8081 などに振り分け
* いずれもデータはボリューム永続化
* SSL やリバースプロキシを使えば外部公開がスムーズ

注意点は、ボリューム初期化のリスク（--volumes でうっかり消さない）、DB の設定ミス、ファイアウォール設定などです。

何回貼るねん！

https://qiita.com/yu_uk/items/82d1ec6543c736fe0836

もし「ローカルからアクセスできない」「SSL の設定がおかしい」「OJS の DB 接続でこける」といったトラブルがあれば、
* `docker logs <コンテナ名>`
* `docker ps -a`
* docker-compose.yml の書き間違い
* ポートやファイアウォールの状況
…を順番に確認すると原因が分かることが多いです。

Nextcloud で大容量ファイルを管理しつつ、OJS で学術ジャーナルを運営したい場面はそう多くないかもしれませんが、**"1台のサーバーにまとめたい"**というニーズには非常に便利な方法です。必要に応じてコンテナを追加して拡張していきましょう。

## 参考リンク
* [PKP Official Docker OJS](https://github.com/pkp/docker-ojs)
* [Docker Hub: pkpofficial/ojs](https://hub.docker.com/r/pkpofficial/ojs)
* [Nextcloud公式 Docker イメージ](https://hub.docker.com/_/nextcloud)
* [Mariadb 公式イメージ](https://hub.docker.com/_/mariadb)
* [PKP Official OJS](https://pkp.sfu.ca/software/ojs/)

この記事が少しでも参考になれば幸いです。
「こんな構成で運用しているよ」「SSL/リバプロの設定でこう工夫した」など、
ぜひコメントで教えてください！