LinodeでGhostブログを立ち上げる

LinodeでGhostブログを立ち上げる
Photo by Marcella Marcella / Unsplash

VPSサービスのLinodeと、オープンソースCMSのGhostを使って、このブログサイトを立ち上げました。この記事ではそのときに考えていたことや、実際の手順についてまとめています。

手順だけ見たいという方は以下からどうぞ

  1. Linodeの設定
  2. Ghostの設定

基本的に以下の公式の情報をもとに進めていますが、微妙にうまくいかないところがあったので、その辺りについては自分が動かすことができた方法を付け加えています。

WordPressが合わなかった

1年ほど前にブログを始めようと思い立って、とりあえず人気があるWordPressを入れてみました。ドメインを準備して、有料テーマがいいらしいというので色々調べてそれも購入しました。

それでさあブログを書こう!

、、、としたんですが、管理画面とかプラグインとか色々とごちゃごちゃしていてどうにもやる気が起きず、結局一つも投稿しないまま1年ほど立ってしまいました。

で、今またブログを始めようとしています。

前回はWordPressが合わなかったので、何か別の方法がないか調べました。

最低限のシンプルなものでいいのでゼロから作るというのもちょっと考えたのですが、別に開発経験があるわけでもないのでさすがに時間がかかりそうだったのでやめました。(作っているうちにブログを始めるという目的を見失う気がしたのもあります。)

そんな中、GhostというCMSがあるのを知りました。シンプルな作りですっきりしていて良さそうに見えたので、大して調べてないですがまあ気に入らなかったらまた別な方法を探せばいいかと思い、これを使ってみることにしました。

Ghost Proかセルフホストか

Ghost Pro

GhostはGhost.orgが運営するフルマネージドサービス(サーバー周りのことやセキュリティ面などブログと直接関係ない部分は全部やってくれる)のGhost(Pro)で使ってもいいし、自分でサーバーを用意してセルフホストで使うこともできます。

Ghost(Pro)だと月額料金がかかるけれど、細かいことは気にせずさっさとブログを始めることができます。一番安いSTARTERプランだと月額$9 (年間一括払いの場合。毎月の支払いだと月額$11)かかります。

Ghost(Pro) 料金表
Ghost(Pro) 料金表
Ghost(Pro) - Official managed hosting for Ghost
The best Ghost managed hosting from the creators of the open source publishing platform. Spend less time on your server, more time on your site.

メンバーの数(ブログの購読者数)で料金が変わるようで、STARTERだと1,000人まで登録可能、1,000人の場合は月額$15 (月払いだと$19)です。僕の場合、まだメンバーシップなどは考えておらず単なるブログとして使うつもりなのでここは関係ありませんでした。

一つ上のCREATORプランだと、月額$25 (月払いは$31)になってちょっと高すぎるので、使うとしたらSTARTERなのですが、STARTERだとカスタムテーマが使えなかったり、メール配信に使うアドレスがghost.ioのものしかダメだったりと、その他今後色々いじる可能性を考えた場合に制限が多すぎていまいちでした。

セルフホスト

Ghostはオープンソースなので、自分でサーバーを立ててしまえば無料で使うことができます。

サーバーはVPSを使うことにしました。性能に関してはどの程度必要なのか現時点でよくわかっていないのですが、まあアクセスはほとんどないでしょうし、とりあえず性能は置いておいて安そうなところを調べてみました。

国内だとXserverとかWebARENA Indigo、海外だとLinode, Vultrあたりが良さそうだなと思いつつ、60日間$100無料というのに惹かれてLinodeの月額$5のプランで初めてみることにしました。(もしかしたら他も似たようなキャンペーンあったかもしれません)

正直今のドル円レートだとあんまりかなあという気もしたのですが、もしかしたら海外向けに発信するかもとか考えると海外にデータセンターある方がいいなとか色々理由を付け加えて、使ってみることに決めました。

💡
後から色々調べる中で、無料で使えるサービスもたくさんあることを知りました。ブログの移行や、また別の用途でサーバーが必要になったときにはそういったものを使ってみようかな。今回はVPSというもののお勉強も兼ねてということで、しばらくはこのまま運用してみようかと思っています。どんなサービスがあるのかは、調べた範囲ではありますが記事の最後にまとめておきます。

