はじめに:技術ブログ「楽パ」へようこそ!
皆さん、こんにちは!技術系ブログ「楽パ(rakupa.net)」へようこそ。このブログは、「More than tech, it’s a movement」をキャッチフレーズに、テクノロジーをより身近に感じ、楽しんでいただくことを目指しています。
この記事では、当ブログ「rakupa.net」が実際にどのように構築されているのか、その舞台裏を余すところなく公開します!対象読者は、ITに関する基本的な知識(IPアドレス、ドメイン、サーバーなど)を少しお持ちの方を想定しています。
なぜrakupa.netを自作サーバーで構築したのか?
- 低コスト: 商用サーバーに比べて、大幅に費用を抑えられます。
- 独自ドメイン: 自分の好きなドメイン名(rakupa.net)を使えます。
- 独自メールサーバー: 自分だけのメールアドレス(例えば、your.awsome.name@rakupa.net)を自由に作成・運用できます。
- 技術的好奇心: サーバー構築の技術を学び、実践する場として最適です。
ハードウェア構成:縁の下の力持ちたち
まずは、rakupa.netを支えるハードウェア構成から見ていきましょう。
ネットワーク構成
ネットワーク環境は、以下のようになっています。
- 回線: 光回線(2Gbps、複数IPv4グローバルIP割り当て可能)
- IPアドレス: 動的IP(ただし、ONUを再起動しない限り、経験上ほとんど変動しません)
サーバーを設置するにあたり、個人利用のネットワークとは分離したかったので、次のような構成にしました。
- ONU(光回線終端装置)からスイッチングハブ(L2)へ接続。
- スイッチングハブから、サーバー専用のミニPCへ直接LANケーブルを接続。
- ミニPCにグローバルIPアドレスを割り当て。
光回線 -[ONU] -- [スイッチングハブ] -- [ミニPC (本サーバー)]
|
[個人用ルーター]
|
+-- [個人用PCなど]
こうすることで、サーバーと個人利用のPCを論理的に分離し、セキュリティを高めています。
ミニPCのスペック

