使用 Octopress 作為部落格平台的其中一個問題就是需要在一台電腦上設定一個工作環境。雖然設定環境對有點技術背景的人來說不算太困難,但是只能從有適當環境的電腦來寫文章,似乎不是一件方便的事。Octopress 能不能跟其他部落格平台,像是 WordPRess 一樣,只要使用瀏覽器,就可以隨時隨地寫文章?答案是肯定的,但必須先提醒,本文所介紹的方法對一般使用者來說仍舊牽涉許多技術細節,如果你不了解文章內容描述的方法,請不要輕易嘗試。

在本文,山姆鍋 介紹如何利用線上工具來做到可以在不同電腦間發佈 Octopress 文章。之前說過,使用 Octopress 寫文章,其實比較像是軟體開發,一樣是:寫程式、編譯、測試以及發佈的流程。既然像寫程式,那可不可像程式一樣做到撰寫、測試、部署自動化?當然是可以!底下就以 開發者文摘 為例,告訴大家如何做到。

設定 GitHub Repository 作為部落格空間

本文假設您已經在 GitHub 上設定好一個 repository,「開發者文章」部落格的 repository 是 eavatar/developers.tw。 如果您還不知道如何進行這個步驟,請參考:

Github Page + Octopress

您需要為這個 repository 建立部署專用的 key pair。並將其中的 public key 關聯到這個 repository,這樣,之後才能在 Travis-CI 中進行部署。

建立 GitHub Pages 作為網頁空間

GitHub Pages 有兩種,一種是個人網頁(Personal pages),一種是專案網頁。本文採用個人網頁。個人網頁的 repository 名稱必須是:“username”.github.com 或者 “username”.github.io,其中 & quot;username" 就是您 GitHub 的用戶名稱。不管使用哪個,存取的網址都是 http ://“username”.github.io/。之後山姆鍋會說明如何將域名改為 ‘developers.tw’。 在命令列,使用下列指令建立 GitHub Pages。