フルマネージドとセルフホストとどっちがいいのか

結局僕はセルフホストを選びましたが、この辺は人によってどっちがいいか変わってくるかなと思います。

僕の場合は自由度が少なくなるのが嫌で、だけどそこまでお金は使いたくない、ということでセルフホストを選びましたが、フルマネージドなGhost(Pro)を選んでおくと、以下で書く作業は全て不要になって今すぐブログを始められます。また、自分でアップデートなどの管理もしなくていいのでその辺を気にせず運用したい人にはGhost Proを使う方が良さそうです。

Linodeの設定

Linodeアカウントの作成

Linodeのアカウントを作成します。

Platform - Getting Started on the Linode Platform

アカウントの作成手順は上記リンクに記載の通りです。ここのSign Upから進めばアカウントが作成できます。

Linode Getting Started
Linode Getting Started

Linodeインスタンスの作成

アカウントが作成できたら、Linodeにインスタンスを立てます。

ここでは、Guides - Create a Compute Instanceの内容に沿って進めます。

Distribution, Region, Plan

DistributionはGhostのガイド、How to install Ghost on Linodeで、Ubuntuに指定されているので、Ubuntu 22.04LTSのイメージを使います。(LTSはLong Time Supportのことで、サポート期間が5年と長い。通常は9ヶ月)

Regionは日本にいて、日本向けのサイトを作るならTokyoかOsakaにしておけば一番速いです。

(とはいえ、海外でもそれなりのスピードは出るので、スピードテストのページで速さを確認してみてから決めてもいいですね。Linodeのスピードテスト)

Planは、上記のGhostのガイドで、最低1GBのメモリがあるサーバーが必要とあります。以下の表の通り、一番安いShared CPUのNanode 1GBでも大丈夫そうなのでこれを選びます。

LinodeのShared CPUの料金表
LinodeのShared CPUの料金表
Standard Linode Instances
Balanced resources that support a wide range of modern cloud applications, from personal projects to production deployments of an enterprise application.

これらを反映すると以下のような画面になります。

インスタンスの作成画面
インスタンスの作成画面

Linode Label, Add Tags

Linode Labelはインスタンスの名前なので区別がつけばなんでも大丈夫です。

Tagも必要に応じて付けられますが、今のところひとつのインスタンスしかないので付けていません。

Root Password, SSH Keys

最後にrootユーザーのパスワードと、SSH鍵を登録します。

Root Passwordはシステムにルートユーザーとしてログインするためのパスワードです。

SSH Keyは、自分のコンピュータ上で公開鍵と秘密鍵のペアを生成して、公開鍵の方をLinode側に登録します。Mac, Linuxの場合はターミナルを開いて以下のコマンドを入力すると生成できます。Windowsでもコマンドプロンプトでできるみたいです

# SSH鍵の生成
ssh-keygen -t ed25519

生成された公開鍵を登録します。labelにはマシン名などを入れておきます。

インスタンスの作成

ここまできたら、残りはOptionalなのでスルーして、インスタンスを立ち上げます。少し時間が経つとインスタンスが出来上がり、IPアドレスなどが確認できるようになります。このIPアドレスを使ってインスタンスに接続し、この後の設定を進めていきます。

DNSの設定

まずはLinodeの管理画面で、DNSレコードの設定を行います。管理画面の左側から”Domains”と書いてあるアイコンをクリックして、自分のドメインにDNSレコードを登録していきます。

Linodeの管理画面
Linodeの管理画面

ドメインレジストラ側の設定

Linodeの管理画面からNS RecordにあるName Serverをコピーして、自分がドメインを購入したレジストラのページにいきます。

LinodeのName Server
LinodeのName Server

僕の場合は豚のお尻のアイコンがかわいいPorkbunで購入したので、Porkbunの自分のアカウントページから、使いたいドメインのName serverを先ほどコピーしたLinodeのものに書き換えます。

