前回のあらすじ
ある日突然『何かオープンなサイト作りたいなぁ.』と思い、
現在契約中のさくらVPSサービスをゼロベースで再構築し、サイトをLaravelへ一本化する決意を固めました。
前回実施した事は以下となります。
① OSをCentOS7からRocky Linuxに変えて再インストール
② SSHの設定
③ Apacheのインストール
④ ファイアウォールの設定
さて、次は何をしようかな.
サイトのHTTPS化
Apacheをインストールした事で「index.html」ファイルを設置すれば、一応サイトとして表示されます。
どんな形であれ、サイトのオープンは成功です!
ただし今回の目的の1つに
『オープンなサイトにするなら[HTTPS]化』があります。
時刻は23時手前、少し手順だけ確認して今日は寝るかと思い、アシスタントに相談(Copilot)。
Copilot
さくらVPSでHTTPS化は簡単?
さくらVPSでのHTTPS化は“慣れればめちゃくちゃ簡単”。
ただし、レンタルサーバよりは少しだけ技術的。理由と一緒にわかりやすく整理するね。
さくらVPSでHTTPS化は簡単? → YES、10〜20分で終わるレベル
~ 省略 ~
ふむふむ。話半分でも30分くらいでできそうだな。
なら今からやるか~
お待たせいたしました、以下手順となります。
○ Apacheの起動確認
以下を叩いて起動中である事を確認します。
# systemctl status httpd
○ certbotのインストール
Let’s Encrypt の証明書を取得するためのツールを導入します。
# dnf install epel-release -y
# dnf install certbot python3-certbot-apache -y
どちらのコマンドも「完了しました!」と言われれば成功です。
○ certbotを実行(自動でhttps化)
# certbot --apache -d あなたのドメイン名 -d www.あなたのドメイン名
『ふむふむ。これで設定は完了か。簡単簡単~.』と思っていたら、
TeraTerm
# certbot --apache -d YourDomain -d www.YourDomain
AH00526: Syntax error on line 85 of /etc/httpd/conf.d/ssl.conf:
SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty
どうも内容的には、
『ssl.confの中に「存在しない証明書ファイル」を参照している行が残っている』との事。
よって、まずはそのファイルを開いてみる。
# cd /etc/httpd/conf.d
ファイル「ssl.conf」をローカルに移動し確認(やり易いので)
アシスタント(Copilot)によると、以下のコードをコメントアウトして、サーバへ戻すとの事。
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
Listen 443 https
以下全て
<VirtualHost _default_:443>
~
</VirtualHost>
それでは、気を取り直していざっ!
TeraTerm
# certbot --apache -d YourDomain -d www.YourDomain
Unable to find a virtual host listening on port 80 which is currently
needed for Certbot to prove to the CA that you control your domain.
Please add a virtual host for port 80.
あ~~~っ!
またエラー。途中飛ばしてますが、実は最初は対話型で処理が進んでいたんですよ。
良い感じで進んでいただけにショックでした。
エラー内容を意訳すると『ポート80で待ってるドメイン名が無いから所有権を証明できないよ』との事。
よって、バーチャルホストにドメイン名を追加する必要があります。
Rocky Linuxの場合は、以下手順となります。
○ 新規confファイル作成
例えばあなたの持っているドメイン名が「hoge.com」の場合「hoge.conf」ファイルを作成します。
ファイルの中身は、以下の様にします(webrootは自身の環境に合わせてください)
<VirtualHost *:80>
ServerName hoge.com
ServerAlias www.hoge.com
DocumentRoot /var/www/html
</VirtualHost>
流石にこれで行けるだろっ!
Apacheを再起動し、再再度自動https化実行。
TeraTerm
# certbot --apache -d YourDomain -d www.YourDomain
Enter email address (used for urgent renewal and security notices)
何か必要な連絡をする場合のメールアドレスを聞かれてるので記入します。
TeraTerm
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.7-June-04-2026.pdf. You must agree in
order to register with the ACME server. Do you agree?
よくある「このルールに許諾しますか」的やつなので「Y」
TeraTerm
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
広告・お知らせメールの許可確認なので「N」
TeraTerm
Account registered.
Please enter the domain name(s) you would like on your certificate (comma and/orspace separated)
あなたのドメインを入力
TeraTerm
You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/reidream.net.conf)
What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Attempt to reinstall this existing certificate
2: Renew & replace the certificate (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter]
複数バーチャルホストがあるがどれが良いと聞かれているので「番号」記入
以上で対話型処理は終了します。
最後のメッセージを確認すると、何やら以下の文字が目立ちます。
『Successfully』
『え?これってもしかして.』
そう設定は完了しました!
ご自身の「https://~」をブラウザから叩いてみましょう。
鍵マークついてますよね!!
長かった。本当に長かった。。
当初アシスタント(Cppilot)は20分前後と見込んでいたHTTPS化。
気が付けば翌日の1時をゆうに回り、トータル約3時間。
軽く切れかけてたのはナイショです。
なにはともあれ、無事暗号化サイトの仲間入りができました。
でわ、お休み~。
HTTPS化の更新
以下コマンドで証明書の自動更新がされるか確認しましょう
TeraTerm
# systemctl status certbot-renew.timer
○ certbot-renew.timer - This is the timer to set the schedule for automated renewals
Loaded: loaded (/usr/lib/systemd/system/certbot-renew.timer; enabled; vendor preset: enabled)
Active: inactive (dead)
Trigger: n/a
上記の白抜きの○が何だか心配になりますが、「enabled」となっているので問題ありません。
※「今この瞬間は動いていない」意味で、スケジュール自体は有効です
ただし念のため以下コマンドを叩いてタイマーを叩き起こしてみましょう
# systemctl enable --now certbot-renew.timer
次に以下を叩いてタイマー一覧を表示
TeraTerm
# systemctl list-timers | grep certbot
Fri 2026-06-12 12:55:23 JST 11h left n/a n/a certbot-renew.timer certbot-renew.service
次回証明書確認のスケジュールが表示されます。
基本的に3ヶ月の自動更新となりますが、2ヶ月を経過すると更新されてない旨のメールが届きます。
特にそのメールはスルーして良いです(「もうそんな時期かぁ~」と思う程度で)
それから10日前後で自動更新が行われるハズです。
特に更新されたメールは届かないため、心配にな場合は自身で更新する方法もあります。
まぁ単純に以下を叩くだけなんですけどね。
# certbot renew
また、あと何日有効かを確認する方法も簡単です。
TeraTerm
# certbot certificates
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Found the following certs:
Certificate Name: reidream.net
Serial Number: 5ee53xxxxxxxxxxxxxxxxxxxb5
Key Type: RSA
Domains: reidream.net www.reidream.net
Expiry Date: 2026-09-09 15:07:44+00:00 (VALID: 80 days)
Certificate Path: /etc/letsencrypt/live/reidream.net/fullchain.pem
Private Key Path: /etc/letsencrypt/live/reidream.net/privkey.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
『Expiry Date』情報を見てください。
【80日】と書いてありますね。
PHPのインストール
PHPには「mod_php」「php-fpm」の2種類が存在します。
今回は現在一般的に使われる環境に合わせ「php-fpm」をインストールします。
○ OSバージョン確認
TeraTerm
# cat /etc/redhat-release
Rocky Linux release 8.10 (Green Obsidian)
○ Remiリポジトリを有効化する
Rocky Linuxで最新のPHPを使うために必要なリポジトリを追加します。
※今回確認した最新は「Ver.8」でしたので、同バージョンを追加
# dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm -y
完了しました!と言われれば成功です
○ 確認
以下を叩いて確認します。
# dnf repolist
「remi-modular」と表示されていれば問題ありません。
○ PHPモジュールをリセット
Rockyの標準PHPを無効化する。
# dnf module reset php -y
完了しました!と言われれば成功です。
○ RemiのPHP X.xを有効化
例えば PHP 8.2 を使うなら
# dnf module enable php:remi-8.2 -y
完了しました!と言われれば成功です
○ PHPインストール
ここまで準備ができたら、いよいよ以下コマンドを叩いてインストールします。
# dnf install php php-cli php-mysqlnd php-opcache php-xml php-mbstring php-json php-gd php-curl -y
完了しました!と言われれば成功です。
○ ApacheがPHPを正しく読み込んでいるか確認
再起動してインストールしたPHPを読み込みます。
更に以下を叩き、正しく読み込んでいるか確認します。
TeraTerm
# systemctl restart httpd
# php -v
PHP 8.2.31 (cli) (built: May 5 2026 13:59:08) (NTS gcc x86_64)
Copyright (c) The PHP Group
Zend Engine v4.2.31, Copyright (c) Zend Technologies
with Zend OPcache v8.2.31, Copyright (c), by Zend Technologies
色々情報が表示されれば問題ありません。
php.iniの設定
適当な「index.php」ファイルを中身「echo phpinfo();」でWrbrootに設置してアクセスしてみましょう。
内容通り表示されていれば成功となり、また「php.ini」の場所も書いてあります。
以下内容をお好みに合わせて修正しましょう。
○ expose_php
PHPはデフォルトの設定ではhttpヘッダーにバージョンを表示します。
バージョンは公開しないほうがセキュアになりますので切りましょう。
expose_php = Off
○ post_max_size
アップロードサイズの変更。
初期値では恐らく「8M」程度だと思いますが、これは明らかに少ないです。
post_max_size = 20M
○ upload_max_filesize
同様にこちらも変更しましょう。
upload_max_filesize = 20M
○ date.timezone
タイムゾーンの設定。
初期値ではコメントアウトされていますが、日本にしましょう。
date.timezone = "Asia/Tokyo"
○ mbstring.language
マルチバイト対応(日本語対応)設定。
初期値ではコメントアウトされていますが有効にしましょう。
mbstring.language = Japanese
○ mbstring.internal_encoding
内部文字エンコーディングのデフォルト値を定義。
通常「UTF-8」なので設定します。
mbstring.internal_encoding = UTF-8
○ mbstring.http_input
HTTP通信の時のインプット文字コードを指定するmbstring.http_inputを設定。
通常「UTF-8」なので設定します。
mbstring.http_input = UTF-8
○ mbstring.http_output
HTTP出力文字コードを指定するmbstring.http_outputを設定します。
初期値はコメントアウトになってます。
mbstring.http_output = pass
○ mbstring.encoding_translation
HTTP入力変換を有効にするmbstring.encoding_translationをOnにします。
mbstring.encoding_translation = On
○ mbstring.detect_order
文字コード自動検出の優先順位を定義するパラメーターであるmbstring.detect_orderを設定します。
初期値はコメントアウトですが有効にします。
mbstring.detect_order = auto
○ mbstring.substitute_character
コードとして変換できない文字がある場合に、代替の文字を出力しないようmbstring.substitute_characterを設定します。
初期値はコメントアウトですが有効にします。
mbstring.substitute_character = none
以上。
どうやら今では無意味な設定もあるらしいけど、備忘録として。
設定を上書きしたら以下を叩いてApacheの再起動をします。
# systemctl restart httpd
MySQLのインストール
現在の最新バージョンである「9.7」をインストールします。
※訳あって結局[8.4]です
○ 古い MySQL/MariaDB が入っていれば削除
競合をさけるために以下コマンドを叩きます。
# dnf remove mariadb* mysql*
完了しました!と言われれば問題なしです。
○ MySQL公式リポジトリを追加します
TeraTerm
# dnf install https://dev.mysql.com/get/mysql-community-release-el9-1.noarch.rpm
tatus code: 404 for https://dev.mysql.com/get/mysql-community-release-el9-1.noarch.rpm (IP: 23.36.106.252)
あう。[404]つまり無いと言われました。
どうやら、MySQL Yum Repositoryが9.7 LTSに対応してないらしい。
最新のバージョンは以下のページで確認できます。
https://dev.mysql.com/downloads/repo/yum/
この画面一覧で、一番小さな文字のカッコ書きの最初の文字列に注目して下さい。
執筆時点では以下の様になっていました。
(mysql84-community-release-el9-4.noarch.rpm)
『mysql84-...』に注目して下さい。
これはバージョン8.4が最新である事を意味します。
なので「8.4」を入れるため、改めて以下を叩きます。
# dnf install https://dev.mysql.com/get/mysql84-community-release-el8-3.noarch.rpm
途中対話型になりますが、[y]で通過します。
完了しました!と言われれば成功です。
○ MySQL 8.4 LTS をインストール
まず間違ってリポジトリに追加した「9.7」を削除します。
以下を叩いて「9.7」に関連するリポジトリ名を探しましょう。
TeraTerm
# dnf repolist all | grep -i mysql
mysql-9.7-lts-community MySQL 9.7 LTS Community Serv 有効化
mysql-tools-9.7-lts-community MySQL Tools 9.7 LTS Communit 有効化
『有効』をピックアップした結果です。
つまり上記を削除する必要があります。以下を叩きましょう。
# dnf config-manager --disable mysql-9.7-lts-community
# dnf config-manager --disable mysql-tools-9.7-lts-community
再度確認し、「9.7」が無効になった確認と「8.4」が現在無効になってる確認をします。
今度は「8.4」を有効にします。
# dnf config-manager --enable mysql-8.4-lts-community
# dnf config-manager --enable mysql-tools-8.4-lts-community
モジュールフィルタをリセットします(対話型は[y])
# dnf module reset mysql
# dnf module disable mysql
完了しました!と言われれば問題なしです。
そして、いよいよMySQLをてインストールします。
# dnf install mysql-community-server
完了しました!と言われれば成功です!
MySQL環境設定
○ MySQL状態確認
以下コマンドを叩いてMySQLを起動します(対話型は[y])
TeraTerm
# systemctl status mysqld
○ mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:mysqld(8)
「Active: inactive (dead)」は起動していません。
○ MySQL起動(自動起動も設定)
以下を叩いて起動させます。
# systemctl start mysqld
# systemctl enable mysqld
次にもう一度状態確認します
TeraTerm
# systemctl status mysqld
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2026-06-12 20:51:51 JST; 1min 9s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Main PID: 10261 (mysqld)
Status: "Server is operational"
Tasks: 34 (limit: 5928)
Memory: 465.4M
CGroup: /system.slice/mysqld.service
mq10261 /usr/sbin/mysqld
「Active: active (running)」となります。
○ 仮パスワードを取得
MySQLは初回起動した瞬間にrootの仮パスワードを生成するので以下で確認します。
TeraTerm
# grep 'temporary password' /var/log/mysqld.log
2026-06-12T11:51:48.416598Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: ?i+FDttgs2tN
最後に表示される「?」含めた文字列が初期パスワードです。
○ rootでログインし、パスワード変更
では早速MySQLへログインして、パスワードを変更します。
TeraTerm
# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 77146
Server version: 8.4.9 MySQL Community Server - GPL
Copyright (c) 2000, 2026, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'お好きなパスワード';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
上記エラーがでた方は残念。
パスワードのセキュア度が弱いと怒られてます。
MySQL「8.4」のパスワードポリシーは以下となります。
パスワードの変更に成功した場合は、一度ログアウトして再度新パスワードでログインしてみましょう。
○ 外部からMySQLへ接続できるようにする
外部からMySQLへ接続するには、さくらの[コントロールパネル] > [パケットフィルタ]で設定します。
パケットフィルター設定を開いたら、どこでも良いので以下の設定をします。
これで設定を保存します。
次にファイアウォールも変更します。
まずは以下を叩いて内容を確認します。
# firewall-cmd --list-all
ここに「3306」が無ければ設定しましょう。
# firewall-cmd --add-port=3306/tcp --permanent
# firewall-cmd --reload
# firewall-cmd --list-all
「3306」が追加されましたね。
○ 外部接続確認
rootで外部接続してみると、結果失敗すると思います。
MySQLの初期設定ではrootユーザーは外部接続出来ない仕様となっています。
ではどうするか?
そうです。一般ユーザーを作りましょう。
VSFTPサーバを立てる
基本的にはサーバの再構築は以上となります。
色々苦労もありましたが、綺麗に構築できたと思います。
ただ、以前の手順書を見てると『VSFTPサーバ』の項目が.
確かにFTPでのWindowsとのファイル転送は必要だし、手順もトラブルなく設定できてます。
『これは今後の為に入れておくかぁ』
と、念のためアシスタントにも確認。
Copilot
VSFTPサーバの構築は簡単かな?
VSFTP(vsftpd)サーバの構築にかかる時間は “10〜25分” が現実的なライン。
あなたのスキルレベルなら 15分前後 で終わる。
15分かぁ、若干フラグを立てに来てる感もあるが、本当に簡単だった記憶しかないので入れる事に。
○ バージョン確認
TeraTerm
# cat /etc/redhat-release
Rocky Linux release 8.10 (Green Obsidian)
○ インストール確認
# rpm -qa vsftpd
何も表示されない場合はインストールされてません。
○ vsftpdインストール
TeraTerm
# dnf -y install vsftpd
[Errno 12] メモリを確保できません
ダウンロード済みのパッケージは、次の正常なトランザクションまでキャッシュに保存されました。
'dnf clean packages' を実行することでキャッシュパッケージを削除できます。
な、何故?
○ エラーになった場合
メモリ不足の可能性が高いので、以下コマンドでswap設定を確認してみます。
TeraTerm
# free -h
total used free shared buff/cache available
Mem: ***Mi ***Mi ***Mi *.*Mi ***Mi ***Mi
Swap: 0B 0B 0B
ここで重要なのは「Swap」で[0B]で、エラーの原因はまずこれです。
以下コマンドを実行してSwapの設定をします。
# fallocate -l 1G /swapfile
# chmod 600 /swapfile
# mkswap /swapfile
# swapon /swapfile
つづいて、以下コマンドで設定の永続化。
# echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
最後にエラー内容にもあったキャッシュを削除します。
# dnf clean packages
再度vsftpdをインストールチャレンジ。
今度は成功するハズです!
○ vsftpdサーバの設定
まずは「FtpRoot」を作成します(任意な場所に作成して下さい)
# mkdir -p /home/ftpuser
# chmod 755 /home/ftpuser
次にユーザーを作成します(任意なユーザー名を作成して下さい)
# adduser ftpuser
# passwd ftpuser
# chown ftpuser:ftpuser /home/ftpuser
最後に「/etc/vsftpd/vsftpd.conf」を編集します。
① 以下コメントを外す
#chroot_local_user=YES
② 最終行に以下を追加する([pasv_address]は置き換えてください)
chroot_local_user=YES
allow_writeable_chroot=YES
pasv_enable=YES
pasv_min_port=32768
pasv_max_port=65535
pasv_address=xxx.127.xx.xxx
local_root=/home/ftpuser
○ vsftpdサーバの起動設定
以下を叩いてvsftpdサーバの起動と、自動起動を有効にします。
TeraTerm
# systemctl start vsftpd
# systemctl enable vsftpd
Created symlink /etc/systemd/system/multi-user...
○ パケットフィルタを設定
FTP通信を可能にするため、パケットフィルタにポートを追加します。
さくらの[コントロールパネル] > [パケットフィルタ]へ移動し以下を設定します。
これで設定を保存します。
○ ファイアウォールの設定
以下コマンドを叩いて、ポート「21」を許可します。
# firewall-cmd --add-port=21/tcp --permanent
# firewall-cmd --add-port=32768-65535/tcp --permanent
# firewall-cmd --reload
○ ローカル(Windows)からの起動確認
『では、疎通を確認して寝よっと』
ん。あれ?
疎通できません。そんなぁ。。
実はwindowsのFTPには「アクティブモード」しかありません。
そしていつの間にやら最近のFTP通信はセキュリティ強化のため「パッシブモード」しか受付ないタイプが多いらしい。
そうです、Rocky Linuxのvsftpdサーバも漏れなくです...orz
ではローカルからのFTP通信はあきらめるのか?
答えは《否》です!
実はwindowsには『curl』を標準で実装していて、この子がパッシブモードのFTP送信をリクエストしてくれます。
簡単ですがコマンドは以下となります。
○ PUT
"C:\Windows\System32\curl.exe" -T hoge.html ftp://ユーザー名:パスワード@xxx.127.xx.xxx/up.html
○ GET
C:\Windows\System32\curl.exe" ftp://ユーザー名:パスワード@xxx.127.xx.xxx/index.html -o C:\bar\hoge.html
○ ディレクトリ内参照
"C:\Windows\System32\curl.exe" ftp://ユーザー名:パスワード@xxx.127.xx.xxx/
長かった。完全にアシスタントにフラグ回収されました。
ITの世界は「セキュア」の名の下に、すぐに仕様が変わりがちなので過去の手順書はアテになりませんね。
まぁ結果オーライと言う事で、お疲れ様でしたぁ!
最後に
トピックを①②に分けて掲載いたしましたが、
今回を持ちまして『さくらVPSでPHPの環境を作成した話』はおしまいとなります。
お付き合い頂き有難うございました。
最後にOSを再起動し、その後サービスが全て立ち上がってるかを確認する意味も込めて確認コマンド一覧を掲載します。
それでは滅びの呪文を唱えましょう(バルス..)
# reboot
再起動後、以下を確認して全て動いていれば完璧です!
systemctl status sshd
systemctl status firewalld
※[WARNING]は気にしない
systemctl status vsftpd
systemctl status httpd
systemctl status php-fpm
systemctl status mysqld
certbot certificates
※[Expiry Date]が証明書の有効期限
systemctl list-timers | grep certbot
※証明書の自動更新タイマーを確認できます
Rocky LinuxのデフォルトSSL設定は『ローカル証明書』を参照しているけど、実際にはそのファイルは存在しない。
だからcertbotがApacheの設定を読み込むときに『証明書ファイルが無い』といった流れです。
修正したら念のためApacheの文法チェックし、再起動しましょう
# apachectl configtest
# systemctl restart httpd