サーバーとして使用しているのは、Amazonで購入した中華製の2万円台の激安ミニPCです。
- CPU: Intel N100 (4コア/4スレッド、最新Intel 7半導体プロセス)
- RAM: 16GB LPDDR5
- SSD: 512GB M.2 SATA
- LAN: 1Gbps × 2ポート
- OS: Windows 11 Pro (購入後クリーンインストール)
このミニPCを選んだ理由は、
- 低消費電力: 電気代が高騰している昨今、省エネ性能は重要です。
- 十分な性能: N100は、価格の割に性能が良く、Webサーバーとしては十分です。
- 将来性: LANポートが2つあるので、将来的にロードバランシングや他のWebアプリケーションのホスティングも検討できます。
補足:2Gbps回線を生かし切れていない?
1GbpsのLANポートでは、2Gbpsの回線速度をフルに活用できません。しかし、現状ではWebサーバーのトラフィックはそれほど多くないため、問題ありません。将来的には、2つ目のLANポートを活用し、他のWebアプリケーションやゲームサーバーをホストしたり、ロードバランシングを導入したりすることも視野に入れています。
ソフトウェア構成:動かす仕組みを作る
次に、サーバー上で動いているソフトウェアについて解説します。
OS: Windows 11 Pro
OSには、Windows 11 Proを選びました。Linuxサーバーの方が一般的かもしれませんが、
- 使い慣れているWindows環境でサーバーを構築したかった。
- WSL2(Windows Subsystem for Linux 2)を使えば、Linux環境も利用できる。
- RDP (リモートデスクトップ接続) で簡単に管理できる。
といった理由から、Windows 11 Proを選択しました。
Docker DesktopとDocker Compose
ブログ本体(WordPress)は、Docker Desktop上でDocker Composeを使って構築しています。
- Dockerとは?
コンテナと呼ばれる仮想環境でアプリケーションを動かす技術です。環境構築を簡単にし、OSに依存せずにアプリケーションを実行できます。 - LinuxとDocker:
Dockerは元々Linuxの技術ですが、WindowsでもDocker Desktopを使うことで利用できます。 - WSL2とは?
Windows上でLinuxカーネルを動かす仕組みです。Docker DesktopはWSL2を利用することで、よりLinuxに近い環境でコンテナを実行できます。
Docker Composeを使うと、複数のコンテナをまとめて定義・管理できるため、WordPressのような複数のコンポーネント(Webサーバー、データベースなど)からなるアプリケーションの構築が容易になります。
MySQL 8: Windowsホストに直接インストール
データベースにはMySQL 8を使用していますが、これはDockerコンテナではなく、Windowsホストに直接インストールしました。
なぜDockerコンテナにしないのか?
- DBをサービスとして利用: WordPressだけでなく、後述するメールサーバー(hMailServer)など、他のアプリケーションからもMySQLを利用するためです。
- パフォーマンス: ホストOSに直接インストールした方が、若干パフォーマンスが良い場合があります(特にI/O)。
インストール手順
- Oracle公式サイトからMySQL 8のインストーラーをダウンロードします。
- インストーラーを実行し、画面の指示に従ってインストールを進めます。
- インストールタイプは「Server Only」を選択しました。
- rootパスワードを設定します。
WordPressセットアップ:ブログの顔を作る
いよいよWordPressのセットアップです。
WordPressは、ざっくり言うと、
- Webサイトやブログを簡単に作れる、世界中で人気のオープンソースのCMS(コンテンツ管理システム) です。
- PHP というプログラミング言語で書かれていて、MySQL などのデータベースと連携して動きます。
- テーマ でデザインを自由に着せ替えでき、プラグイン で機能を追加できます。(例:お問い合わせフォーム、SEO対策、ECサイト化など)
- HTML/CSSの知識があれば、より高度なカスタマイズも可能です。
- サーバーにインストールして使う WordPress.org と、ブログサービスとして提供される WordPress.com の2種類があります。(通常、技術的な話をする場合は .org の方を指します)
- Gutenberg(グーテンベルク)というブロックエディターで、直感的にコンテンツを作成できます。
- コミュニティが活発で、情報やサポートが豊富です。
といった特徴があります。技術的な補足としては、
- REST APIが提供されており、外部アプリケーションとの連携も可能です。
- カスタム投稿タイプやカスタムフィールドを駆使すれば、様々な種類のWebサイトを構築できます。
- セキュリティ対策は重要で、定期的なアップデートや適切なプラグインの選定が必要です。
ドメイン取得とDNSレコード設定
まず、ブログのURLとなるドメイン(rakupa.net)をお名前.comで取得しました。
- お名前.comを選んだ理由: 初年度無料で一部のドメインを取得できるキャンペーンがあったためです。
- DNSレコード設定: ドメインを取得したら、DNSレコードを設定する必要があります。
- Aレコード: rakupa.net をミニPCのグローバルIPアドレスに紐付けます。
- MXレコード: メールサーバー(後述)を指定します。
- その他: SPFレコード、DKIMレコードなど、メールの信頼性を高めるためのレコードも設定します。
Let’s EncryptでSSL証明書を取得
WebサイトをHTTPS化(暗号化)するために、Let’s Encryptで無料のSSL証明書を取得します。
- Let’s Encryptとは?
無料でSSL証明書を発行してくれる認証局です。 - Certbot:
Let’s Encryptの証明書を簡単に取得・更新できるツールです。
CertbotもDockerコンテナとして動かします。
nginxでリバースプロキシ設定
Webサーバーにはnginxを使用しています。
- リバースプロキシとは?
クライアントからのリクエストを受け取り、適切なサーバー(今回はWordPressコンテナ)へ転送する役割を担います。
nginxの主な役割は、
- HTTPからHTTPSへのリダイレクト: すべてのHTTPリクエストをHTTPSにリダイレクトし、安全な通信を確保します。
- URLパスベースのルーティング: rakupa.net/app1、rakupa.net/app2 のように、URLのパスに応じて異なるアプリケーションにリクエストを振り分けられます。
- サブドメイン運用: app1.rakupa.net、app2.rakupa.net のようなサブドメインで複数のアプリケーションを運用することも可能です(ただし、サブドメインごとにSSL証明書が必要になります)。
Docker ComposeでWordPressインストール
WordPressのインストールには、Docker Composeを使用します。
- ホスト側のMySQLに接続: WordPressコンテナから、WindowsホストにインストールしたMySQLに接続します。
- Named Docker Volume: WordPressのファイル群を保存するために、Named Docker Volumeを使用します。
- なぜNamed Volume? Windows環境では、ファイルシステムの違いから、バインドマウント(ホストのディレクトリを直接マウントする方法)よりもNamed Volumeの方がパフォーマンスが良くなります。
独自メールサーバー構築:自分だけのメールアドレス
独自ドメインの魅力の一つは、自分だけのメールアドレス(例:myblog@rakupa.net)を持てることです。
hMailServerの採用
Windowsで動作するメールサーバーソフトウェアとして、hMailServerを採用しました。
- hMailServerを選んだ理由:
- オープンソース、無料で利用できる。
- Windows環境で比較的簡単に設定できる。
- MySQLをデータベースとして利用できる。
DNSレコード設定(MXレコードなど)
メールサーバーを運用するためには、DNSレコードの設定が必要です。
- MXレコード: どのサーバーがメールを受信するかを指定します。mail.rakupa.net を指定します。
- SPFレコード: 自分のドメインから送信されるメールが、どのサーバーから送信されるかを宣言します。
- DKIMレコード: 送信メールに電子署名を付加し、なりすましを防ぎます。
mail.rakupa.netのSSL証明書取得
メールの送受信を暗号化するために、mail.rakupa.net のSSL証明書もLet’s Encryptで取得します。
STARTTLSによる接続暗号化
hMailServerでは、STARTTLSという方式でメールの送受信を暗号化できます。
- STARTTLSとは?
最初は平文で接続し、途中から暗号化通信に切り替える方式です。多くのメールクライアントが対応しており、互換性に優れています。
PTRレコード未設定の理由
通常、メールサーバーの信頼性を高めるために、PTRレコード(IPアドレスからドメイン名を逆引きできるようにするレコード)を設定することが推奨されます。しかし、今回は設定していません。
- 理由:
- 動的IPアドレスを使用しているため、PTRレコードを頻繁に更新する必要がある。
- ISPによっては、動的IPアドレスに対するPTRレコードの設定を許可していない場合がある。
Gmailなどへの送信テスト
PTRレコードを設定していないため、迷惑メールとして扱われる可能性を懸念しましたが、実際にGmailなどの主要なメールサービスにテストメールを送信したところ、TLS暗号化の状態で問題なく受信できました。