porkbun.com | An oddly satisfying experience.
Porkbun is an amazingly awesome ICANN accredited domain name registrar based out of the Pacific Northwest. We’re different, we’re easy, and we’re affordable. Use us, you won’t be sorry. If you don’t use us we’ll be sad, but we’ll still love you.

Linode側での設定

A/AAAA Recordに、自分のドメインとIPアドレスを登録します。IPv4, IPv6の2つのレコードを登録しますが、Hostnameはどちらも同じで大丈夫です。僕の場合は、このサイトのURL、signfrogs.com をHostnameに入力しています。

その他の設定

もし同じドメインでメールも使いたい場合は、メールホスティングで利用しているサービスの情報をDNSレコードに記述する必要があります。僕はProtonmailを使っているので、そこで指定されているDNSレコードをLinode側に記述しています。

Proton Mail: Get a private, secure, and encrypted email account | Proton
Proton Mail is the world’s largest secure email service with over 100 million users. Available on Web, iOS, Android, and desktop. Protected by Swiss privacy law.

やったことはないですがGoogle Workspaceを使うこともできそうですね。

これらの設定はすぐには反映されませんが、正しく入力できていれば、しばらく待つと反映されます。

その他に例えばGhostだとMailgunの設定が管理画面にありますが、これはメールを一斉配信するためのサービスで、こういったものを使う場合などにもDNSレコードの編集が必要になります。

Transactional Email API Service For Developers | Mailgun
Powerful Transactional Email APIs that enable you to send, receive, and track emails, built with developers in mind. Learn more today!

Linodeインスタンスの設定

Guides - Setting Up and Securing a Compute Instance

インスタンスに接続

まずターミナルからsshで先ほど作成したLinodeインスタンスにアクセスします。
パスワードにはインスタンス立ち上げ時に指定したrootのパスワードを入力すればOKです。

# rootで接続
ssh root@[ipアドレス]
💡
もし何らかの理由で設定がうまくいかない場合、インスタンスをrebuildして初めからやり直すことがあるかもしれません。しかしrebuild後にそのままだとssh接続がうまくいかず、以前のホスト情報をknown_hostsから消すと接続できるようになりました。コマンドは以下の通りです

ssh-keygen -R [ipアドレス]

システムのアップデート

# update
apt update && apt upgrade

タイムゾーンの設定

Asia -> Toykoを選択

# set timezone
dpkg-reconfigure tzdata
# 正しく設定されているかチェックする
date

ホスト名の設定とhostsファイルの編集

自分で区別できれば何でもいいが、ここではblog01とする

# ホスト名の設定 
hostnamectl set-hostname blog01

hostsファイルにIPアドレスとホストの情報を追記します。以下のコマンドでnanoエディタを使ってhostsファイルを開きます

# hostsファイルの編集
nano /etc/hosts

エディタの画面になり、hostsファイルの中身が見えるので、localhostの行の下に以下を追記する

[IPv4アドレス] blog01.[ドメイン名] blog01
[IPv6アドレス] blog01.[ドメイン名] blog01
  • [IPv4アドレス], [IPv6アドレス]には自分のインスタンスのIPアドレスを書きます。
  • [ドメイン名]には自分のドメイン名を書きます。このサイトの場合はsignfrogs.com

入力が終わったら、Ctrl + XY で書き込んでnanoを終了

ユーザーの追加

新しくユーザーを作り、その後はrootではなく新しく作ったユーザーで操作します

ユーザーを作ります

# userの追加
adduser [新しいユーザー名]

パスワードの設定を促されるので設定して、次にユーザをsudoグループに追加します

adduser [新しいユーザー名] sudo

ここまでできたら一度ログアウトしてから、新しいユーザーでログインします。アクセスする際には先ほど設定したパスワードを入力します。

# ログアウト
exit
# 新しいユーザーでログイン
ssh [新しいユーザー名]@[ipアドレス]

SSH鍵でアクセスできるようにもしておきます。
※Windows、Linuxの場合はリンク先の公式ガイドを参照してください

# インスタンス側で鍵を置く場所を作る
mkdir -p ~/.ssh && sudo chmod -R 700 ~/.ssh/

# ターミナルをもう一つ立ち上げて、ローカルから鍵をコピーする
scp ~/.ssh/[公開鍵] [新しいユーザー名]@[ipアドレス]:~/.ssh/authorized_keys

