ホームサーバー完全構築ガイド #6 クラウドストレージの構築

<!-- START_SERIES -->

ホームサーバー完全構築ガイド シリーズ記事：

[ホームサーバー完全構築ガイド #0 計画とハードウェア選定](https://qiita.com/SolitudeRA/items/0a3f810efb315ba04fd2)
[ホームサーバー完全構築ガイド #1 OS導入と基本設定](https://qiita.com/SolitudeRA/items/aecc62f0bb4270367656)
[ホームサーバー完全構築ガイド #2 インフラの構築](https://qiita.com/SolitudeRA/items/4c6196234446c5965f23)
[ホームサーバー完全構築ガイド #3 サービス群の選定](https://qiita.com/SolitudeRA/items/78ed880f4fa89d466c1f)
[ホームサーバー完全構築ガイド #4 WordPressのデプロイ](https://qiita.com/SolitudeRA/items/ce9e9dadf46e19143656)
[ホームサーバー完全構築ガイド #5 情報収集システムの構築](https://qiita.com/SolitudeRA/items/f41e730e87181076d707)
[ホームサーバー完全構築ガイド #7 DevOpsプラットフォームの構築](https://qiita.com/SolitudeRA/items/8580cffbb7de7148366a)
[ホームサーバー完全構築ガイド #8 スマートホームプラットフォームの構築](https://qiita.com/SolitudeRA/items/9626951e8d8558ef2616)

<!-- END_SERIES -->

# はじめに

**ホームサーバー完全構築ガイド**シリーズへようこそ。このシリーズでは、ホームサーバーを活用したさまざまなシステム構築方法をご紹介しています。今回は、プライバシーとカスタマイズ性を重視したクラウドストレージ環境を構築するために、**Nextcloud** を取り上げます。

Google Drive や Dropbox などのクラウドサービスは便利ですが、データが外部サーバーに保存されるため、プライバシーやセキュリティに不安を感じる方も少なくありません。また、これらのサービスにはカスタマイズの制約があり、特定の用途やニーズに完全に対応できない場合もあります。一方で、**Nextcloud** を使用すれば、クラウドサービスと同等の利便性を保ちながら、データを完全に自分のサーバーで管理でき、自由度の高いカスタマイズが可能です。

今回の記事では、**Nginx** を Web サーバーとして採用し、提供いただいた Nginx の設定ファイルを活用します。この設定は、**Cloudflare** を DNS サービスプロバイダーとして利用することを前提としています。また、データベースには信頼性の高い **MySQL** を使用します。

# 今回のゴール

1. **Nextcloud の導入**：ホームサーバーに Nextcloud をインストールして動作させる
2. **データベースの設定**：MySQL を使用して Nextcloud のデータを管理
3. **Nginx の設定**：Cloudflare を前提とした Nginx 設定ファイルを適用
4. **セキュアな通信の設定**：Let's Encrypt を使って HTTPS 通信を実現
5. **運用の開始**：クライアントアプリのインストールや機能拡張

# 準備

## 必要な環境

- **サーバー環境**：
  - **OS**：Ubuntu Server 22.04（推奨）
  - **CPU & メモリ**：最低 2コア / 2GB RAM（推奨 4コア / 4GB RAM 以上）
  - **ストレージ**：必要な容量に応じて設定（SSD 推奨）
- **ネットワーク環境**：
  - ドメイン名（例：`example.com`）が利用可能
  - サーバーがインターネットからアクセス可能な IP アドレスを持っていること
- **DNS 設定**：
  - **Cloudflare** を DNS サービスプロバイダーとして使用し、ドメインを設定

## 必要なソフトウェアのインストール

### システムのアップデート

まず、システムを最新の状態に更新します。

```bash
sudo apt update && sudo apt upgrade -y
```

### Nginx のインストール

Nginxのインストールは[ホームサーバー完全構築ガイド #2 インフラの構築](https://qiita.com/SolitudeRA/items/4c6196234446c5965f23)を参照してください。

### PHP および関連モジュールのインストール

Nextcloud に必要な PHP とその拡張モジュールをインストールします。

```bash
sudo apt install php-fpm php-mysql php-xml php-mbstring php-curl php-zip php-gd php-intl php-bcmath php-gmp php-imagick -y
```

PHP-FPM のバージョンを確認します。

```bash
php -v
```

### MySQL のインストールと初期設定

MySQLのインストールおよび初期設定は[ホームサーバー完全構築ガイド #2 インフラの構築](https://qiita.com/SolitudeRA/items/4c6196234446c5965f23)を参照してください。

# Nextcloud のダウンロードとセットアップ

## Nextcloud のダウンロード

Nextcloud の最新バージョンを公式サイトからダウンロードします。

```bash
wget https://download.nextcloud.com/server/releases/latest.tar.bz2
```

## アーカイブの解凍

ダウンロードしたファイルを解凍し、適切なディレクトリに移動します。

```bash
tar -xjf latest.tar.bz2
sudo mv nextcloud /var/www/
```

## 権限の設定

Nextcloud のディレクトリに適切な権限を設定します。

```bash
sudo chown -R www-data:www-data /var/www/nextcloud
sudo chmod -R 755 /var/www/nextcloud
```

---

# データベースの設定

MySQL コンソールに入り、データベースとユーザーを作成します。

```bash
sudo mysql -u root -p
```

以下の SQL コマンドを実行します。

```sql
CREATE DATABASE nextcloud CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
CREATE USER 'nextclouduser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'あなたのパスワード';
GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextclouduser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```

---

# Nginx の設定

## Nginx 設定ファイルの編集

提供いただいた Nginx の設定を適用します。この設定は **Cloudflare** を DNS サービスプロバイダーとして利用することを前提としています。

設定ファイルを作成または編集します。

```bash
sudo nano /etc/nginx/sites-available/nextcloud.conf
```

以下の内容を貼り付けます（必要に応じてパスやドメイン名を調整してください）。

```nginx
upstream php-handler {
    server unix:/run/php/php8.1-fpm.sock;
}

# Cloudflare を DNS サービスプロバイダーとして利用

server {
    listen 80;
    listen [::]:80;

    server_name cloud.example.com;

    server_tokens off;

    include /etc/nginx/trust_source/cloudflare;
    deny all;

    access_log /var/log/nginx/nextcloud/access80.log;
    error_log /var/log/nginx/nextcloud/error80.log;

    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name cloud.example.com;

    server_tokens off;

    # 内部ネットワークを許可
    allow 172.19.0.0/16;

    include /etc/nginx/trust_source/cloudflare;
    deny all;

    ssl_certificate     /etc/ssl/your_ssl_cert.pem;
    ssl_certificate_key /etc/ssl/your_ssl_key.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;
    ssl_session_tickets off;

    ssl_dhparam /etc/ssl/dhparam.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:...';
    ssl_prefer_server_ciphers off;

    add_header Strict-Transport-Security "max-age=63072000" always;

    ssl_stapling on;
    ssl_stapling_verify on;

    ssl_trusted_certificate /etc/ssl/your_trusted_cert.pem;

    resolver 1.1.1.1;

    access_log /var/log/nginx/nextcloud/access443.log;
    error_log /var/log/nginx/nextcloud/error443.log;

    root /var/www/nextcloud;

    index index.php index.html /index.php$request_uri;

    client_max_body_size 512M;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;

    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;

    client_body_buffer_size 512k;

    add_header Referrer-Policy                   "no-referrer"       always;
    add_header X-Content-Type-Options            "nosniff"           always;
    add_header X-Frame-Options                   "SAMEORIGIN"        always;
    add_header X-Permitted-Cross-Domain-Policies "none"              always;
    add_header X-Robots-Tag                      "noindex, nofollow" always;
    add_header X-XSS-Protection                  "1; mode=block"     always;

    fastcgi_hide_header X-Powered-By;

    include mime.types;
    types {
        application/javascript mjs;
    }

    location = / {
        if ( $http_user_agent ~ ^DavClnt ) {
            return 302 /remote.php/webdav/$is_args$args;
        }
    }

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }

    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }

        location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

        return 301 /index.php$request_uri;
    }

    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }

    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }

    location ~ \.php(?:$|/) {
        rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;

        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        set $path_info $fastcgi_path_info;

        try_files $fastcgi_script_name =404;

        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;

        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;

        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;

        fastcgi_max_temp_file_size 0;
    }

    location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map|ogg|flac)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463, $asset_immutable";
        access_log off;

        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }

    location ~ \.woff2?$ {
        try_files $uri /index.php$request_uri;
        expires 7d;
        access_log off;
    }

    location /remote {
        return 301 /remote.php$request_uri;
    }

    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }
}
```

**注意**：

- `server_name` はあなたのドメイン名に変更してください（例：`cloud.example.com`）。
- `ssl_certificate` と `ssl_certificate_key` のパスは、あなたの SSL 証明書のパスに変更してください。
- `include /etc/nginx/trust_source/cloudflare;` は **Cloudflare** を DNS サービスプロバイダーとして使用している場合に有効です。

## Nginx 設定の有効化とテスト

設定ファイルを保存し、シンボリックリンクを作成してサイトを有効化します。

```bash
sudo ln -s /etc/nginx/sites-available/nextcloud.conf /etc/nginx/sites-enabled/
```

Nginx の設定をテストします。

```bash
sudo nginx -t
```

問題がなければ、Nginx を再起動します。

```bash
sudo systemctl restart nginx
```

---

# Let's Encrypt による HTTPS の設定

## Certbot のインストール

Let's Encrypt の Certbot をインストールします。

```bash
sudo apt install certbot python3-certbot-nginx -y
```

## SSL 証明書の取得と適用

以下のコマンドを実行し、プロンプトに従って設定します。

```bash
sudo certbot --nginx -d cloud.example.com
```

## SSL 証明書の自動更新確認

Certbot の自動更新が正しく設定されているか確認します。

```bash
sudo certbot renew --dry-run
```

---

# Nextcloud の Web 設定

ブラウザで以下の URL にアクセスします。

```
https://cloud.example.com
```

## 管理者アカウントの作成

- **ユーザー名**：任意の管理者ユーザー名
- **パスワード**：強力なパスワードを設定

## データベース設定

- **データベースの種類**：MySQL
- **データベース名**：`nextcloud`
- **データベースユーザー名**：`nextclouduser`
- **データベースパスワード**：先ほど設定したパスワード
- **データベースホスト**：`localhost`

すべて入力したら、「インストール完了」ボタンをクリックします。

---

# Nextcloud の運用開始

## クライアントアプリのインストール

- **デスクトップクライアント**：[公式サイト](https://nextcloud.com/install/#install-clients)からダウンロード
- **モバイルアプリ**：App Store や Google Play から入手可能

## アプリの追加

Nextcloud 内の「アプリ」セクションから、カレンダーやタスク管理などのアプリを追加できます。

## バックアップの設定

定期的なデータのバックアップを設定し、データの安全性を確保します。

---

# まとめ

今回のガイドでは、ホームサーバーに **Nextcloud** を導入し、プライバシーを重視したクラウドストレージ環境を構築しました。**Nginx** を使用し、Cloudflare を前提とした設定ファイルを適用することで、高性能かつセキュアなサーバーを実現しました。また、データベースには **MySQL** を使用し、安定したデータ管理を行いました。

これにより、データを自分の管理下に置きつつ、高い利便性を享受できます。ぜひ、ご自身のニーズに合わせてカスタマイズしてみてください。

---

# 参考資料

- [Nextcloud 公式サイト](https://nextcloud.com/)
- [Nextcloud 管理者マニュアル](https://docs.nextcloud.com/server/latest/admin_manual/)
- [Nginx 公式ドキュメント](https://nginx.org/en/docs/)
- [Let's Encrypt 公式サイト](https://letsencrypt.org/)
- [Certbot 公式サイト](https://certbot.eff.org/)
- [MySQL 公式ドキュメント](https://dev.mysql.com/doc/)