1
2
3
4
$ rake setup_github_pages
Enter the read/write url for your repository
(For example, '[email protected]:your_username/your_username.github.io)
Repository url:

按照提示輸入您的 GitHub Pages 的 repository 名稱。開發者文摘使用的是’eavatar.github.io’。設定好 GitHub Pages 後,第一次可能需要幾分鐘網頁才會正確產生。 為了能夠部署到這個 repository,需要修改 Octopress 的 Rakefile,讓 deploy_default 這個參數的值為 “push”。例如:

1
deploy_default = "push"

使用下列指令試看看可不可以正確部署到 GitHub Pages。

1
$ rake gen_deploy

如果 GitHub 上,‘evatar.github.io’(需要換成您自己的 repository)有出現部署的檔案,那應該就沒有問題。

設定 Travis-CI 做自動建構與部署

Travis-CI 提供雲端持續整合 (continous integration) 服務,可以直接整合 GitHub 上的專案。 為了讓專案可以在 Travis-CI 上建構,需要在根目錄建立一個’.travis.yml’檔案。底下是開發者文摘使用的內容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
branches:
only:
- master
language: ruby
rvm:
- 1.9.3

before_script:
# Set the git config stuff, so Git stops yelling at us
- git config --global user.name "Eavatar (via Travis-CI)"
- git config --global user.email "[email protected]"
# Set read-write git origin
- git remote set-url origin $REPO.git
# Unpack ssh key for git
- echo -n $id_rsa_{00..30} >> ~/.ssh/id_rsa_base64
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
# Disable SSH server fingerprint verification
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
# Set deployment target to github pages.
- rake setup_github_pages[$REPO]
# To reset the 'url' to the custom domain in '_config.yml'
- git checkout -- _config.yml
script:
# Generate site
- rake generate
after_script:
# Deploy!
- rake deploy
env:
global:
# Repo read-write address
- REPO="[email protected]:eavatar/eavatar.github.io"
# SSH key. Encoded. See https://gist.github.com/4631240
- secure: "isiGSNSbp+m/LzegVKAlD7fg0xa4882KQxmQLWwcYTL6x3uI6otGQs+5gduM\nS2yIRqrrZnZFMlQrSg/PI5nztR+Cvz1OrpzVEDvQ+sZ9bvB1kYymPuxDOWvc\n5o25UD824F9IemgaliVUc+wIDmAdGJwu/Dluek5dduLD/PLy26c="
- secure: "F26cKapu7SoOVCO91jC9lqRkzPWabQ43kzFaIsrLLRHzZ/YH8kyj+B2dOO7I\n6PFz5O8hBsNcSF/UAIMlaqPXDp7prNXluiTdRhyBdkzRpJLI84mqTZ55s3+L\nGGI+hS5znFqXvK2S7/J7DWAhYmilxjHLIEs1OgRFtNwMW+l+E7Q="
- secure: "KzTioDF1N2riuxkLgjyb+WT95aUTeG54qJ+n3DDQSbXitydhevMqRzzf6cJf\nRUKU7Z4iA5ArWycL7eHQ1KAwO9g2xXy9c7i6Yvsw9BMUIUEUePuXgsa1SnMS\nXcOqZ5SpaCtKNUvdf2YtA5GdQMi4vJ4aQGgJOqZcHTWfH8muvks="
- secure: "jftKtS2WMyYD6dxDqhGgWhWql9cqRKN8E1ViNwuq6m5F6HBJECUbPMpDDJsT\naWAKYQqFIPp/ZhaG7qqKxCsxIyCbOPPjbl/AnKLdHOGT8qSLgVepvujKujUU\nSB2hrr+M2ZF3U9ljLldnkogxr75cU6Yb5vVsYef1b56xJIjCi24="
- secure: "YrSZCER3s+N5iY4EiXVPa5mgxyAyxspoaI4toV+fu9X/dWZWezY+0Fb2v5VQ\n81/zB8NS+S+oMHk8Cgwzkj6ZQDXb+D0TOqvS4AFV8KrMhxL3ADxO6erPrMiJ\n5xQhU47f3rCA++C6kkd7CjHnrV2R8ef+WRT0cSOqClDFrtQFIk8="
- secure: "UI/9SsAdETNj6htFtlW2YFyoYBslf+PRp335mVrZh2cHbAJv674saxXT69ah\nq3irGsezBwXdECH2fpdtZmROBGoNx/zGeuuMVAa6+mf4FZU5K0xz8m+EmklK\niJyAfbWiK93oRO5/CZrUBJ1e+me+GtVcze2k/6VHlzNloGNaN4E="
- secure: "BuLPC+NxtHkF53xxTdHPZQvY7mYK5uTqDG1FSfVNbTlU1mxNACqG9YsJ5ZLs\n1PYo+ZHXSdYyv2641idGhqJwmymBOqFgNgujwGeusZPQpb2u71P/p/1w2I01\n0AR3bKJmUpivsxhhrZ42AURGmB2rMWYV4Z04T8yyc19SWpmoHgE="
- secure: "FYNqxA6aeOCYs34w7ZNjjf8Na1N4UoTNS21AOQSCXFU/qAS1FZ0BYLb2EbQD\nB14/0n8qsyjzuiaW8E9h/JC7jdCouJDguwQ2r+jNMNw6WKNyLKiz8pvujh6d\np4XUHLChGBVhkK0BPQw27plTiN54iHR5e9f+Gg9S+/q9RkV8uRM="
- secure: "Y300+XT68eN9KkodepEGatVNpia973uyMJf8Y5Sf+WF6twsyNjRCcanR6SkU\nHEz/JXvojySB4W8NA0BEf1/XhAyWD3qLzAaTb/p1Qs1YaDSzmomDelygiSZ1\nbZB6be+M0gwDjFpUKSXWt2BuJXtEt0sDOfFMtrnlvpHIWT7W1GI="
- secure: "UInwrNPNmmJLnyP1g/exR7/08mpJwZ4nVsn4vuEP3oaYwiwYiZ3mMfYG6OGV\nuiIyFkn9BQ/yBJYCvjMxsUbJF0RCW32mHAfVRCXKL0MrqPjlfMoRRegAcgLK\nfnTwssv9po/1i9JHIdf1Pxd+xbAS9c8Q45/TDKel7aF6MUNoho4="
- secure: "hSujJ6uTgYHo4qMDxrmi+8oRCL0Z/5jdm3Zs8xUKI1wziuUSytcNuz2VtX6E\nWdKkMIkmBlJQvk4csJ+oZkqyfsDCuADYEun1U2UmOgiFV+wk7ALPev63wdbu\nBM3JYj7i/R1+tJjVUlpP1aOPHf8zHGe7SvUWZEgzA9PZHp8hhqM="
- secure: "aJesFAVF0MgXxOxoPYci5ekuqXjau2T0GQMd1z2XJQhQFbkboAvDLDytR7vi\nyopRO4gZ7FTyaluljE+lI0Il9PmL8MJQkrL1gB7t0LdBuWRs+vXryub45GSZ\nBUr8EzezQALtfUrZyt3csx+uilbB0a7iwllfHn8s98R99HBT7eA="
- secure: "Xham4T6i88+bmsfVQDZQdouBYz+VWPyegjiyZrJdYDo30RBy+Lnfmgq9gixs\niGTZZjxAltBNdLOzAlGKQWA25eNuvt6zqr2aLZ8ftxMHJQV3q/LoIICgl9CH\ngV16b8UiAsparV+voB1veMAT3EmdmmhDkJLw6239O9QspC2vds8="
- secure: "YFPzT3E1xj/D+lXNfwHkp1gmI2+MVmf1QFfdKkoDf0XhIvHk8L9NR26OeQTy\nc1nYy1oGEZCVRgzf6gXG4M6cT3G0qQ0lwPxqSfYJhFnNiJUZ4956NzeMtdnp\nuJCToYnuRT90KmLiWyXlhQ1SUmaSBGww2gyyQBVOweMbEc4hpTQ="
- secure: "iS2Ljp7R3cdYvUIxP7TkswWT2thmI8WX7ps+YBpwQag5q/681tbfV3T5tUpH\n8Y1Y0/fRPb6XXNuNUoY0p1IpvemXvU7KipVxtI6T6qiMzZNtGJvZ5NxnIili\nKlM31RDS/YsuiQ8qaznOBAgjgjUa/9GPqsjLZEwjO37Sri0N/kQ="
- secure: "TMt9YNKEt3ptVpkg3p3GMZ3PefVjmK3vDmbLzHmmlGGZ5JYg2GO1Td2ZS94K\nXABBAZD600TGBx5CLTqh1XhwiKQi3X8g8mWNy4ty2FGns8j7R0pliLY9Ogkq\nxAheer4DleeV66OMzvQcIFlXJVPK26wttC+/EbDlGqnNNTinom0="
- secure: "G8I9m0D15nplGIRcKy/1xdsVH3gy9S9j5KnrK+ZCsQfanMwYK3LorHEtnVTC\nYpnU17vB98O0UFt8W2UD0bb/Y7VfHWVPH77jbFUz4bl3d2vLOCRKJl0lJT+w\nIdG2JbC0xt8k2O8g6AvCjHAVRxPTU8wEIjL+uSEHlUNXGQmvJfs="
- secure: "MJbLJCbIfzGbQDwiWDCxSEFomIIKHGnoLpsCxr2V6WW8k4ysyNj5cPpdU1Zp\n6G0TGUzqcU+9D6kC011VqYviZEEsBJCx4WKd3LFMJ804dBPWkb/UzegEONlo\nYskwfucHu+ykvQ+VIc0lBRLJe9nX0Jq2y5tmqIirRK+/4U6yBQU="
- secure: "CEmvHKzOFnXzdD+VRSaJ4J7f7eyaojCHsDFddSORwAJbPgmRh5zWDM7DNZa0\n9LQvrMtX4tepLY2fqRgLl8Sr65KmP0hTGN9Ay+YFOOO5u+Bp7f+c+yndpgf4\n5j2O8ewYwyhFp7EY3qWKv0tUD2o2oITR72XZ1BVmv55NDORKgAE="
- secure: "b54/nTQjWbh7XJsxa/6y69Zu+AKHoKZ5rNsTdu3m9TbEGExCZRGu4AONnBTy\nzYQtJ4rxL4yCmf27Mg6G2cWkQD8/reEvFblT2/kwNMgB48mrVFJU+6JAAebs\nAkcXV7Mm/eRMCa/gdqKhV7UH88dArq21Z/corNsYK+cMzUy7WUs="
- secure: "Eorn76Z6sVhPOECUPwG2fHOY6X2q/1gZTY4BOkKkQVTBQ3jrrIwvPp8TGxIh\niJPGEtUt4kAeYAG5624ezfs89BPewAeznNjFFsgsQ2SOspczzxxbB5Xcgwaj\nsKxtEqapEu8wdL6BrzggA7o/QtHkSbiv16kaYL7Oy+Ya0uwvvV4="
- secure: "gFwuTn+sWNnXQj3uEn/SrVBGLRU0pxAKSQEu7+SBrgZPAjbFV6aLVMgPMF9C\nR4h+XWigQpTOTyiqqaORTfKGZ5N8oIxH4l/RDjUJOBOq0mwd87FK2n3oS5ZQ\nvAfVxZnlqVSXYNaAJzkiUtAiTsEnEQQdcgFLQqdiHtRXUPiEvmI="
- secure: "lj35YWQRZe6brLTOC39QDw/WF6kX0G9KSbqbdud+xkpfaO4E0hTqlV6kze6H\nCHN88BA8QavERCed2jURM3rVfMQFZH9jXFJKWX1/UXzYGG6xJVZYquLIPTj2\n68kPaSdcHpxwW+O0LCekPjg2+5bMe8uqTIIohBl3fysQOW3VGzY="

其中,最複雜的部分就是需要預先把部署用的 SSH private key 進行編碼,並在部署時進行解碼,讓 Travis-CI 服務器擁有權限部署卻又避免讓其他人知道 SSH private key。 假如還沒有的話,安裝 Travis-CI 的命令列工具:

1
$ sudo gem install travis

在 Linux 平台,可以使用下列指令進行 private key 編碼:

1
2
3
$ base64 --wrap=0 ~/.ssh/id_rsa_deploy > ~/.ssh/id_rsa_deploy_base64
$ ENCRYPTION_FILTER="echo \$(echo \"- secure: \")\$(travis encrypt \"\$FILE='\`cat $FILE\`'\" -r eavatar/developers.tw)"
$ split --bytes=100 --numeric-suffixes --suffix-length=2 --filter="$ENCRYPTION_FILTER" ~/.ssh/id_rsa_deploy_base64 id_rsa_

其中,‘evatar/developers.tw’需要換成您自己的 GitHub repository。如果在建構時,沒有像下圖出現’export id_rsa_00=[secure]’,那可能是您指定的 Git repository 不正確。

更改為客制域名: Developers.TW

GitHub Pages 支援使用客制域名,有就是讓您可以使用自己的域名來存取部落格網頁。為了使用這個功能,您需要在 GitHub Pages 的根目錄建立名稱為’CNAME’的檔案,其內容事您要使用的域名,開發者文摘的域名是:‘developers.tw’。 建好了’CNAME’這個檔案後,需要設定 DNS 的 CNMAE 紀錄,讓’developers.tw’對應到’eavatar.github.io’。

使用 Prose.io 撰寫文章

Prose.io 讓您可以使用瀏覽器直接在線上編輯 GitHub 上的檔案。透過 Prose.io,我們就可以隨時撰寫博客文章了。在_config.yml 設定檔,加入下面設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
#-----------------------#
# prose.io settings #
#-----------------------#
prose:
rooturl: "source"
metadata:
"source/_posts": |
layout: post
title: "Title"
comments: true
categories:
published: false
date: CURRENT_DATETIME

Prose.io 支援 Markdown。

參考來源