# 鍵の保存場所と鍵ファイルのパーミッション変更
sudo chmod -R 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

# ログアウトして再接続
exit
ssh [新しいユーザー名]@[ipアドレス]

最後にSSHの設定ファイルで、rootでのログイン、パスワードでのSSHログインを禁止しておきます。nanoで設定ファイルを開きます

sudo nano /etc/ssh/sshd_config

以下の3箇所を書き換えます。

  • AddressFamily inet
    接続要求を聞くインターネットプロトコルを1つに制限します、v6を使う場合はinet6と書きます
  • PermitRootLogin no
    rootでのログインを禁じます
  • PasswordAuthentication no
    パスワード認証を無効にします

書き換えたら保存して閉じます。

sshサービスをリスタートして新しい設定を読み込みます。

# sshサービスをリスタートして、新しい設定を読み込む
sudo systemctl restart sshd

ここまでの設定でGhostを使う要件として1GBのメモリとともに記載されていた、A configured and secured Linode server の準備ができました。

Ghostの設定

Ghostの環境構築

これからGhostをインストールしていきます。あともう少し!

How to install Ghost on Ubuntu

上記リンクのInstall NGINXから進めます。

# install nginx
sudo apt install nginx
nginx -V

ファイアウォールを設定します

# ufwの設定
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'

sudo ufw enable
sudo ufw status

MySQLをインストールして、ユーザーとパスワードを設定します

# install mysql
sudo apt install mysql-server
# バージョンの確認
mysql -V
# MySQLを実行して、パーミッションの更新
sudo mysql

MySQLが立ち上がったら以下のように設定

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '設定したいパスワード';
# MySQLを終了
quit

これで少しつまづいたのですが、以下の記述をしないとGhostからMySQLに接続できませんでした。以下のリンクの情報を参考にして::1から始まる行を削除するとうまく動くようになりました。

Error: connect ECONNREFUSED ::1:3306 is when i try to use typeorm in nestjs
This error when i try to use typeorm in nestjs i did setting for using typeorm like this app.module.ts import { Module } from ‘@nestjs/common’; import { GraphQLModule } from ‘@nestjs/graphql’; impo…
# ローカルループバックアドレスのIPv6側を無効化
sudo nano /etc/hosts

nanoエディタの編集画面で、::1から始まる行を丸ごと削除します

Node.jsのインストール

# install nodejs
curl -sL https://deb.nodesource.com/setup_18.x -o /tmp/nodesource_setup.sh
sudo bash /tmp/nodesource_setup.sh
sudo apt install nodejs
node -v

Ghost-CLIのインストール。5分くらいかかります

# install ghost cli
sudo npm install ghost-cli@latest -g

npmを最新バージョンにするように以下のようなメッセージが出ることがあります。

npm notice New patch version of npm available! 10.5.0 -> 10.5.1
npm notice Run npm install -g npm@10.5.1 to update

その場合はメッセージの指示通りに実行します。バージョンは適宜変えてください。

# update npm
sudo npm install -g npm@10.5.1

Ghostをインストールします、[ユーザー]のところには、Linodeの設定のときに作った新しいユーザー名を入れます

# install ghost
sudo mkdir -p /var/www/ghost
# sudo権限のあるユーザにオーナーシップを変更
sudo chown [ユーザー]:[ユーザー] /var/www/ghost 
sudo chmod 775 /var/www/ghost
cd /var/www/ghost
# 作ったディレクトリが空でないとインストールできないので、空かどうかを確認
ls -a
# 問題なければインストールを実行
ghost install

あとは指示に従って入力していきます。

  • Enter your blog URL:
    – 自分のブログのURLを入力します。このサイトの場合はhttps://signfrogs.com
  • Enter your MySQL hostname: (localhost)
    – そのままEnter
  • Enter your MySQL username:
    rootと入力
  • Enter your MySQL password:
    – MySQLのインストールのときに設定したパスワードを入力
  • Enter your Ghost database name: (ghost_prod)
    – 特にこだわりがなければそのままEnter
  • Do you wish to set up "ghost" mysql user? (Y/n)
    Yを入力
  • Do you wish to set up Nginx? (Y/n)
    Yを入力
  • Do you wish to set up SSL? (Y/n)
    Yを入力
  • Enter your email (For SSL Certificate)
    – 自分のメールアドレスを入力
  • Do you wish to set up Systemd? (Y/n)
    Yを入力
  • Do you want to start Ghost? (Y/n)
    Yを入力