オプション:法人向けメールリレーサービスについて
SendGridのような法人向けのメールリレーサービスの無料プランも検討しましたが、個人では利用できないようでした。
設定ファイル詳細:舞台裏を覗いてみよう
ここからは、実際に使用している設定ファイルの中身を公開します。
docker-compose.yml
services:
nginx:
image: nginx:latest
restart: always
ports:
- "80:80" # HTTPポート
- "443:443" # HTTPSポート
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf # nginx設定ファイル
- ./certbot/conf:/etc/letsencrypt # Certbotの証明書保存先
- ./certbot/www:/var/www/certbot # CertbotのWebrootパス
depends_on:
- wordpress
networks:
- wordpress_network
command: /bin/sh -c "nginx && while true; do sleep 12h && nginx -s reload; done" # nginxを起動し、12時間ごとに設定をリロード
certbot:
image: certbot/certbot
volumes:
- ./certbot/conf:/etc/letsencrypt # Certbotの証明書保存先
- ./certbot/www:/var/www/certbot # CertbotのWebrootパス
- ./certbot:/usr/scripts # Certbotのスクリプト保存先
entrypoint: ["/bin/sh", "/usr/scripts/certbot-entrypoint.sh"] # 証明書自動更新スクリプトを実行
wordpress:
image: wordpress:latest
container_name: wordpress
environment:
WORDPRESS_DB_HOST: host.docker.internal:3306 # WindowsホストのMySQLに接続
WORDPRESS_DB_USER: app # データベースユーザー名
WORDPRESS_DB_PASSWORD: yourpassword # データベースパスワード(各自設定してください!)
WORDPRESS_DB_NAME: wp # データベース名
volumes:
- ./php/custom.ini:/usr/local/etc/php/conf.d/custom.ini # php.ini設定ファイル
- wordpress_data:/var/www/html # WordPressファイル保存用のNamed Volume
restart: always
networks:
- wordpress_network
networks:
wordpress_network:
external: true
volumes:
wordpress_data:
解説
- nginx:
- image: 最新版のnginxイメージを使用します。
- ports: ホストの80番ポートと443番ポートをコンテナの80番ポートと443番ポートにマッピングします。
- volumes:
- nginx.conf: nginxの設定ファイルをコンテナにマウントします。
- /etc/letsencrypt: Certbotで取得したSSL証明書を保存するディレクトリです。
- /var/www/certbot: CertbotがWebroot認証に使用するディレクトリです。
- depends_on: WordPressコンテナが起動してからnginxコンテナを起動するようにします。
- command: nginxを起動し、12時間ごとに設定ファイルをリロードします。
- certbot:
- image: certbot/certbotイメージを使用します。
- volumes:
- /etc/letsencrypt: Certbotの証明書保存先をホストと共有します。
- /var/www/certbot: CertbotのWebrootパスをホストと共有します。
- /usr/scripts: 証明書自動更新スクリプトをコンテナにマウントします。
- entrypoint: コンテナ起動時に証明書自動更新スクリプトを実行します。
- wordpress:
- image: 最新版のWordPressイメージを使用します。
- environment:
- WORDPRESS_DB_HOST: host.docker.internal を指定することで、WindowsホストのMySQLに接続できます。
- WORDPRESS_DB_USER、WORDPRESS_DB_PASSWORD、WORDPRESS_DB_NAME: MySQLの接続情報を設定します。
- volumes:
- ./php/custom.ini:/usr/local/etc/php/conf.d/custom.ini: PHPの設定ファイル(php.ini)をコンテナ内の/usr/local/etc/php/conf.d/ディレクトリにマウントします。*.iniファイルはPHPによってロードされ、設定が上書きされます。ファイル名の辞書順で読み込まれるので、custom.iniというファイル名にすることで、デフォルト設定を上書きしやすくなります。
* wordpress_data:/var/www/html: WordPressのファイル群をNamed Volumeに保存します。
Certbotコマンドと自動更新スクリプト
証明書取得コマンド(初回のみ)
# rakupa.netの証明書取得
docker-compose run --entrypoint "certbot certonly --webroot --webroot-path=/var/www/certbot --email your-email@example.com --agree-tos --no-eff-email -d rakupa.net" certbot
# mail.rakupa.netの証明書取得
docker-compose run --entrypoint "certbot certonly --webroot --webroot-path=/var/www/certbot --email your-email@example.com --agree-tos --no-eff-email -d mail.rakupa.net" certbot
- –webroot: Webroot認証を使用することを指定します。
- –webroot-path: Webrootパスを指定します。
- –email: メールアドレスを指定します(証明書の有効期限切れ通知などに使用されます)。
- –agree-tos: 利用規約に同意します。
- –no-eff-email: EFF(電子フロンティア財団)にメールアドレスを共有しないようにします。
- -d: 証明書を取得するドメイン名を指定します。
証明書自動更新スクリプト (certbot-entrypoint.sh)
#!/bin/sh
while true; do
echo "証明書を更新します..."
certbot renew || echo "Certbotの更新に失敗しました"
echo "12時間待機します..."
sleep 12h
done
このスクリプトは、Certbotコンテナの起動時に実行され、12時間ごとに証明書の更新を試みます。
nginx設定ファイル
初期設定 (初回Certbot認証用)
events {}
http {
server {
listen 80;
server_name rakupa.net;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
}
この設定は、CertbotがLet’s Encryptの認証を行う際に必要となる一時的なものです。
運用時設定
events {}
http {
client_max_body_size 2048M; # アップロードファイルサイズ制限
server {
listen 80;
server_name rakupa.net;
return 301 https://$host$request_uri; # HTTPをHTTPSにリダイレクト
}
server {
listen 443 ssl;
server_name rakupa.net;
ssl_certificate /etc/letsencrypt/live/rakupa.net/fullchain.pem; # SSL証明書
ssl_certificate_key /etc/letsencrypt/live/rakupa.net/privkey.pem; # 秘密鍵
location / {
proxy_pass http://wordpress:80; # WordPressコンテナにリクエストを転送
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
server {
listen 80;
server_name rakupa.net mail.rakupa.net;
# Certbot自動更新のときに、 ACME Challengeに使う場所
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
}
解説
- client_max_body_size: アップロードできるファイルの最大サイズを設定します(WordPressのメディアライブラリなどで大きなファイルをアップロードする場合に必要)。
- 最初のserverブロック:
- 80番ポート(HTTP)でリクエストを受け付けます。
- rakupa.net 宛のリクエストをすべてHTTPSにリダイレクトします。
- 2番目のserverブロック:
- 443番ポート(HTTPS)でリクエストを受け付けます。
- ssl_certificate と ssl_certificate_key: SSL証明書と秘密鍵のパスを指定します。
- location /:
- proxy_pass: リクエストをWordPressコンテナ(http://wordpress:80)に転送します。
- proxy_set_header: リクエストヘッダーを設定し、WordPressにクライアントのIPアドレスなどの情報を正しく伝えます。
- 3番目のserverブロック:
- listen 80;: 80番ポート(HTTP)でリクエストを受け付けます。(Certbotの検証は通常HTTPで行われるため)
- server_name rakupa.net mail.rakupa.net;: rakupa.net および mail.rakupa.net 宛のリクエストを処理します。
- location /.well-known/acme-challenge/ { … }: Let’s EncryptのCertbotがドメインの所有権を検証するために使用する特別なディレクトリへのリクエストを処理します。
php.ini (WordPress向け推奨設定)
; ファイルアップロードサイズ上限
upload_max_filesize = 512M
post_max_size = 512M
; メモリ上限
memory_limit = 256M
; 実行時間上限
max_execution_time = 300
max_input_time = 300
これらの設定は、WordPressのパフォーマンスや安定性を向上させるために推奨されるものです。
- upload_max_filesize、post_max_size: アップロードできるファイルの最大サイズを設定します。
- memory_limit: PHPが使用できるメモリの上限を設定します。
- max_execution_time、max_input_time: スクリプトの実行時間と入力時間の制限を設定します。
セキュリティ対策:安全第一!
自宅サーバーを運用する上で、セキュリティ対策は非常に重要です。
Windows Firewall設定
サーバーPCにグローバルIPアドレスを直接割り当てているため、Windows Firewallの設定は特に重要です。
- ネットワークプロファイル: 「パブリックネットワーク」に設定します。
- 不要なポートの無効化: 外部からの不要なアクセスを防ぐために、使用しないポートはすべて無効にします。
- RDPのソースIP制限: リモートデスクトップ接続(RDP)を使用する場合は、接続元のIPアドレスを制限し、不正アクセスを防ぎます。
ネットワークログ記録
現時点では導入していませんが、将来的にはネットワークログを記録し、分析することを検討しています。
- メリット:
- 不正アクセスの早期発見
- 問題発生時の原因究明
- セキュリティインシデントの証拠保全
脆弱性スキャン
パスワードの徹底的に管理もちろん、定期的に脆弱性スキャンを行い、サーバーにセキュリティ上の問題がないかを確認しています。
- 使用ツール:
- Nmap: ポートスキャンを行い、開いているポートや動作しているサービスを特定します。
- Nessus (Community Edition): より詳細な脆弱性スキャンを行います。
- HostedScan.com (無料プラン): 外部から脆弱性スキャンを行います。
WordPressとDockerイメージの脆弱性対策
- WordPress: 自動更新を有効にし、常に最新の状態を保ちます。
- Dockerイメージ: 使用するイメージの脆弱性情報を定期的に確認し、必要に応じてイメージを更新します。
アンチウイルスソフトは不要?
サーバー専用のPCであるため、基本的にはアンチウイルスソフトは不要と考えています。
- 理由:
- 外部からファイルをダウンロードしたり、怪しいWebサイトを閲覧したりすることがないため、ウイルスに感染するリスクが低い。
- アンチウイルスソフトがリソースを消費し、サーバーのパフォーマンスに影響を与える可能性がある。
- 不安な場合: Windows Defender(Windows 11に標準搭載されているセキュリティ機能)で十分な保護が得られます。
今後の展望:さらなる進化を目指して
Kubernetes (k8s) によるサーバーのクラスター化:
- 複数台のサーバーをKubernetesでクラスター化し、WordPressを運用することを検討しています。
- これにより、Webサイトの負荷分散を実現し、アクセス集中時でも安定した表示速度を維持します。
- さらに、耐故障性も向上させ、一部のサーバーに障害が発生した場合でも、サイト全体のダウンタイムを最小限に抑えることを目指します。
サイトのDBとWebアプリケーションのバックアップ
データの損失を防ぐために、定期的なバックアップは不可欠です。今後は、自動化されたバックアップシステムを構築する予定です。(Kubernetesの機能を活用したバックアップも視野に入れます)
【更新(2025年9月13日)】サイトのDBとWebアプリケーションのバックアップを自動化
データの損失は、個人ブログであっても致命的な事態に繋がりかねません。ハードウェアの故障、誤操作、あるいはサイバー攻撃など、データ消失のリスクは常に存在します。そこで、以前「今後の展望」としていたバックアップシステムの構築を実装しました。
今回は、「MySQLデータベース」と「WordPressのデータ一式」を毎日自動でバックアップし、圧縮後にGoogle Driveへアップロードするという、堅牢かつ低コストな仕組みをPowerShellスクリプトで実現します。
バックアップ戦略の全体像
今回の戦略は、広く推奨されている「3-2-1ルール」(3つのコピー、2種類のメディア、1つはオフサイト)を意識しています。
- 何を:
- MySQLデータベース(記事、ユーザー情報など)
- WordPressの全データ(テーマ、プラグイン、アップロードしたメディアファイルなど)が格納されたDockerボリューム
- いつ:
- 毎日深夜(Windowsのタスクスケジューラでスクリプトを自動実行)
- どこへ:
- ローカルサーバーの一時フォルダにバックアップを作成・圧縮
- 圧縮したファイルをオフサイト(Google Drive)へアップロード
- 世代管理:
- ローカルとGoogle Driveの両方で、直近14日分のバックアップを保持し、それより古いものは自動的に削除
使用するツール
この自動化システムは、以下のツールを連携させて実現しています。
- PowerShell: Windows標準の強力なスクリプト環境。すべての中核を担います。
- mysqldump: MySQL公式のバックアップツール。データベースをSQLファイルとして出力します。
- Docker: WordPressデータが格納されているDockerボリュームにアクセスし、中身をアーカイブします。
- 7-Zip (推奨): 高い圧縮率を誇る無料のアーカイバ。インストールされていない場合は、Windows標準のZIP機能に自動で切り替わります。
- rclone: 様々なクラウドストレージに対応したコマンドラインツール。Google Driveとの連携に利用します。
バックアップシステム構築手順
それでは、具体的な構築手順をステップごとに解説します。
ステップ1: Google Drive APIの有効化と認証情報の設定
rcloneがGoogle Driveにアクセスするためには、Google Cloud Platform (GCP)でAPIを有効化し、認証情報を取得する必要があります。
- GCPプロジェクトの作成:
- Google Cloud Platform コンソールにアクセスし、新しいプロジェクトを作成します(既存のプロジェクトでも構いません)。
- Google Drive APIの有効化:
- 左上のナビゲーションメニューから「APIとサービス」>「ライブラリ」を選択します。
- 検索バーに「Google Drive API」と入力し、表示されたAPIを選択して「有効にする」をクリックします。
- OAuth 2.0 クライアントIDの作成:
- 「APIとサービス」>「認証情報」に移動します。
- 画面上部の「+ 認証情報を作成」をクリックし、「OAuth クライアント ID」を選択します。
- 「アプリケーションの種類」で「デスクトップアプリ」を選択し、任意の名前(例: rclone-backup-client)を付けます。
- 「作成」をクリックすると、「クライアントID」と「クライアントシークレット」が表示されます。この2つの情報は後で使うので、必ずメモしておいてください。
ステップ2: rclone の設定
次に、サーバー上でrcloneを設定し、Google Driveに接続できるようにします。
- rclone公式サイトからWindows向けのrcloneをダウンロードし、解凍したrclone.exeを任意の場所(例: C:\rclone\)に配置します。
- コマンドプロンプトまたはPowerShellを開き、rclone configコマンドを実行します。
- ここからは対話形式で設定を進めます。
- n) New remote を選択 -> n を入力してEnter
- name> -> 任意のリモート名(例: gdrive)を入力してEnter
- Storage> -> drive (Google Drive) を見つけて対応する番号を入力してEnter
- client_id> -> ステップ1で取得したクライアントIDを貼り付けてEnter
- client_secret> -> ステップ1で取得したクライアントシークレットを貼り付けてEnter
- scope> -> 1 (Full access all files, except AppData folder) を選択 -> 1 を入力してEnter
- root_folder_id> -> そのままEnter
- service_account_file> -> そのままEnter
- Edit advanced config? -> n (No) を入力してEnter
- Use auto config? -> y (Yes) を入力してEnter
- ブラウザが自動的に起動し、Googleアカウントへのログインとアクセス許可を求められます。バックアップに使用したいアカウントを選択し、アクセスを許可してください。
- コマンドプロンプトの画面に「Success!」と表示されれば認証成功です。
- y) Yes this is OK -> y を入力してEnter
- q) Quit config -> q を入力してEnter
これでrcloneからgdrive:という名前でGoogle Driveにアクセスできるようになりました。
ステップ3: バックアップスクリプトの作成と解説
以下が実際に使用しているPowerShellスクリプト(backup-wordpress.ps1)です。このスクリプトをサーバーの任意の場所に保存します。
[CmdletBinding()]
param(
# --- 環境に合わせて変更してください ---
[string]$MySqlBinPath = "your mysql installation path\MySQL\MySQL Server 8.4\bin",
[string]$DbHost = "127.0.0.1",
[int] $DbPort = 3306,
[string]$DbName = "your db name",
[string]$DbUser = "your db user",
[string]$DbPassword = "your db password", # DBのパスワード
[string]$DockerVolumeName = "wordpress_wordpress_data",
[string]$BackupRoot = "your WordPress path",
[string]$rclonePath = "your rclone path\rclone\rclone.exe",
[string]$remoteName = "gdrive", # rcloneで設定したリモート名
[string]$remoteFolder = "WordPressBackups", # Drive上のフォルダ名
[int] $RetentionDays = 14
)
# --- スクリプト本体 ---
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Ensure-Tool {
param([string]$PathOrCmd, [string]$Friendly)
if ($PathOrCmd -match '\\' -or $PathOrCmd -match '/') {
if (-not (Test-Path -LiteralPath $PathOrCmd)) {
throw "$Friendly not found at: $PathOrCmd"
}
} else {
& $PathOrCmd --version *> $null 2>&1
if ($LASTEXITCODE -ne 0) { throw "$Friendly not available on PATH." }
}
}
try {
# 0. ツールと設定の確認
$mysqldump = Join-Path $MySqlBinPath "mysqldump.exe"
Ensure-Tool -PathOrCmd $mysqldump -Friendly "mysqldump"
Ensure-Tool -PathOrCmd "docker" -Friendly "Docker CLI"
Ensure-Tool -PathOrCmd $rclonePath -Friendly "rclone"
docker volume inspect $DockerVolumeName *> $null 2>&1
if ($LASTEXITCODE -ne 0) { throw "Docker volume '$DockerVolumeName' not found." }
# 1. バックアップ用フォルダの準備
$timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
New-Item -ItemType Directory -Force -Path $BackupRoot | Out-Null
$backupDir = Join-Path $BackupRoot $timestamp
New-Item -ItemType Directory -Force -Path $backupDir | Out-Null
Write-Host "Backing up to $backupDir"
# 2. MySQLデータベースのダンプ
$sqlPath = Join-Path $backupDir ("mysql-{0}-{1}.sql" -f $DbName, $timestamp)
$dumpArgs = @("--host=$DbHost", "--port=$DbPort", "--user=$DbUser", "-p$DbPassword", "--single-transaction", "--quick", "--routines", "--triggers", "--events", "--default-character-set=utf8mb4", "--result-file=$sqlPath", $DbName)
Write-Host "Dumping MySQL database '$DbName'..."
& $mysqldump @dumpArgs
if ($LASTEXITCODE -ne 0 -or -not (Test-Path $sqlPath)) { throw "mysqldump failed." }
# 3. Dockerボリュームのアーカイブ
$tarPath = Join-Path $backupDir ("volume-{0}-{1}.tar.gz" -f $DockerVolumeName, $timestamp)
$tarCmd = "tar -C /data -czf /backup/volume-$DockerVolumeName-$timestamp.tar.gz ."
Write-Host "Archiving Docker volume '$DockerVolumeName'..."
docker run --rm -v "${DockerVolumeName}:/data:ro" -v "${backupDir}:/backup" alpine sh -c $tarCmd
if ($LASTEXITCODE -ne 0 -or -not (Test-Path $tarPath)) { throw "Volume archive failed." }
# 4. バックアップフォルダの圧縮 (7-Zip推奨)
$archiveName = "wp-backup-$timestamp.7z"
$archivePath = Join-Path $BackupRoot $archiveName
$sevenZipPath = "${env:ProgramFiles}\7-Zip\7z.exe"
if (Test-Path $sevenZipPath) {
Write-Host "Compressing with 7-Zip..."
& $sevenZipPath a -t7z -mx9 $archivePath "$backupDir\*" | Out-Null
} else {
Write-Warning "7-Zip not found. Falling back to built-in ZIP..."
$archivePath = [System.IO.Path]::ChangeExtension($archivePath, ".zip")
Compress-Archive -Path "$backupDir\*" -DestinationPath $archivePath -Force
}
if (-not (Test-Path $archivePath)) { throw "Compression failed." }
# 5. 一時フォルダの削除
Write-Host "Cleaning up uncompressed files..."
Remove-Item $backupDir -Recurse -Force
# 6. ローカルの古いバックアップを削除
Write-Host "Pruning local backups older than $RetentionDays days..."
Get-ChildItem -Path $BackupRoot -File | Where-Object { $_.Extension -in ".7z", ".zip" -and $_.LastWriteTime -lt (Get-Date).AddDays(-$RetentionDays) } | ForEach-Object {
Write-Host "Deleting local archive: $($_.FullName)"
Remove-Item $_.FullName -Force
}
# 7. Google Driveへアップロード
$remoteTarget = "${remoteName}:${remoteFolder}"
Write-Host "Uploading backup file to Google Drive..."
& $rclonePath copy "$archivePath" "$remoteTarget" --transfers=1 --checkers=2 --drive-chunk-size=64M --quiet
# 8. Google Driveの古いバックアップを削除
Write-Host "Pruning old backups from Google Drive..."
$cutoffDate = (Get-Date).AddDays(-$RetentionDays)
$rcloneFiles = & $rclonePath lsjson "$remoteTarget" --files-only | ConvertFrom-Json
foreach ($file in $rcloneFiles) {
if ([DateTime]::Parse($file.ModTime).ToLocalTime() -lt $cutoffDate) {
$filePath = "${remoteTarget}/${file.Name}"
Write-Host "Deleting remote file: $filePath"
& $rclonePath delete "$filePath" --drive-use-trash=false
}
}
Write-Host "Backup completed successfully: $archivePath"
}
catch {
Write-Error $_.Exception.Message
exit 1
}
スクリプトのポイント解説:
- パラメータ部: スクリプト冒頭のparam(…)ブロックは、ご自身の環境に合わせて修正が必要です。特に$DbPasswordや各種パスは必ず確認してください。
- MySQLダンプ: mysqldumpコマンドを使い、データベースの整合性を保ちながら(–single-transaction)、効率的にデータをエクスポートします。
- Dockerボリュームのアーカイブ: docker runコマンドで軽量なalpineコンテナを一時的に起動し、ホストのDockerボリュームをマウント(-vオプション)。コンテナ内からtarコマンドを実行してボリューム全体を .tar.gz ファイルに固めます。データを読み取り専用(:ro)でマウントすることで、バックアップ中の意図しないデータ変更を防いでいます。
- Google Driveへのアップロード: rclone copyコマンドで、ローカルの圧縮ファイルをGoogle Driveの指定フォルダにコピーします。
- Google Driveの世代管理: rclone lsjsonでGoogle Drive上のファイル一覧と更新日時(メタデータ)をJSON形式で取得します。これをPowerShellで処理し、設定した保持日数($RetentionDays)より古いファイルをrclone deleteで削除します。
ステップ4: 自動実行の設定 (Windows タスクスケジューラ)
最後に、このスクリプトを毎日自動で実行するようにWindowsのタスクスケジューラに登録します。
- 「タスク スケジューラ」を検索して開きます。
- 右側の操作ウィンドウから「基本タスクの作成」をクリックします。
- 名前と説明を入力し(例: WordPress Backup)、「次へ」。
- トリガーで「毎日」を選択し、「次へ」。
- 開始時刻を深夜など、サーバー負荷の低い時間帯に設定し、「次へ」。
- 操作で「プログラムの開始」を選択し、「次へ」。
- 以下の通り設定します。
- プログラム/スクリプト: powershell.exe
- 引数の追加 (オプション): -ExecutionPolicy Bypass -File “C:\path\to\your\backup-wordpress.ps1”
- ※スクリプトを保存したフルパスを指定してください。
- 「完了」をクリックする前に、「[完了]をクリックしたときに、このタスクの[プロパティ]ダイアログを開く」にチェックを入れます。
- プロパティ画面が開いたら、「全般」タブで「最上位の特権で実行する」にチェックを入れ、「OK」をクリックします。
これで、毎日指定した時刻にバックアップが自動的に実行され、大切なブログのデータが安全にGoogle Driveへ保管される仕組みが完成しました。自作サーバーを運用する上で、このような自動化されたバックアップ体制は、安心して運用を続けるための生命線と言えるでしょう。
コストまとめ:気になるお値段は?
初期費用
- 2.5Gbpsスイッチ: 約6,000円
- ミニPC: 約2万4千円
維持費用
- ドメイン更新料: 年間約2,000円(初年度無料キャンペーンを利用)
- インターネット回線: 個人利用と共用のため、実質無料
- 電気代: ミニPCの消費電力を平均10W、電気料金を40円/kWhとすると、年間約3,500円
補足:ソーラーパワーで電気代を削減!
自宅では、ソーラーパネル発電システムと蓄電池を導入しており、電気代はさらに安く抑えられています。将来的には、直流給電システムを導入し、サーバーやルーターを太陽光発電で直接動かす独自の「半オフグリッドサーバー」の構築も検討しています。
自作サーバーのメリット・デメリット
メリット
- カスタマイズ性: 自分の好きなようにハードウェアやソフトウェアを構成できます。
- 低コスト: 商用サーバーに比べて、大幅に費用を抑えられます。
- 学習機会: サーバー構築の知識や技術を実践的に学べます。
- 不要PCの再利用
デメリット
- ハードウェア安定性: 商用サーバーに比べて、ハードウェアの故障リスクが高い可能性があります。
- セキュリティ管理: セキュリティ対策を自分で行う必要があります。
- 手間と時間: 構築やメンテナンスに手間と時間がかかります。
自作しない場合の代替案:手軽に始めるなら
「自作サーバーはちょっとハードルが高い…」と感じる方には、Netowlのスターサーバーのようなレンタルサーバーを利用するのもおすすめです。
- スターサーバー:
- 無料でWordPressサイトを公開できる。
- サーバーの管理は不要。
- 手軽に始められる。
まとめ:Let’s enjoy technology!
今回は、技術ブログ「楽パ」のサーバー構築について、詳細に解説しました。自宅サーバーは、低コストで自由度が高く、技術的なチャレンジも楽しめる魅力的な選択肢です。
この記事が、皆さんの「やってみたい!」を後押しできたら嬉しいです。
(本記事の画像や本文作成の大部分には、Geminiを使用しました。)
コメント