---
title: '使用 Grav 快速架設 Blog'
url: 'https://www.dbyellow.com/blog/grav-blog-setup-guide'
markdown: 'https://www.dbyellow.com/blog/grav-blog-setup-guide.md'
lang: zh-tw
date: '2026-08-10'
description: 'Table of Contents 1. 檢查與更新 VM 環境 2. 安裝 PHP 和移除 Apache 3. 配置 PHP-FPM …'
taxonomy:
  category:
    - Tech
  tag:
    - Grav
    - Blog
    - Linux
    - Nginx
    - Linode
  archives_month:
    - aug_2026
  archives_year:
    - '2026'
---

![Hero Image](https://www.dbyellow.com/user/themes/typhoon/images/headers/sea-and-sky.jpg)

   10th Aug 2026  - Mark 

#  使用 Grav 快速架設 Blog 

 [  Grav  ](https://www.dbyellow.com/tag:Grav#blog_list) [  Blog  ](https://www.dbyellow.com/tag:Blog#blog_list) [  Linux  ](https://www.dbyellow.com/tag:Linux#blog_list) [  Nginx  ](https://www.dbyellow.com/tag:Nginx#blog_list) [  Linode  ](https://www.dbyellow.com/tag:Linode#blog_list) 

  [ 部落格 ](https://www.dbyellow.com/)      使用 Grav 快速架設 Blog    

#### Table of Contents

- [1. 檢查與更新 VM 環境](#1-vm)
- [2. 安裝 PHP 和移除 Apache](#2-php-apache)
- [3. 配置 PHP-FPM](#3-php-fpm)
- [4. 配置 Nginx](#4-nginx)
    - [References](#references)
- [🚀 Grav 2.0 補充更新（2026/08）](#grav-2-0-2026-08)
    - [1. PHP 版本需求升級](#1-php)
    - [2. 升級方式完全不一樣：Migration ≠ Upgrade](#2-migration-upgrade)
    - [3. Admin 換成 Admin Next](#3-admin-admin-next)
    - [4. First-party REST API（跟你直接有關）](#4-first-party-rest-api)
    - [5. Markdown 升級：GitHub Flavored Markdown 預設開啟](#5-markdown-github-flavore)
    - [6. ⚠️ 安全改動：Twig in Content 預設關閉](#6-twig-in-content)
    - [7. Native AI 整合（MCP Server）](#7-native-ai-mcp-server)
    - [8. Plugin 相容性](#8-plugin)
    - [9. 我這篇文章會不會壞掉？](#9)
    - [10. 給「現在該不該升」的建議](#10)
    - [References（2.0 相關）](#references-2-0)

我最近因為想要練習寫文章，所以找了幾個部落格內容管理系統，最後選定使用 Grav 當作部落格網站。

## 1. 檢查與更新 VM 環境

我這邊選 **Linode** 因為本身喜歡簡單容易操作的介面，架設這個選最便宜的方案 1 CPU。

在購買 VM 後，SSH 進去的第一件事情就是檢查 VM 環境：

```
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 20.04.6 LTS
Release:        20.04
Codename:       focal
```

這邊確定為 **Ubuntu 20.04 LTS**。

## 2. 安裝 PHP 和移除 Apache

把 apt 套件更新並且把系統自帶的 apache 移除，因為 nginx 在靜態檔案的處理速度比較快：

```
$ sudo apt update -y && sudo apt upgrade -y && sudo apt remove apache2* && sudo apt autoremove
```

接下來安裝 PHP 基本套件：

```
$ sudo apt install vim zip unzip nginx git php-fpm php-cli php-gd php-curl php-mbstring php-xml php-zip php-apcu
```

調整 php.ini — 把 `cgi.fix_pathinfo` 改為 1，這邊是因為有資安的問題（[參考](https://www.laruence.com/2010/05/20/1495.html)）：

```
$ vim /etc/php/8.1/fpm/php.ini
```

```
cgi.fix_pathinfo=1
```

```
$ systemctl restart php8.1-fpm
```

## 3. 配置 PHP-FPM

```
$ cd /etc/php/8.1/fpm/pool.d
$ mv www.conf www.conf.bak
$ vim grav.conf
```

由於我們這邊是選擇 1 CPU 的：

```
[grav]
user = grav
group = grav
listen = /var/run/php/php7.4-fpm.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
chdir = /
```

建立使用者：

```
$ adduser grav
```

> 在 Linux 中，使用 `adduser grav` 指令時，通常會同時建立：
> 
> - 使用者 `grav`：這是你指定的使用者名稱。
> - 群組 `grav`：系統會自動建立一個與使用者名稱相同的群組。
> - 使用者 `grav` 會被加到群組 `grav`：新建立的使用者 grav 會被自動加入到剛建立的群組 grav。
> 
> 換句話說，使用者 grav 的預設主要群組是 grav。因此，當使用者 grav 建立檔案或目錄時，這些檔案或目錄的預設所屬群組也是 grav。
> 
> 如果你希望使用不同的群組或不自動建立群組，你可以使用其他參數來自定義，例如使用 `--ingroup` 選項。

切換使用者並建立網站目錄：

```
$ su - grav
$ mkdir -p www/html
$ cd www/html
```

測試 HTML 跟 PHP 的格式會不會成功：

```
$ touch index.html && echo 'hello world!' >> index.html;
# 測試 index.html
$ rm index.html
$ touch index.php && echo '<?php phpinfo();' >> index.php
# 測試 index.php
```

退出 grav 角色。

## 4. 配置 Nginx

```
$ exit
# 這邊會切換成 root
$ cd /etc/nginx/sites-available/
$ ls -al
default
$ vim grav
```

```nginx
server {
    # listen 80;
    index index.html index.php;
    ## Begin - Server Info
    root /home/grav/www/html;
    server_name localhost;
    ## End - Server Info
    ## Begin - Index
    # for subfolders, simply adjust:
    # `location /subfolder {`
    # and the rewrite to use `/subfolder/index.php`
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    ## End - Index
    ## Begin - Security
    # deny all direct access for these folders
    location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
    # deny running scripts inside core system folders
    location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
    # deny running scripts inside user folder
    location ~* /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
    # deny access to specific files in the root folder
    location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
    ## End - Security
    ## Begin - PHP
    location ~ \.php$ {
        # Choose either a socket or TCP/IP address
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        # fastcgi_pass unix:/var/run/php5-fpm.sock; #legacy
        # fastcgi_pass 127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    }
    ## End - PHP
}
```

設定完成後 `nginx -t` 測試：

```
$ cd ../sites-enabled
$ ln -s ../sites-available/grav
$ rm default
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ systemctl restart nginx
$ systemctl restart php8.1-fpm
```

> `sites-available`：這個目錄包含 Nginx 的 virtual host 設定檔，可以放多組、不同設定的站台設定。
> 
> `sites-enabled`：包含指向 `/etc/nginx/sites-available` 目錄的符號連結。當 `sites-available` 中的設定檔被符號連結過來，Nginx 重啟後該站台就會生效。

網站建立好之後，切換去 grav 使用者，並在網站目錄底下開始建立 Grav：

```
$ su grav
$ cd ~/www
$ wget -O grav.zip https://getgrav.org/download/core/grav/latest
$ unzip grav.zip
$ rm -Rf html
$ mv grav html
$ cd ~/www/html
$ bin/grav clear
```

```
Clearing cache
Cleared:  /home/grav/www/html/cache/twig/*
Cleared:  /home/grav/www/html/cache/doctrine/*
Cleared:  /home/grav/www/html/cache/compiled/*
Cleared:  /home/grav/www/html/images/*
Cleared:  /home/grav/www/html/assets/*
Touched: /home/grav/www/html/user/config/system.yaml
```

重啟之後，拜訪 Linode 上面給你的 public IP，有看到畫面就成功了。

### References

- https://learn.getgrav.org/17/webservers-hosting/vps/linode
- https://www.laruence.com/2010/05/20/1495.html
- https://taobig.org/?p=650

---

## 🚀 Grav 2.0 補充更新（2026/08）

這篇原文是 **Grav 1.7 時代**的 setup。Grav 在 **2026 年 5 月**正式推出 **2.0 stable**，跟 1.7 比起來有幾個會直接影響這份 setup 的差別，整理在下面。

### 1. PHP 版本需求升級

| 版本 | 支援 PHP |
|---|---|
| Grav 1.7（這篇） | PHP 8.0 - 8.3 |
| **Grav 2.0** | **PHP 8.3 - 8.5+** |

這篇裝的是 PHP 8.1，**跑 2.0 會直接掛掉**。新的 setup 請從 PHP 8.3 開始：

```
$ sudo apt install php8.3-fpm php8.3-cli php8.3-gd php8.3-curl \
    php8.3-mbstring php8.3-xml php8.3-zip php8.3-apcu
```

PHP-FPM pool 設定相應改成 `php8.3-fpm.sock`，Nginx 的 `fastcgi_pass` 也要記得改。

### 2. 升級方式完全不一樣：Migration ≠ Upgrade

> **沒有** `bin/gpm self-upgrade` 從 1.7 升到 2.0。

官方原文很直接：「You do not upgrade to Grav 2.0 in place. You migrate.」原因是底層 Symfony / Twig / library stack 全部換過，原本那種「就地 mutate running site」的升級方式在實戰上一直踩雷。

正確做法：

1. 在現有的 1.7 站裝一個 **`Migrate to Grav 2.0`** plugin
2. plugin 會在旁邊的子資料夾 stage 一個全新的 2.0 安裝
3. 跑 migration — 內容、帳號、相容 plugin 都會被搬過去
4. 你可以對著真實內容測試任意久
5. 確定沒問題再 **promote**（會自動備份舊站）
6. 不滿意就 **reset**，舊站原封不動

**不要**直接抓 2.0 zip 蓋到舊站 — Symfony / Twig 底層都換了，覆蓋會壞掉。

> 💡 還沒準備好？**Grav 1.7.53 是最後一個 1.7**，會持續收到 security fix，可以安心停在這裡。

### 3. Admin 換成 Admin Next

原本那個 jQuery + Twig 拼出來的 admin 叫 **Admin Classic**，2.0 預設換成 **Admin Next**：

- 全 API 驅動，dark / light mode 都有
- 三種頁面檢視（含 Mac Finder 風格欄位檢視）
- 自訂 dashboard、即時多人協作編輯
- 多語系 + RTL 開箱即用

Admin Classic 在 2.0 還是可以裝回去，但官方主推 Next。

### 4. First-party REST API（跟你直接有關）

**你寫的 `binapi` plugin 用的就是這個 API** — 只是 1.7 時代它是外掛，**2.0 變成核心功能**，authentication、permission check 都內建。涵蓋 pages / media / config / users / plugins / system tasks。

→ 你現有的 binapi 在 2.0 應該可以直接用，但需要加一個 **compatibility flag**（見下面第 8 點）。

### 5. Markdown 升級：GitHub Flavored Markdown 預設開啟

- ✅ Task list（`- [ ]` / `- [x]`）
- ✅ Highlight（`==重點==`）
- ✅ Autolink（裸 URL 自動變連結）
- ✅ 表格增強（optional plugin）
- ✅ 速度更快的新 renderer

### 6. ⚠️ 安全改動：Twig in Content 預設關閉

2.0 把「在 page content 裡寫 Twig」改成 **sandboxed + 預設關閉**（1.7 是開放的）。這是補一個真的安全漏洞。

→ 如果你的文章或 plugin 有靠 in-content Twig 渲染東西（例如 `{{ site.title }}`），2.0 上不會自動跑，要明確開 + 進 sandbox 才能用。

### 7. Native AI 整合（MCP Server）

2.0 內建 **first-party MCP server**，AI agent 可以透過同一套 API + 同一套權限，做你在 admin 能做的任何事。Andy Miller（Grav 創辦人）說他自己已經這樣跑站好幾個月。

未來如果想接 AI 編輯流程（例如用 Claude Code 直接改 dbyellow.com），可以走這個介面，不用自己寫整合。

### 8. Plugin 相容性

好消息：**大部分 plugin 在 2.0 直接能用**，event system / blueprint / plugin architecture 沒變。

唯一要做的：在 plugin 的 blueprint YAML 裡加一行：

```yaml
compatibility:
  grav2: true
```

讓 GPM 和 migration tool 知道你有測過 2.0。建議你幫 `binapi` 也補上這個 flag。

### 9. 我這篇文章會不會壞掉？

不會 — **內容是純 markdown 檔**，跟版本無關。`/user/pages/` 整個資料夾被 migration tool 原封不動搬過去，你的文章、taxonomy、frontmatter 都會跟著走。

真正會壞的是：**PHP 版本、底層 Symfony/Twig、相依套件**。這幾個都是 server 層的事。

### 10. 給「現在該不該升」的建議

| 情境 | 建議 |
|---|---|
| 站還在跑 1.7.53，沒特殊需求 | **留在 1.7.53**，繼續收 security fix |
| 想用 Admin Next / 想接 AI agent | 排時間用 Migrate plugin 升 2.0 |
| 自己有 plugin | 先測試在 2.0 跑得起來，順便加 `compatibility: { grav2: true }` |
| 純架站教學用途 | 可以直接從 2.0 開始學，這篇的 nginx + php-fpm 概念還是通用的 |

### References（2.0 相關）

- https://getgrav.org/blog/grav-2-stable-released
- https://learn.getgrav.org/16/migration/migrating-from-grav-1
- https://learn.getgrav.org/16/advanced/api-reference
- https://getgrav.org/blog/admin-next-a-modern-admin-experience
- https://getgrav.org/blog/grav-2-developer-guide-compatibility-flags

 [ Previous Post](https://www.dbyellow.com/blog/family-thirteen-cards-2026) [Next Post ](https://www.dbyellow.com/blog/move-from-tmux-to-wezterm) 

#### Other Related Posts:

 [ ![LightRAG + OpenClaw + qmd：打造有記憶的本地 AI 助理](https://www.dbyellow.com/user/pages/01.blog/2026-04-lightrag-openclaw/hero.jpg) ](https://www.dbyellow.com/blog/2026-04-lightrag-openclaw) [  LightRAG  ](https://www.dbyellow.com/tag:LightRAG#blog_list) [  OpenClaw  ](https://www.dbyellow.com/tag:OpenClaw#blog_list) [  qmd  ](https://www.dbyellow.com/tag:qmd#blog_list) [  RAG  ](https://www.dbyellow.com/tag:RAG#blog_list) [  知識圖譜  ](https://www.dbyellow.com/tag:%E7%9F%A5%E8%AD%98%E5%9C%96%E8%AD%9C#blog_list) [  本地部署  ](https://www.dbyellow.com/tag:%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2#blog_list) [  AI  ](https://www.dbyellow.com/tag:AI#blog_list) 

###  LightRAG + OpenClaw + qmd：打造有記憶的本地 AI 助理 

[LightRAG + OpenClaw + qmd：打造有記憶的本地 AI 助理](https://www.dbyellow.com/blog/2026-04-lightrag-openclaw)

#### Table of Contents

- [前言](#)
- [三個工具，各有所長](#-1)
    - [OpenClaw：Agent 框架](#openclaw-agent)
    ...

 21st Apr 2026 - Mark 

###  Classic Modern Architecture 

[Classic Modern Architecture](https://www.dbyellow.com/blog/ubuntu-with-alacritty-on-windows)

今天試裝之前為了研究 linux 系統 而有小玩的 windows wsl 系統，這次嘗試，是因為在公司mac 上玩了 alacritty 這個新的終端工具，想基於他的跨平台性能，iterm 2 以下安裝為非乾淨的 windows 安裝，有一些指令，可能會稍微有誤差

使用管理員執行 Powershell

```
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```

安裝 Ubuntu 18.04 [url](https://www.microsoft.com/store/apps/9N9TNGVNDL3Q)

```shell
sudo apt-get update
sudo apt-get...
```

 18th Sep 2020 

- [部落格](https://www.dbyellow.com/)
- [爬山](https://www.dbyellow.com/hiking) 

    - [皇帝殿](https://www.dbyellow.com/hiking/huang-di-diaen)
- [生活](https://www.dbyellow.com/life)
- [關於](https://www.dbyellow.com/about)

---

## Navigation

- Parent: [部落格](https://www.dbyellow.com/index.md)
- Previous: [Move from tmux to wezterm](https://www.dbyellow.com/blog/move-from-tmux-to-wezterm.md)
- Next: [客廳裡的十三支戰場：一家大小的牌桌風雲](https://www.dbyellow.com/blog/family-thirteen-cards-2026.md)