以下のコマンドでGhostの実行ステータスが確認できます

ghost ls

Ghostの管理画面

最後にGhostの管理画面に入って、ブログの設定をしておきます。

ブラウザで自分のサイトにアクセスします。このときURLの末尾に/ghostをつけるとGhost configuration pageが開くので、そこでGhostのアカウントを作ります。すると今後はここからブログの投稿や、デザイン、メンバーシップなどの各種設定ができるようになります。

僕の場合は今のところメンバーシップを使う予定はないので、Sign up や Subscribeのボタンは必要ありません。これを非表示にする方法は以下のリンクに書いてありました。

Can I disable memberships on my site?
Yes! If you don’t want to use the membership feature in Ghost, it can be disabled in Ghost Admin.

書かれている通りに、Setting -> Membership -> Access に進んで、 Subscription access をNobodyにすると、消したいボタンが消えてくれます。

このあとは

ということで無事にブログを立ち上げることができました。

あとはGoogle Analyticsを設定しておくと、サイトの分析が可能になるのでやっておいた方がいいかな。

GhostでGoogle Analyticsを使う方法は、以下のリンクに記載があります。

Settings > Code injection でヘッダにGAのコードを埋め込むと使えるようになるみたいです。

Google Analytics + Ghost - How to use Ghost and Google Analytics together

メンバーシップ機能を使う人はその辺の設定とか、上で書いたメール配信の設定も必要ですね。

月額課金とかもStripeという決済サービスのアカウントと連携して簡単に設定できるみたいなので、その辺も必要な人はやるといいと思います。課金機能を使う場合、日本向けのサイトだったら特定商取引法に対応するために準備しておかないといけないページがある点は注意が必要です。

Stripe | Financial Infrastructure for the Internet
Stripe powers online and in-person payment processing and financial solutions for businesses of all sizes. Accept payments, send payouts, and automate financial processes with a suite of APIs and no-code tools.

無料で使えるサービス

試してみたいサービスのリスト。

  • Netlify
    • 料金プランのStarter Planが無料
    • ただし、使用量の制限を超過すると、使用停止ではなく超過料金が請求されるので使わない気がする。管理が得意な人なら特に気にならないかも
Scale & Ship Faster with a Composable Web Architecture | Netlify
Realize the speed, agility and performance of a scalable, composable web architecture with Netlify. Explore the composable web platform now!
  • Vercel
    • Pricingに書いてあるHobbyプランが無料
    • このプランだと商用利用は不可。広告載せたりもダメっぽい
Vercel: Build and deploy the best Web experiences with The Frontend Cloud – Vercel
Vercel’s Frontend Cloud gives developers the frameworks, workflows, and infrastructure to build a faster, more personalized Web.
  • GitHub Pages
    • GitHubのリポジトリから直接デプロイ
    • 商用利用はダメ
    • 無料だとPublicリポジトリしか使えない
GitHub Pages
Websites for you and your projects, hosted directly from your GitHub repository. Just edit, push, and your changes are live.
Cloudflare Pages
Build your next application with Cloudflare Pages
Cloud Computing Services | Google Cloud
Meet your business challenges head on with cloud computing services from Google, including data management, hybrid & multi-cloud, and AI & ML.
Explore Oracle Cloud Infrastructure
Maximize efficiency and save with a cloud solution that’s designed specifically for your industry and available anywhere you need it.
  • AWS
    • AWS無料利用枠のページに、12ヶ月無料のものと常に無料のものが説明されている
    • AWS Lambdaを使ってサーバーレスで何か作ってみたい(あんまり理解してないけど)
Cloud Computing Services - Amazon Web Services (AWS)
Amazon Web Services offers reliable, scalable, and inexpensive cloud computing services. Free to join, pay only for what you use.

Read more

Ghostでコードブロックや画像を折りたたむ方法

Ghostでコードブロックや画像を折りたたむ方法

GhostのエディタではCardsという機能を使って記事本文中に様々な要素を埋め込むことができます。 Editor cardsJump to a card * Images * Markdown * HTML * Gallery * Divider * Bookmark * Email content * Email call to action * Public preview * Button * Callout * GIF * Toggle * Audio * Video * File * Product * Header * Embeds * Signup Card The Ghost editor includes rich media objects called Cards, which can be inserted into your content to add

ghost updateをすると編集したテーマファイルが元に戻ってしまう問題の解決策

ghost updateをすると編集したテーマファイルが元に戻ってしまう問題の解決策

以前Sourceテーマのファイルを編集して、タグ一覧のページを作りました。 Ghostブログにタグ一覧ページを作る (Sourceテーマの場合)記事を分類するのにタグをつけているのですが、いくらタグをつけたところで絞り込みに使えないのであれば何の意味もないですよね。 僕はSourceというGhostのデフォルトのテーマを使っているのですが、このテーマだと、それぞれのタグをそのままナビゲーションバーに設置することはできるんですが、ドロップダウンでタグを選んだり、タグの一覧を表示したりはすぐにはできないようです。 そこで今回は、Sourceテーマを使ってタグ一覧のページを作ってみましたという記事です。 Sourceテーマを使ってタグ絞り込みをしたいときにできること 上でも述べましたが、このテーマだと、ドロップダウンとか一覧ページはそのままだと出せません。 できるのは、それぞれのタグをナビゲーションバーに置くくらいです。 これは例えば、「ブログ」というタグをつけた記事があって、そのタグを持っている記事一覧を出せるようにしようと思ったら、ナビゲーションバーに「ブログ」という項目をわざわざ作ら

GhostにCode injectionでThree.jsの3Dモデルを埋め込んでみる

GhostにCode injectionでThree.jsの3Dモデルを埋め込んでみる

Three.jsを使って作られた3Dモデルをブログ記事の中にCode injectionを使って埋め込めるのかなとふと思ったので試してみました。 本文中でHTMLカードに<canvas>タグ、Code injectionのヘッダに<style>タグでCSSを、<script>タグでJavaScriptを貼り付けると、ちゃんと動かすことができました。 埋め込んだのはThree.jsのマニュアルにあった以下の例です。 three.js manual コードの中身は全く理解できていませんが、3Dって面白いですね。 Three.jsでは3Dモデルをインポートして使用することもできるようですが、以下のようなところから素材を使わせてもらうこともできるみたいですね。 OpenGameArt.orgというサイトで、ゲーム制作をしている人には有名なのかもしれませんが、僕は初めて知りました。 OpenGameArt.orgOpenGameArt.org 素材によってライセンス形態が異なるようですが、先日の記事で描いたCC0みたいなライセンスにしてある3D素材もあって、Three.j

Joseph Mallord William Turner "Mortlake Terrace", 1827 | Courtesy National Gallery of Art, Washington

部屋に飾る絵画とブログの画像

僕は特別アートに詳しいわけでもないですが、たまに絵を見たくなることもあります。 そういうとき、思い切って美術館に行くこともあるにはあるんですが、基本的に出不精なのでネットで調べて満足してしまうことが大半です。 ただやっぱり画面の中で見るのはその一瞬だけですし、なんだか味気ないってのも正直あります。 この記事は、そんなときはパブリックドメインになっている絵画データを印刷するとなんかいいよってことを伝えたくて書きました。 こういう自由に利用可能な素材はブログの画像なんかにも使えるのもいいですよね。この記事のトップにもパブリックドメインの絵画をお借りして載せてみました。 パブリックドメインってなんぞや 高画質な絵画データでもパブリックドメインで無償でダウンロード可能になってるものが結構あったりします。 パブリックドメインとは、誰でも自由に利用可能(商用利用含む)な素材です。 パブリックドメインになっている素材は大きく分けて、 1. 著作権が切れたもの 2. 著作者がパブリックドメインにしたもの(CC0と表記されている) の2種類があるようです。 💡僕は