[{"data":1,"prerenderedAt":2975},["ShallowReactive",2],{"navigation":3,"posts-undefined-Ghost-0-999":20},[4,8,12,16],{"title":5,"path":6,"stem":7},"首页","\u002F","00.index",{"title":9,"path":10,"stem":11},"文章","\u002Fposts","01.posts",{"title":13,"path":14,"stem":15},"动态","\u002Fmoments","02.moments",{"title":17,"path":18,"stem":19},"关于","\u002Fabout","09.about",[21,272,2358,2388,2426,2558],{"id":22,"title":23,"body":24,"class":252,"cover":253,"coverSize":252,"date":254,"description":30,"draft":255,"extension":256,"hideComments":255,"location":252,"meta":257,"navigation":108,"path":258,"readingTime":259,"seo":264,"sitemap":265,"stem":266,"tags":267,"time":252,"weather":252,"__hash__":271},"posts\u002Fposts\u002F2023\u002F20230408.upgrade-ghost-5-0-to-5-42.md","Ghost 5.0 升级到 5.42",{"type":25,"value":26,"toc":250},"minimark",[27,31,198,208,211,240,243,246],[28,29,30],"p",{},"距离上次升级 Ghost 已经过去快 1 年了，上次是 Ghost 5.0 刚发布的时候升级的，这次直接把容器镜像版本改为最新的 5.42 时，报了个错：",[32,33,38],"pre",{"className":34,"code":35,"language":36,"meta":37,"style":37},"language-log shiki shiki-themes material-theme-lighter github-light github-dark","ERROR connect ECONNREFUSED 127.0.0.1:3306\nconnect ECONNREFUSED 127.0.0.1:3306\n\n\"Unknown database error\"\n\nError ID:\n500\n\nError Code:\nECONNREFUSED\n\nError: connect ECONNREFUSED 127.0.0.1:3306\nat \u002Fvar\u002Flib\u002Fghost\u002Fversions\u002F5.42.0\u002Fnode_modules\u002Fknex-migrator\u002Flib\u002Fdatabase.js:57:19\nat TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16)\n","log","",[39,40,41,79,103,110,116,121,130,136,141,149,155,160,186,192],"code",{"__ignoreMap":37},[42,43,46,50,54,58,61,64,66,68,70,73,76],"span",{"class":44,"line":45},"line",1,[42,47,49],{"class":48},"s_sjI","ERROR",[42,51,53],{"class":52},"su5hD"," connect ECONNREFUSED ",[42,55,57],{"class":56},"s39Yj","127",[42,59,60],{"class":52},".",[42,62,63],{"class":56},"0",[42,65,60],{"class":52},[42,67,63],{"class":56},[42,69,60],{"class":52},[42,71,72],{"class":56},"1",[42,74,75],{"class":52},":",[42,77,78],{"class":56},"3306\n",[42,80,82,85,87,89,91,93,95,97,99,101],{"class":44,"line":81},2,[42,83,84],{"class":52},"connect ECONNREFUSED ",[42,86,57],{"class":56},[42,88,60],{"class":52},[42,90,63],{"class":56},[42,92,60],{"class":52},[42,94,63],{"class":56},[42,96,60],{"class":52},[42,98,72],{"class":56},[42,100,75],{"class":52},[42,102,78],{"class":56},[42,104,106],{"class":44,"line":105},3,[42,107,109],{"emptyLinePlaceholder":108},true,"\n",[42,111,113],{"class":44,"line":112},4,[42,114,115],{"class":48},"\"Unknown database error\"\n",[42,117,119],{"class":44,"line":118},5,[42,120,109],{"emptyLinePlaceholder":108},[42,122,124,127],{"class":44,"line":123},6,[42,125,126],{"class":48},"Error",[42,128,129],{"class":52}," ID:\n",[42,131,133],{"class":44,"line":132},7,[42,134,135],{"class":56},"500\n",[42,137,139],{"class":44,"line":138},8,[42,140,109],{"emptyLinePlaceholder":108},[42,142,144,146],{"class":44,"line":143},9,[42,145,126],{"class":48},[42,147,148],{"class":52}," Code:\n",[42,150,152],{"class":44,"line":151},10,[42,153,154],{"class":52},"ECONNREFUSED\n",[42,156,158],{"class":44,"line":157},11,[42,159,109],{"emptyLinePlaceholder":108},[42,161,163,165,168,170,172,174,176,178,180,182,184],{"class":44,"line":162},12,[42,164,126],{"class":48},[42,166,167],{"class":52},": connect ECONNREFUSED ",[42,169,57],{"class":56},[42,171,60],{"class":52},[42,173,63],{"class":56},[42,175,60],{"class":52},[42,177,63],{"class":56},[42,179,60],{"class":52},[42,181,72],{"class":56},[42,183,75],{"class":52},[42,185,78],{"class":56},[42,187,189],{"class":44,"line":188},13,[42,190,191],{"class":48},"at \u002Fvar\u002Flib\u002Fghost\u002Fversions\u002F5.42.0\u002Fnode_modules\u002Fknex-migrator\u002Flib\u002Fdatabase.js:57:19\n",[42,193,195],{"class":44,"line":194},14,[42,196,197],{"class":48},"at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16)\n",[28,199,200,201],{},"重试了几次都不行，在 Ghost 的文档中找了半天也没发现从 5.0 升级到 5.42 中间有什么 breaking changes。最后从 Ghost 的 Docker 镜像维护仓库找到了相关的 Issue：",[202,203,207],"a",{"href":204,"rel":205},"https:\u002F\u002Fgithub.com\u002Fdocker-library\u002Fghost\u002Fpull\u002F323",[206],"nofollow","#323",[28,209,210],{},"大致原因主要是这样，Ghost 5.0 之后其实是有个 breaking change，就是原先数据库是支持 SQLite3 和 MySQL 5 的，在 5.0 之后，数据库只支持 MySQL 8 了，但是 SQLite3 在开发环境还是支持的。对应的 Docker 镜像，在 5.9 之前，都还是可以继续用之前的 SQLite3 的，但是在 5.9 这个版本中，Docker 镜像将默认数据库改为了 MySQL 8，这就导致从低版本升到高于 5.9 版本的镜像之后，数据库会直接找不到。在这个 PR 中，其实给出了一个临时的解决方案，就是在环境变量中加两个变量，就可以继续使用 SQLite3，这两个变量是：",[32,212,216],{"className":213,"code":214,"language":215,"meta":37,"style":37},"language-yaml shiki shiki-themes material-theme-lighter github-light github-dark","database__client: sqlite3\ndatabase__connection__filename: \u002Fvar\u002Flib\u002Fghost\u002Fcontent\u002Fdata\u002Fghost.db\n","yaml",[39,217,218,230],{"__ignoreMap":37},[42,219,220,224,227],{"class":44,"line":45},[42,221,223],{"class":222},"sQzsp","database__client",[42,225,75],{"class":226},"sP7_E",[42,228,229],{"class":48}," sqlite3\n",[42,231,232,235,237],{"class":44,"line":81},[42,233,234],{"class":222},"database__connection__filename",[42,236,75],{"class":226},[42,238,239],{"class":48}," \u002Fvar\u002Flib\u002Fghost\u002Fcontent\u002Fdata\u002Fghost.db\n",[28,241,242],{},"添加完之后，容器可以正常升级了。",[28,244,245],{},"但，既然官方已经将数据库支持重点改为了 MySQL 8，不怕麻烦的话，也可以升级下数据库。原本准备写个 MySQL 8 的升级教程的，想想不折腾了，我的博客用轻量的 SQLite3 就够了。",[247,248,249],"style",{},"html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}",{"title":37,"searchDepth":81,"depth":81,"links":251},[],null,"jpg","2023-04-08",false,"md",{},"\u002Fposts\u002F2023\u002Fupgrade-ghost-5-0-to-5-42",{"text":260,"minutes":261,"time":262,"words":263},"2 min read",1.995,119700,399,{"title":23,"description":30},{"loc":258},"posts\u002F2023\u002F20230408.upgrade-ghost-5-0-to-5-42",[268,269,270],"技术","博客","Ghost","jTG5prR9EJe76ga8Usd6FU3xLZllrEAUvtzpDIDc-io",{"id":273,"title":274,"body":275,"class":252,"cover":253,"coverSize":252,"date":2344,"description":37,"draft":255,"extension":256,"hideComments":255,"location":252,"meta":2345,"navigation":108,"path":2346,"readingTime":2347,"seo":2352,"sitemap":2353,"stem":2354,"tags":2355,"time":252,"weather":252,"__hash__":2357},"posts\u002Fposts\u002F2022\u002F20220524.use-gitlab-to-deploy-ghost-theme-automatically.md","使用 GitLab CI 自动部署 Ghost 主题",{"type":25,"value":276,"toc":2342},[277,283,286,295,1067,1078,1087,1091,1101,1104,1107,1130,1137,2083,2088,2194,2201,2322,2336,2339],[278,279,280],"blockquote",{},[28,281,282],{},"居家隔离的第 N 天",[28,284,285],{},"今天收到了 Ghost 5.0 发布的邮件，第一时间更新了下，发现主题里有些功能已经不兼容了，于是准备对主题做下更新。在看 Ghost Integrations 的时候发现有个 GitHub 的插件特别好用，支持通过 GitHub Actions 自动部署你的主题。但是我自己的项目用的都是 GitLab，找了一圈，没有官方的插件。于是尝试自己通过 GitLab CI 来实现。",[28,287,288,289,294],{},"大致看了下基于 GitHub Actions 自动部署的实现方式，通过官方提供的一个 ",[202,290,293],{"href":291,"rel":292},"https:\u002F\u002Fgithub.com\u002FTryGhost\u002Faction-deploy-theme\u002Fblob\u002Fmain\u002Findex.js",[206],"TryGhost\u002Faction-deploy-theme"," 的步骤，代码很简单，总共 40 行，我们来看下它做了什么：",[32,296,300],{"className":297,"code":298,"language":299,"meta":37,"style":37},"language-javascript shiki shiki-themes material-theme-lighter github-light github-dark","const path = require('node:path')\nconst core = require('@actions\u002Fcore')\nconst exec = require('@actions\u002Fexec')\nconst GhostAdminApi = require('@tryghost\u002Fadmin-api');\n\n(async function main() {\n  try {\n    const url = core.getInput('api-url')\n    const api = new GhostAdminApi({\n      url,\n      key: core.getInput('api-key'),\n      version: 'canary'\n    })\n\n    const basePath = process.env.GITHUB_WORKSPACE\n    const pkgPath = path.join(process.env.GITHUB_WORKSPACE, 'package.json')\n\n    let zipPath = core.getInput('file')\n\n    \u002F\u002F Zip file was not provided - zip everything up!\n    if (!zipPath) {\n      const themeName = core.getInput('theme-name') || require(pkgPath).name\n      const themeZip = `${themeName}.zip`\n      const exclude = core.getInput('exclude') || ''\n      zipPath = themeZip\n\n      \u002F\u002F Create a zip\n      await exec.exec(`zip -r ${themeZip} ${core.getInput('working-directory') || '.'} -x *.git* *.zip yarn* npm* node_modules* *routes.yaml *redirects.yaml *redirects.json ${exclude}`, [], { cwd: basePath })\n    }\n\n    zipPath = path.join(basePath, zipPath)\n\n    \u002F\u002F Deploy it to the configured site\n    await api.themes.upload({ file: zipPath })\n    console.log(`${zipPath} successfully uploaded.`)\n  }\n  catch (err) {\n    console.error(err)\n    process.exit(1)\n  }\n}())\n","javascript",[39,301,302,335,357,379,405,409,428,436,465,484,492,518,534,541,545,568,611,616,644,649,656,676,721,746,778,789,794,800,892,898,903,928,933,939,973,999,1005,1020,1036,1054,1059],{"__ignoreMap":37},[42,303,304,308,312,316,320,323,327,330,332],{"class":44,"line":45},[42,305,307],{"class":306},"sbsja","const",[42,309,311],{"class":310},"s_hVV"," path",[42,313,315],{"class":314},"smGrS"," =",[42,317,319],{"class":318},"sGLFI"," require",[42,321,322],{"class":52},"(",[42,324,326],{"class":325},"sjJ54","'",[42,328,329],{"class":48},"node:path",[42,331,326],{"class":325},[42,333,334],{"class":52},")\n",[42,336,337,339,342,344,346,348,350,353,355],{"class":44,"line":81},[42,338,307],{"class":306},[42,340,341],{"class":310}," core",[42,343,315],{"class":314},[42,345,319],{"class":318},[42,347,322],{"class":52},[42,349,326],{"class":325},[42,351,352],{"class":48},"@actions\u002Fcore",[42,354,326],{"class":325},[42,356,334],{"class":52},[42,358,359,361,364,366,368,370,372,375,377],{"class":44,"line":105},[42,360,307],{"class":306},[42,362,363],{"class":310}," exec",[42,365,315],{"class":314},[42,367,319],{"class":318},[42,369,322],{"class":52},[42,371,326],{"class":325},[42,373,374],{"class":48},"@actions\u002Fexec",[42,376,326],{"class":325},[42,378,334],{"class":52},[42,380,381,383,386,388,390,392,394,397,399,402],{"class":44,"line":112},[42,382,307],{"class":306},[42,384,385],{"class":310}," GhostAdminApi",[42,387,315],{"class":314},[42,389,319],{"class":318},[42,391,322],{"class":52},[42,393,326],{"class":325},[42,395,396],{"class":48},"@tryghost\u002Fadmin-api",[42,398,326],{"class":325},[42,400,401],{"class":52},")",[42,403,404],{"class":226},";\n",[42,406,407],{"class":44,"line":118},[42,408,109],{"emptyLinePlaceholder":108},[42,410,411,413,416,419,422,425],{"class":44,"line":123},[42,412,322],{"class":52},[42,414,415],{"class":306},"async",[42,417,418],{"class":306}," function",[42,420,421],{"class":318}," main",[42,423,424],{"class":226},"()",[42,426,427],{"class":226}," {\n",[42,429,430,434],{"class":44,"line":132},[42,431,433],{"class":432},"sVHd0","  try",[42,435,427],{"class":226},[42,437,438,441,444,446,448,450,453,456,458,461,463],{"class":44,"line":138},[42,439,440],{"class":306},"    const",[42,442,443],{"class":310}," url",[42,445,315],{"class":314},[42,447,341],{"class":52},[42,449,60],{"class":226},[42,451,452],{"class":318},"getInput",[42,454,322],{"class":455},"skxfh",[42,457,326],{"class":325},[42,459,460],{"class":48},"api-url",[42,462,326],{"class":325},[42,464,334],{"class":455},[42,466,467,469,472,474,477,479,481],{"class":44,"line":143},[42,468,440],{"class":306},[42,470,471],{"class":310}," api",[42,473,315],{"class":314},[42,475,476],{"class":314}," new",[42,478,385],{"class":318},[42,480,322],{"class":455},[42,482,483],{"class":226},"{\n",[42,485,486,489],{"class":44,"line":151},[42,487,488],{"class":52},"      url",[42,490,491],{"class":226},",\n",[42,493,494,497,499,501,503,505,507,509,512,514,516],{"class":44,"line":157},[42,495,496],{"class":455},"      key",[42,498,75],{"class":226},[42,500,341],{"class":52},[42,502,60],{"class":226},[42,504,452],{"class":318},[42,506,322],{"class":455},[42,508,326],{"class":325},[42,510,511],{"class":48},"api-key",[42,513,326],{"class":325},[42,515,401],{"class":455},[42,517,491],{"class":226},[42,519,520,523,525,528,531],{"class":44,"line":162},[42,521,522],{"class":455},"      version",[42,524,75],{"class":226},[42,526,527],{"class":325}," '",[42,529,530],{"class":48},"canary",[42,532,533],{"class":325},"'\n",[42,535,536,539],{"class":44,"line":188},[42,537,538],{"class":226},"    }",[42,540,334],{"class":455},[42,542,543],{"class":44,"line":194},[42,544,109],{"emptyLinePlaceholder":108},[42,546,548,550,553,555,558,560,563,565],{"class":44,"line":547},15,[42,549,440],{"class":306},[42,551,552],{"class":310}," basePath",[42,554,315],{"class":314},[42,556,557],{"class":52}," process",[42,559,60],{"class":226},[42,561,562],{"class":52},"env",[42,564,60],{"class":226},[42,566,567],{"class":310},"GITHUB_WORKSPACE\n",[42,569,571,573,576,578,580,582,585,587,590,592,594,596,599,602,604,607,609],{"class":44,"line":570},16,[42,572,440],{"class":306},[42,574,575],{"class":310}," pkgPath",[42,577,315],{"class":314},[42,579,311],{"class":52},[42,581,60],{"class":226},[42,583,584],{"class":318},"join",[42,586,322],{"class":455},[42,588,589],{"class":52},"process",[42,591,60],{"class":226},[42,593,562],{"class":52},[42,595,60],{"class":226},[42,597,598],{"class":310},"GITHUB_WORKSPACE",[42,600,601],{"class":226},",",[42,603,527],{"class":325},[42,605,606],{"class":48},"package.json",[42,608,326],{"class":325},[42,610,334],{"class":455},[42,612,614],{"class":44,"line":613},17,[42,615,109],{"emptyLinePlaceholder":108},[42,617,619,622,625,627,629,631,633,635,637,640,642],{"class":44,"line":618},18,[42,620,621],{"class":306},"    let",[42,623,624],{"class":52}," zipPath",[42,626,315],{"class":314},[42,628,341],{"class":52},[42,630,60],{"class":226},[42,632,452],{"class":318},[42,634,322],{"class":455},[42,636,326],{"class":325},[42,638,639],{"class":48},"file",[42,641,326],{"class":325},[42,643,334],{"class":455},[42,645,647],{"class":44,"line":646},19,[42,648,109],{"emptyLinePlaceholder":108},[42,650,652],{"class":44,"line":651},20,[42,653,655],{"class":654},"sutJx","    \u002F\u002F Zip file was not provided - zip everything up!\n",[42,657,659,662,665,668,671,674],{"class":44,"line":658},21,[42,660,661],{"class":432},"    if",[42,663,664],{"class":455}," (",[42,666,667],{"class":314},"!",[42,669,670],{"class":52},"zipPath",[42,672,673],{"class":455},") ",[42,675,483],{"class":226},[42,677,679,682,685,687,689,691,693,695,697,700,702,704,707,709,711,714,716,718],{"class":44,"line":678},22,[42,680,681],{"class":306},"      const",[42,683,684],{"class":310}," themeName",[42,686,315],{"class":314},[42,688,341],{"class":52},[42,690,60],{"class":226},[42,692,452],{"class":318},[42,694,322],{"class":455},[42,696,326],{"class":325},[42,698,699],{"class":48},"theme-name",[42,701,326],{"class":325},[42,703,673],{"class":455},[42,705,706],{"class":314},"||",[42,708,319],{"class":318},[42,710,322],{"class":455},[42,712,713],{"class":52},"pkgPath",[42,715,401],{"class":455},[42,717,60],{"class":226},[42,719,720],{"class":52},"name\n",[42,722,724,726,729,731,734,737,740,743],{"class":44,"line":723},23,[42,725,681],{"class":306},[42,727,728],{"class":310}," themeZip",[42,730,315],{"class":314},[42,732,733],{"class":325}," `${",[42,735,736],{"class":52},"themeName",[42,738,739],{"class":325},"}",[42,741,742],{"class":48},".zip",[42,744,745],{"class":325},"`\n",[42,747,749,751,754,756,758,760,762,764,766,769,771,773,775],{"class":44,"line":748},24,[42,750,681],{"class":306},[42,752,753],{"class":310}," exclude",[42,755,315],{"class":314},[42,757,341],{"class":52},[42,759,60],{"class":226},[42,761,452],{"class":318},[42,763,322],{"class":455},[42,765,326],{"class":325},[42,767,768],{"class":48},"exclude",[42,770,326],{"class":325},[42,772,673],{"class":455},[42,774,706],{"class":314},[42,776,777],{"class":325}," ''\n",[42,779,781,784,786],{"class":44,"line":780},25,[42,782,783],{"class":52},"      zipPath",[42,785,315],{"class":314},[42,787,788],{"class":52}," themeZip\n",[42,790,792],{"class":44,"line":791},26,[42,793,109],{"emptyLinePlaceholder":108},[42,795,797],{"class":44,"line":796},27,[42,798,799],{"class":654},"      \u002F\u002F Create a zip\n",[42,801,803,806,808,810,813,815,818,821,824,827,829,832,835,837,839,842,844,847,849,851,853,855,857,860,863,865,867,870,872,875,877,880,883,885,887,890],{"class":44,"line":802},28,[42,804,805],{"class":432},"      await",[42,807,363],{"class":52},[42,809,60],{"class":226},[42,811,812],{"class":318},"exec",[42,814,322],{"class":455},[42,816,817],{"class":325},"`",[42,819,820],{"class":48},"zip -r ",[42,822,823],{"class":325},"${",[42,825,826],{"class":52},"themeZip",[42,828,739],{"class":325},[42,830,831],{"class":325}," ${",[42,833,834],{"class":52},"core",[42,836,60],{"class":325},[42,838,452],{"class":318},[42,840,322],{"class":841},"sfo-9",[42,843,326],{"class":325},[42,845,846],{"class":48},"working-directory",[42,848,326],{"class":325},[42,850,673],{"class":841},[42,852,706],{"class":314},[42,854,527],{"class":325},[42,856,60],{"class":48},[42,858,859],{"class":325},"'}",[42,861,862],{"class":48}," -x *.git* *.zip yarn* npm* node_modules* *routes.yaml *redirects.yaml *redirects.json ",[42,864,823],{"class":325},[42,866,768],{"class":52},[42,868,869],{"class":325},"}`",[42,871,601],{"class":226},[42,873,874],{"class":455}," []",[42,876,601],{"class":226},[42,878,879],{"class":226}," {",[42,881,882],{"class":455}," cwd",[42,884,75],{"class":226},[42,886,552],{"class":52},[42,888,889],{"class":226}," }",[42,891,334],{"class":455},[42,893,895],{"class":44,"line":894},29,[42,896,897],{"class":226},"    }\n",[42,899,901],{"class":44,"line":900},30,[42,902,109],{"emptyLinePlaceholder":108},[42,904,906,909,911,913,915,917,919,922,924,926],{"class":44,"line":905},31,[42,907,908],{"class":52},"    zipPath",[42,910,315],{"class":314},[42,912,311],{"class":52},[42,914,60],{"class":226},[42,916,584],{"class":318},[42,918,322],{"class":455},[42,920,921],{"class":52},"basePath",[42,923,601],{"class":226},[42,925,624],{"class":52},[42,927,334],{"class":455},[42,929,931],{"class":44,"line":930},32,[42,932,109],{"emptyLinePlaceholder":108},[42,934,936],{"class":44,"line":935},33,[42,937,938],{"class":654},"    \u002F\u002F Deploy it to the configured site\n",[42,940,942,945,947,949,952,954,957,959,962,965,967,969,971],{"class":44,"line":941},34,[42,943,944],{"class":432},"    await",[42,946,471],{"class":52},[42,948,60],{"class":226},[42,950,951],{"class":52},"themes",[42,953,60],{"class":226},[42,955,956],{"class":318},"upload",[42,958,322],{"class":455},[42,960,961],{"class":226},"{",[42,963,964],{"class":455}," file",[42,966,75],{"class":226},[42,968,624],{"class":52},[42,970,889],{"class":226},[42,972,334],{"class":455},[42,974,976,979,981,983,985,988,990,992,995,997],{"class":44,"line":975},35,[42,977,978],{"class":52},"    console",[42,980,60],{"class":226},[42,982,36],{"class":318},[42,984,322],{"class":455},[42,986,987],{"class":325},"`${",[42,989,670],{"class":52},[42,991,739],{"class":325},[42,993,994],{"class":48}," successfully uploaded.",[42,996,817],{"class":325},[42,998,334],{"class":455},[42,1000,1002],{"class":44,"line":1001},36,[42,1003,1004],{"class":226},"  }\n",[42,1006,1008,1011,1013,1016,1018],{"class":44,"line":1007},37,[42,1009,1010],{"class":432},"  catch",[42,1012,664],{"class":455},[42,1014,1015],{"class":52},"err",[42,1017,673],{"class":455},[42,1019,483],{"class":226},[42,1021,1023,1025,1027,1030,1032,1034],{"class":44,"line":1022},38,[42,1024,978],{"class":52},[42,1026,60],{"class":226},[42,1028,1029],{"class":318},"error",[42,1031,322],{"class":455},[42,1033,1015],{"class":52},[42,1035,334],{"class":455},[42,1037,1039,1042,1044,1047,1049,1052],{"class":44,"line":1038},39,[42,1040,1041],{"class":52},"    process",[42,1043,60],{"class":226},[42,1045,1046],{"class":318},"exit",[42,1048,322],{"class":455},[42,1050,72],{"class":1051},"srdBf",[42,1053,334],{"class":455},[42,1055,1057],{"class":44,"line":1056},40,[42,1058,1004],{"class":226},[42,1060,1062,1064],{"class":44,"line":1061},41,[42,1063,739],{"class":226},[42,1065,1066],{"class":52},"())\n",[28,1068,1069,1070,1073,1074,1077],{},"把主题打包成 zip 包，然后提供 Ghost 上创建的 ",[39,1071,1072],{},"Admin API Key"," 和 ",[39,1075,1076],{},"API URL","，通过 API 去上传，那么我们应该也可以自己去实现。",[28,1079,1080,1081,1073,1084,1086],{},"首先，我们也需要去 Ghost 后台创建一个自定义的 Integration，比如取名叫 GitLab CI，目的是为了获得 ",[39,1082,1083],{},"Admin API key",[39,1085,1076],{},"，后面在 GitLab CI 中需要用到。",[1088,1089],"post-image",{"filename":1090},"01.png",[28,1092,1093,1094,1073,1097,1100],{},"下一步，去 GitLab CI 中，把这两个内容配置成变量，取名 ",[39,1095,1096],{},"GHOST_ADMIN_API_KEY",[39,1098,1099],{},"GHOST_API_URL"," 以便在 CI 脚本中使用。",[1088,1102],{"filename":1103},"02.png",[28,1105,1106],{},"在项目中添加 Ghost Admin API 库：",[32,1108,1112],{"className":1109,"code":1110,"language":1111,"meta":37,"style":37},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","yarn add @tryghost\u002Fadmin-api --dev\n","bash",[39,1113,1114],{"__ignoreMap":37},[42,1115,1116,1120,1123,1126],{"class":44,"line":45},[42,1117,1119],{"class":1118},"sbgvK","yarn",[42,1121,1122],{"class":48}," add",[42,1124,1125],{"class":48}," @tryghost\u002Fadmin-api",[42,1127,1129],{"class":1128},"stzsN"," --dev\n",[28,1131,1132,1133,1136],{},"在 ",[39,1134,1135],{},"gulpfile.js"," 中插入部署的任务：",[32,1138,1140],{"className":297,"code":1139,"language":299,"meta":37,"style":37},"const GhostAdminApi = require('@tryghost\u002Fadmin-api')\nconst { series, src, dest } = require('gulp')\nconst less = require('gulp-less')\nconst zip = require('gulp-zip')\nconst pump = require('pump')\n\nconst handleError = (done) => {\n  return function (err) {\n    if (err) {\n      console.error(err)\n    }\n    return done(err)\n  }\n}\n\nfunction css(done) {\n  pump(\n    [\n      src('.\u002Fassets\u002Fcss\u002F*.less', { sourcemaps: true }),\n      less({}),\n      dest('assets\u002Fcss', { sourcemaps: '.\u002F' }),\n    ],\n    handleError(done)\n  )\n}\n\nfunction zipper(done) {\n  const targetDir = 'dist\u002F'\n  const themeName = require('.\u002Fpackage.json').name\n  const filename = `${themeName}.zip`\n\n  pump(\n    [\n      src(['**', '!node_modules', '!node_modules\u002F**', '!dist', '!dist\u002F**']),\n      zip(filename),\n      dest(targetDir),\n    ],\n    handleError(done)\n  )\n}\n\nasync function deploy(done) {\n  try {\n    const zipFile = `dist\u002F${require('.\u002Fpackage.json').name}.zip`\n    const api = new GhostAdminApi({\n      url: process.env.GHOST_API_URL,\n      key: process.env.GHOST_ADMIN_API_KEY,\n      version: `v${require('.\u002Fpackage.json').version}`,\n    })\n\n    await api.themes.upload({ file: zipFile })\n    console.log(`${zipFile} successfully uploaded.`)\n    done()\n  }\n  catch (err) {\n    console.error(err)\n    done(err)\n  }\n}\n\nconst build = series(css)\n\nexports.build = build\nexports.zip = series(build, zipper)\nexports.deploy = deploy\nexports.default = build\n",[39,1141,1142,1162,1198,1220,1242,1264,1268,1291,1306,1318,1333,1337,1351,1355,1360,1364,1380,1388,1393,1426,1440,1475,1482,1493,1498,1502,1506,1521,1538,1563,1582,1586,1592,1596,1651,1665,1678,1684,1694,1698,1702,1706,1724,1731,1772,1789,1808,1827,1862,1869,1874,1903,1927,1936,1941,1954,1969,1980,1985,1990,1995,2010,2015,2032,2054,2069],{"__ignoreMap":37},[42,1143,1144,1146,1148,1150,1152,1154,1156,1158,1160],{"class":44,"line":45},[42,1145,307],{"class":306},[42,1147,385],{"class":310},[42,1149,315],{"class":314},[42,1151,319],{"class":318},[42,1153,322],{"class":52},[42,1155,326],{"class":325},[42,1157,396],{"class":48},[42,1159,326],{"class":325},[42,1161,334],{"class":52},[42,1163,1164,1166,1168,1171,1173,1176,1178,1181,1183,1185,1187,1189,1191,1194,1196],{"class":44,"line":81},[42,1165,307],{"class":306},[42,1167,879],{"class":226},[42,1169,1170],{"class":310}," series",[42,1172,601],{"class":226},[42,1174,1175],{"class":310}," src",[42,1177,601],{"class":226},[42,1179,1180],{"class":310}," dest",[42,1182,889],{"class":226},[42,1184,315],{"class":314},[42,1186,319],{"class":318},[42,1188,322],{"class":52},[42,1190,326],{"class":325},[42,1192,1193],{"class":48},"gulp",[42,1195,326],{"class":325},[42,1197,334],{"class":52},[42,1199,1200,1202,1205,1207,1209,1211,1213,1216,1218],{"class":44,"line":105},[42,1201,307],{"class":306},[42,1203,1204],{"class":310}," less",[42,1206,315],{"class":314},[42,1208,319],{"class":318},[42,1210,322],{"class":52},[42,1212,326],{"class":325},[42,1214,1215],{"class":48},"gulp-less",[42,1217,326],{"class":325},[42,1219,334],{"class":52},[42,1221,1222,1224,1227,1229,1231,1233,1235,1238,1240],{"class":44,"line":112},[42,1223,307],{"class":306},[42,1225,1226],{"class":310}," zip",[42,1228,315],{"class":314},[42,1230,319],{"class":318},[42,1232,322],{"class":52},[42,1234,326],{"class":325},[42,1236,1237],{"class":48},"gulp-zip",[42,1239,326],{"class":325},[42,1241,334],{"class":52},[42,1243,1244,1246,1249,1251,1253,1255,1257,1260,1262],{"class":44,"line":118},[42,1245,307],{"class":306},[42,1247,1248],{"class":310}," pump",[42,1250,315],{"class":314},[42,1252,319],{"class":318},[42,1254,322],{"class":52},[42,1256,326],{"class":325},[42,1258,1259],{"class":48},"pump",[42,1261,326],{"class":325},[42,1263,334],{"class":52},[42,1265,1266],{"class":44,"line":123},[42,1267,109],{"emptyLinePlaceholder":108},[42,1269,1270,1272,1276,1278,1280,1284,1286,1289],{"class":44,"line":132},[42,1271,307],{"class":306},[42,1273,1275],{"class":1274},"sfCm-"," handleError",[42,1277,315],{"class":314},[42,1279,664],{"class":226},[42,1281,1283],{"class":1282},"s99_P","done",[42,1285,401],{"class":226},[42,1287,1288],{"class":306}," =>",[42,1290,427],{"class":226},[42,1292,1293,1296,1298,1300,1302,1304],{"class":44,"line":138},[42,1294,1295],{"class":432},"  return",[42,1297,418],{"class":306},[42,1299,664],{"class":226},[42,1301,1015],{"class":1282},[42,1303,401],{"class":226},[42,1305,427],{"class":226},[42,1307,1308,1310,1312,1314,1316],{"class":44,"line":143},[42,1309,661],{"class":432},[42,1311,664],{"class":455},[42,1313,1015],{"class":52},[42,1315,673],{"class":455},[42,1317,483],{"class":226},[42,1319,1320,1323,1325,1327,1329,1331],{"class":44,"line":151},[42,1321,1322],{"class":52},"      console",[42,1324,60],{"class":226},[42,1326,1029],{"class":318},[42,1328,322],{"class":455},[42,1330,1015],{"class":52},[42,1332,334],{"class":455},[42,1334,1335],{"class":44,"line":157},[42,1336,897],{"class":226},[42,1338,1339,1342,1345,1347,1349],{"class":44,"line":162},[42,1340,1341],{"class":432},"    return",[42,1343,1344],{"class":318}," done",[42,1346,322],{"class":455},[42,1348,1015],{"class":52},[42,1350,334],{"class":455},[42,1352,1353],{"class":44,"line":188},[42,1354,1004],{"class":226},[42,1356,1357],{"class":44,"line":194},[42,1358,1359],{"class":226},"}\n",[42,1361,1362],{"class":44,"line":547},[42,1363,109],{"emptyLinePlaceholder":108},[42,1365,1366,1369,1372,1374,1376,1378],{"class":44,"line":570},[42,1367,1368],{"class":306},"function",[42,1370,1371],{"class":318}," css",[42,1373,322],{"class":226},[42,1375,1283],{"class":1282},[42,1377,401],{"class":226},[42,1379,427],{"class":226},[42,1381,1382,1385],{"class":44,"line":613},[42,1383,1384],{"class":318},"  pump",[42,1386,1387],{"class":455},"(\n",[42,1389,1390],{"class":44,"line":618},[42,1391,1392],{"class":455},"    [\n",[42,1394,1395,1398,1400,1402,1405,1407,1409,1411,1414,1416,1420,1422,1424],{"class":44,"line":646},[42,1396,1397],{"class":318},"      src",[42,1399,322],{"class":455},[42,1401,326],{"class":325},[42,1403,1404],{"class":48},".\u002Fassets\u002Fcss\u002F*.less",[42,1406,326],{"class":325},[42,1408,601],{"class":226},[42,1410,879],{"class":226},[42,1412,1413],{"class":455}," sourcemaps",[42,1415,75],{"class":226},[42,1417,1419],{"class":1418},"syTEX"," true",[42,1421,889],{"class":226},[42,1423,401],{"class":455},[42,1425,491],{"class":226},[42,1427,1428,1431,1433,1436,1438],{"class":44,"line":651},[42,1429,1430],{"class":318},"      less",[42,1432,322],{"class":455},[42,1434,1435],{"class":226},"{}",[42,1437,401],{"class":455},[42,1439,491],{"class":226},[42,1441,1442,1445,1447,1449,1452,1454,1456,1458,1460,1462,1464,1467,1469,1471,1473],{"class":44,"line":658},[42,1443,1444],{"class":318},"      dest",[42,1446,322],{"class":455},[42,1448,326],{"class":325},[42,1450,1451],{"class":48},"assets\u002Fcss",[42,1453,326],{"class":325},[42,1455,601],{"class":226},[42,1457,879],{"class":226},[42,1459,1413],{"class":455},[42,1461,75],{"class":226},[42,1463,527],{"class":325},[42,1465,1466],{"class":48},".\u002F",[42,1468,326],{"class":325},[42,1470,889],{"class":226},[42,1472,401],{"class":455},[42,1474,491],{"class":226},[42,1476,1477,1480],{"class":44,"line":678},[42,1478,1479],{"class":455},"    ]",[42,1481,491],{"class":226},[42,1483,1484,1487,1489,1491],{"class":44,"line":723},[42,1485,1486],{"class":318},"    handleError",[42,1488,322],{"class":455},[42,1490,1283],{"class":52},[42,1492,334],{"class":455},[42,1494,1495],{"class":44,"line":748},[42,1496,1497],{"class":455},"  )\n",[42,1499,1500],{"class":44,"line":780},[42,1501,1359],{"class":226},[42,1503,1504],{"class":44,"line":791},[42,1505,109],{"emptyLinePlaceholder":108},[42,1507,1508,1510,1513,1515,1517,1519],{"class":44,"line":796},[42,1509,1368],{"class":306},[42,1511,1512],{"class":318}," zipper",[42,1514,322],{"class":226},[42,1516,1283],{"class":1282},[42,1518,401],{"class":226},[42,1520,427],{"class":226},[42,1522,1523,1526,1529,1531,1533,1536],{"class":44,"line":802},[42,1524,1525],{"class":306},"  const",[42,1527,1528],{"class":310}," targetDir",[42,1530,315],{"class":314},[42,1532,527],{"class":325},[42,1534,1535],{"class":48},"dist\u002F",[42,1537,533],{"class":325},[42,1539,1540,1542,1544,1546,1548,1550,1552,1555,1557,1559,1561],{"class":44,"line":894},[42,1541,1525],{"class":306},[42,1543,684],{"class":310},[42,1545,315],{"class":314},[42,1547,319],{"class":318},[42,1549,322],{"class":455},[42,1551,326],{"class":325},[42,1553,1554],{"class":48},".\u002Fpackage.json",[42,1556,326],{"class":325},[42,1558,401],{"class":455},[42,1560,60],{"class":226},[42,1562,720],{"class":52},[42,1564,1565,1567,1570,1572,1574,1576,1578,1580],{"class":44,"line":900},[42,1566,1525],{"class":306},[42,1568,1569],{"class":310}," filename",[42,1571,315],{"class":314},[42,1573,733],{"class":325},[42,1575,736],{"class":52},[42,1577,739],{"class":325},[42,1579,742],{"class":48},[42,1581,745],{"class":325},[42,1583,1584],{"class":44,"line":905},[42,1585,109],{"emptyLinePlaceholder":108},[42,1587,1588,1590],{"class":44,"line":930},[42,1589,1384],{"class":318},[42,1591,1387],{"class":455},[42,1593,1594],{"class":44,"line":935},[42,1595,1392],{"class":455},[42,1597,1598,1600,1603,1605,1608,1610,1612,1614,1617,1619,1621,1623,1626,1628,1630,1632,1635,1637,1639,1641,1644,1646,1649],{"class":44,"line":941},[42,1599,1397],{"class":318},[42,1601,1602],{"class":455},"([",[42,1604,326],{"class":325},[42,1606,1607],{"class":48},"**",[42,1609,326],{"class":325},[42,1611,601],{"class":226},[42,1613,527],{"class":325},[42,1615,1616],{"class":48},"!node_modules",[42,1618,326],{"class":325},[42,1620,601],{"class":226},[42,1622,527],{"class":325},[42,1624,1625],{"class":48},"!node_modules\u002F**",[42,1627,326],{"class":325},[42,1629,601],{"class":226},[42,1631,527],{"class":325},[42,1633,1634],{"class":48},"!dist",[42,1636,326],{"class":325},[42,1638,601],{"class":226},[42,1640,527],{"class":325},[42,1642,1643],{"class":48},"!dist\u002F**",[42,1645,326],{"class":325},[42,1647,1648],{"class":455},"])",[42,1650,491],{"class":226},[42,1652,1653,1656,1658,1661,1663],{"class":44,"line":975},[42,1654,1655],{"class":318},"      zip",[42,1657,322],{"class":455},[42,1659,1660],{"class":52},"filename",[42,1662,401],{"class":455},[42,1664,491],{"class":226},[42,1666,1667,1669,1671,1674,1676],{"class":44,"line":1001},[42,1668,1444],{"class":318},[42,1670,322],{"class":455},[42,1672,1673],{"class":52},"targetDir",[42,1675,401],{"class":455},[42,1677,491],{"class":226},[42,1679,1680,1682],{"class":44,"line":1007},[42,1681,1479],{"class":455},[42,1683,491],{"class":226},[42,1685,1686,1688,1690,1692],{"class":44,"line":1022},[42,1687,1486],{"class":318},[42,1689,322],{"class":455},[42,1691,1283],{"class":52},[42,1693,334],{"class":455},[42,1695,1696],{"class":44,"line":1038},[42,1697,1497],{"class":455},[42,1699,1700],{"class":44,"line":1056},[42,1701,1359],{"class":226},[42,1703,1704],{"class":44,"line":1061},[42,1705,109],{"emptyLinePlaceholder":108},[42,1707,1709,1711,1713,1716,1718,1720,1722],{"class":44,"line":1708},42,[42,1710,415],{"class":306},[42,1712,418],{"class":306},[42,1714,1715],{"class":318}," deploy",[42,1717,322],{"class":226},[42,1719,1283],{"class":1282},[42,1721,401],{"class":226},[42,1723,427],{"class":226},[42,1725,1727,1729],{"class":44,"line":1726},43,[42,1728,433],{"class":432},[42,1730,427],{"class":226},[42,1732,1734,1736,1739,1741,1744,1746,1748,1751,1753,1755,1757,1759,1761,1763,1766,1768,1770],{"class":44,"line":1733},44,[42,1735,440],{"class":306},[42,1737,1738],{"class":310}," zipFile",[42,1740,315],{"class":314},[42,1742,1743],{"class":325}," `",[42,1745,1535],{"class":48},[42,1747,823],{"class":325},[42,1749,1750],{"class":318},"require",[42,1752,322],{"class":841},[42,1754,326],{"class":325},[42,1756,1554],{"class":48},[42,1758,326],{"class":325},[42,1760,401],{"class":841},[42,1762,60],{"class":325},[42,1764,1765],{"class":52},"name",[42,1767,739],{"class":325},[42,1769,742],{"class":48},[42,1771,745],{"class":325},[42,1773,1775,1777,1779,1781,1783,1785,1787],{"class":44,"line":1774},45,[42,1776,440],{"class":306},[42,1778,471],{"class":310},[42,1780,315],{"class":314},[42,1782,476],{"class":314},[42,1784,385],{"class":318},[42,1786,322],{"class":455},[42,1788,483],{"class":226},[42,1790,1792,1794,1796,1798,1800,1802,1804,1806],{"class":44,"line":1791},46,[42,1793,488],{"class":455},[42,1795,75],{"class":226},[42,1797,557],{"class":52},[42,1799,60],{"class":226},[42,1801,562],{"class":52},[42,1803,60],{"class":226},[42,1805,1099],{"class":310},[42,1807,491],{"class":226},[42,1809,1811,1813,1815,1817,1819,1821,1823,1825],{"class":44,"line":1810},47,[42,1812,496],{"class":455},[42,1814,75],{"class":226},[42,1816,557],{"class":52},[42,1818,60],{"class":226},[42,1820,562],{"class":52},[42,1822,60],{"class":226},[42,1824,1096],{"class":310},[42,1826,491],{"class":226},[42,1828,1830,1832,1834,1836,1839,1841,1843,1845,1847,1849,1851,1853,1855,1858,1860],{"class":44,"line":1829},48,[42,1831,522],{"class":455},[42,1833,75],{"class":226},[42,1835,1743],{"class":325},[42,1837,1838],{"class":48},"v",[42,1840,823],{"class":325},[42,1842,1750],{"class":318},[42,1844,322],{"class":841},[42,1846,326],{"class":325},[42,1848,1554],{"class":48},[42,1850,326],{"class":325},[42,1852,401],{"class":841},[42,1854,60],{"class":325},[42,1856,1857],{"class":52},"version",[42,1859,869],{"class":325},[42,1861,491],{"class":226},[42,1863,1865,1867],{"class":44,"line":1864},49,[42,1866,538],{"class":226},[42,1868,334],{"class":455},[42,1870,1872],{"class":44,"line":1871},50,[42,1873,109],{"emptyLinePlaceholder":108},[42,1875,1877,1879,1881,1883,1885,1887,1889,1891,1893,1895,1897,1899,1901],{"class":44,"line":1876},51,[42,1878,944],{"class":432},[42,1880,471],{"class":52},[42,1882,60],{"class":226},[42,1884,951],{"class":52},[42,1886,60],{"class":226},[42,1888,956],{"class":318},[42,1890,322],{"class":455},[42,1892,961],{"class":226},[42,1894,964],{"class":455},[42,1896,75],{"class":226},[42,1898,1738],{"class":52},[42,1900,889],{"class":226},[42,1902,334],{"class":455},[42,1904,1906,1908,1910,1912,1914,1916,1919,1921,1923,1925],{"class":44,"line":1905},52,[42,1907,978],{"class":52},[42,1909,60],{"class":226},[42,1911,36],{"class":318},[42,1913,322],{"class":455},[42,1915,987],{"class":325},[42,1917,1918],{"class":52},"zipFile",[42,1920,739],{"class":325},[42,1922,994],{"class":48},[42,1924,817],{"class":325},[42,1926,334],{"class":455},[42,1928,1930,1933],{"class":44,"line":1929},53,[42,1931,1932],{"class":318},"    done",[42,1934,1935],{"class":455},"()\n",[42,1937,1939],{"class":44,"line":1938},54,[42,1940,1004],{"class":226},[42,1942,1944,1946,1948,1950,1952],{"class":44,"line":1943},55,[42,1945,1010],{"class":432},[42,1947,664],{"class":455},[42,1949,1015],{"class":52},[42,1951,673],{"class":455},[42,1953,483],{"class":226},[42,1955,1957,1959,1961,1963,1965,1967],{"class":44,"line":1956},56,[42,1958,978],{"class":52},[42,1960,60],{"class":226},[42,1962,1029],{"class":318},[42,1964,322],{"class":455},[42,1966,1015],{"class":52},[42,1968,334],{"class":455},[42,1970,1972,1974,1976,1978],{"class":44,"line":1971},57,[42,1973,1932],{"class":318},[42,1975,322],{"class":455},[42,1977,1015],{"class":52},[42,1979,334],{"class":455},[42,1981,1983],{"class":44,"line":1982},58,[42,1984,1004],{"class":226},[42,1986,1988],{"class":44,"line":1987},59,[42,1989,1359],{"class":226},[42,1991,1993],{"class":44,"line":1992},60,[42,1994,109],{"emptyLinePlaceholder":108},[42,1996,1998,2000,2003,2005,2007],{"class":44,"line":1997},61,[42,1999,307],{"class":306},[42,2001,2002],{"class":310}," build",[42,2004,315],{"class":314},[42,2006,1170],{"class":318},[42,2008,2009],{"class":52},"(css)\n",[42,2011,2013],{"class":44,"line":2012},62,[42,2014,109],{"emptyLinePlaceholder":108},[42,2016,2018,2021,2023,2026,2029],{"class":44,"line":2017},63,[42,2019,2020],{"class":56},"exports",[42,2022,60],{"class":226},[42,2024,2025],{"class":52},"build ",[42,2027,2028],{"class":314},"=",[42,2030,2031],{"class":52}," build\n",[42,2033,2035,2037,2039,2042,2044,2046,2049,2051],{"class":44,"line":2034},64,[42,2036,2020],{"class":56},[42,2038,60],{"class":226},[42,2040,2041],{"class":52},"zip ",[42,2043,2028],{"class":314},[42,2045,1170],{"class":318},[42,2047,2048],{"class":52},"(build",[42,2050,601],{"class":226},[42,2052,2053],{"class":52}," zipper)\n",[42,2055,2057,2059,2061,2064,2066],{"class":44,"line":2056},65,[42,2058,2020],{"class":56},[42,2060,60],{"class":226},[42,2062,2063],{"class":52},"deploy ",[42,2065,2028],{"class":314},[42,2067,2068],{"class":52}," deploy\n",[42,2070,2072,2074,2076,2079,2081],{"class":44,"line":2071},66,[42,2073,2020],{"class":56},[42,2075,60],{"class":226},[42,2077,2078],{"class":52},"default ",[42,2080,2028],{"class":314},[42,2082,2031],{"class":52},[28,2084,1132,2085,2087],{},[39,2086,606],{}," 中插入脚本：",[32,2089,2093],{"className":2090,"code":2091,"language":2092,"meta":37,"style":37},"language-json shiki shiki-themes material-theme-lighter github-light github-dark","{\n  \u002F* ... *\u002F\n  \"scripts\": {\n    \"build\": \"gulp build\",\n    \"zip\": \"gulp zip\",\n    \"deploy\": \"gulp deploy\"\n  }\n  \u002F* ... *\u002F\n}\n","json",[39,2094,2095,2099,2104,2120,2143,2163,2182,2186,2190],{"__ignoreMap":37},[42,2096,2097],{"class":44,"line":45},[42,2098,483],{"class":226},[42,2100,2101],{"class":44,"line":81},[42,2102,2103],{"class":654},"  \u002F* ... *\u002F\n",[42,2105,2106,2109,2113,2116,2118],{"class":44,"line":105},[42,2107,2108],{"class":56},"  \"",[42,2110,2112],{"class":2111},"sseR_","scripts",[42,2114,2115],{"class":56},"\"",[42,2117,75],{"class":226},[42,2119,427],{"class":226},[42,2121,2122,2125,2129,2131,2133,2136,2139,2141],{"class":44,"line":112},[42,2123,2124],{"class":56},"    \"",[42,2126,2128],{"class":2127},"sZMiF","build",[42,2130,2115],{"class":56},[42,2132,75],{"class":226},[42,2134,2135],{"class":325}," \"",[42,2137,2138],{"class":48},"gulp build",[42,2140,2115],{"class":325},[42,2142,491],{"class":226},[42,2144,2145,2147,2150,2152,2154,2156,2159,2161],{"class":44,"line":118},[42,2146,2124],{"class":56},[42,2148,2149],{"class":2127},"zip",[42,2151,2115],{"class":56},[42,2153,75],{"class":226},[42,2155,2135],{"class":325},[42,2157,2158],{"class":48},"gulp zip",[42,2160,2115],{"class":325},[42,2162,491],{"class":226},[42,2164,2165,2167,2170,2172,2174,2176,2179],{"class":44,"line":123},[42,2166,2124],{"class":56},[42,2168,2169],{"class":2127},"deploy",[42,2171,2115],{"class":56},[42,2173,75],{"class":226},[42,2175,2135],{"class":325},[42,2177,2178],{"class":48},"gulp deploy",[42,2180,2181],{"class":325},"\"\n",[42,2183,2184],{"class":44,"line":132},[42,2185,1004],{"class":226},[42,2187,2188],{"class":44,"line":138},[42,2189,2103],{"class":654},[42,2191,2192],{"class":44,"line":143},[42,2193,1359],{"class":226},[28,2195,2196,2197,2200],{},"添加 ",[39,2198,2199],{},".gitlab-ci.yml"," 文件：",[32,2202,2204],{"className":213,"code":2203,"language":215,"meta":37,"style":37},"image: node:14-slim # 注意：不要用 alpine 的镜像，上传至 https 站点会有问题\n\nstages:\n  - deploy\n\ndeploy:\n  stage: deploy\n  script:\n    - yarn install\n    - yarn zip\n    - yarn deploy\n  only:\n    - tags\n  cache:\n    paths:\n      - node_modules\u002F\n",[39,2205,2206,2219,2223,2231,2238,2242,2248,2257,2264,2272,2279,2286,2293,2300,2307,2314],{"__ignoreMap":37},[42,2207,2208,2211,2213,2216],{"class":44,"line":45},[42,2209,2210],{"class":222},"image",[42,2212,75],{"class":226},[42,2214,2215],{"class":48}," node:14-slim",[42,2217,2218],{"class":654}," # 注意：不要用 alpine 的镜像，上传至 https 站点会有问题\n",[42,2220,2221],{"class":44,"line":81},[42,2222,109],{"emptyLinePlaceholder":108},[42,2224,2225,2228],{"class":44,"line":105},[42,2226,2227],{"class":222},"stages",[42,2229,2230],{"class":226},":\n",[42,2232,2233,2236],{"class":44,"line":112},[42,2234,2235],{"class":226},"  -",[42,2237,2068],{"class":48},[42,2239,2240],{"class":44,"line":118},[42,2241,109],{"emptyLinePlaceholder":108},[42,2243,2244,2246],{"class":44,"line":123},[42,2245,2169],{"class":222},[42,2247,2230],{"class":226},[42,2249,2250,2253,2255],{"class":44,"line":132},[42,2251,2252],{"class":222},"  stage",[42,2254,75],{"class":226},[42,2256,2068],{"class":48},[42,2258,2259,2262],{"class":44,"line":138},[42,2260,2261],{"class":222},"  script",[42,2263,2230],{"class":226},[42,2265,2266,2269],{"class":44,"line":143},[42,2267,2268],{"class":226},"    -",[42,2270,2271],{"class":48}," yarn install\n",[42,2273,2274,2276],{"class":44,"line":151},[42,2275,2268],{"class":226},[42,2277,2278],{"class":48}," yarn zip\n",[42,2280,2281,2283],{"class":44,"line":157},[42,2282,2268],{"class":226},[42,2284,2285],{"class":48}," yarn deploy\n",[42,2287,2288,2291],{"class":44,"line":162},[42,2289,2290],{"class":222},"  only",[42,2292,2230],{"class":226},[42,2294,2295,2297],{"class":44,"line":188},[42,2296,2268],{"class":226},[42,2298,2299],{"class":48}," tags\n",[42,2301,2302,2305],{"class":44,"line":194},[42,2303,2304],{"class":222},"  cache",[42,2306,2230],{"class":226},[42,2308,2309,2312],{"class":44,"line":547},[42,2310,2311],{"class":222},"    paths",[42,2313,2230],{"class":226},[42,2315,2316,2319],{"class":44,"line":570},[42,2317,2318],{"class":226},"      -",[42,2320,2321],{"class":48}," node_modules\u002F\n",[28,2323,2324,2325,2327,2328,2331,2332,2335],{},"注意，为了避免每次提交代码都部署，",[39,2326,2169],{}," 任务限制了只有打了 ",[39,2329,2330],{},"tag"," 的 ",[39,2333,2334],{},"commit"," 才会触发。",[28,2337,2338],{},"好了，更新代码，打个 tag 就会自动打包上传至 Ghost 后台了！",[247,2340,2341],{},"html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sfo-9, html code.shiki .sfo-9{--shiki-light:#90A4AE;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sfCm-, html code.shiki .sfCm-{--shiki-light:#90A4AE;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sseR_, html code.shiki .sseR_{--shiki-light:#9C3EDA;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZMiF, html code.shiki .sZMiF{--shiki-light:#E2931D;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":37,"searchDepth":81,"depth":81,"links":2343},[],"2022-05-24",{},"\u002Fposts\u002F2022\u002Fuse-gitlab-to-deploy-ghost-theme-automatically",{"text":2348,"minutes":2349,"time":2350,"words":2351},"4 min read",3.575,214500,715,{"title":274,"description":37},{"loc":2346},"posts\u002F2022\u002F20220524.use-gitlab-to-deploy-ghost-theme-automatically",[268,270,2356,269],"DevOps","2cB9yXMzvXfyQ8XEXx9VDbtCvf4CKC-2FRBZ833gE-Q",{"id":2359,"title":2360,"body":2361,"class":252,"cover":2374,"coverSize":252,"date":2375,"description":2365,"draft":255,"extension":256,"hideComments":255,"location":252,"meta":2376,"navigation":108,"path":2377,"readingTime":2378,"seo":2382,"sitemap":2383,"stem":2384,"tags":2385,"time":252,"weather":252,"__hash__":2387},"posts\u002Fposts\u002F2019\u002F20190306.new-blog-theme.md","折腾了一下博客的新主题",{"type":25,"value":2362,"toc":2372},[2363,2366,2369],[28,2364,2365],{},"心仪这个主题很久了，第一次在 themeforest 上购买主题，感觉还是挺爽的，比自己从零开始做一个要省事多了。😎",[28,2367,2368],{},"自定义了一些样式，有空还需要汉化一下。",[28,2370,2371],{},"睡觉🌛",{"title":37,"searchDepth":81,"depth":81,"links":2373},[],"png","2019-03-06",{},"\u002Fposts\u002F2019\u002Fnew-blog-theme",{"text":2379,"minutes":2380,"time":2381,"words":2012},"1 min read",0.31,18600,{"title":2360,"description":2365},{"loc":2377},"posts\u002F2019\u002F20190306.new-blog-theme",[2386,269,270],"日记","naHPr0OArpbPnxgtqkXp10Fc9qBJ_AR5bEeCiNCxbmQ",{"id":2389,"title":2390,"body":2391,"class":252,"cover":2374,"coverSize":252,"date":2412,"description":2395,"draft":255,"extension":256,"hideComments":255,"location":252,"meta":2413,"navigation":108,"path":2414,"readingTime":2415,"seo":2419,"sitemap":2420,"stem":2421,"tags":2422,"time":252,"weather":2424,"__hash__":2425},"posts\u002Fposts\u002F2019\u002F20190109.ghost-docker-mail-config.md","Ghost Docker 部署方式配置邮箱",{"type":25,"value":2392,"toc":2410},[2393,2396,2399,2407],[28,2394,2395],{},"很久没登录博客了，今天登录时，发现忘记密码了，之前都是自动登录的，估计是自动登录过期了，没办法自动登录了，试了几次，账号被锁定了。",[28,2397,2398],{},"尝试找回密码，发现好像没有配置 SMTP 邮箱。于是找了下配置项，用 Docker 部署的话，在编排模板的 environment 中添加如下配置：",[32,2400,2405],{"className":2401,"code":2403,"language":2404},[2402],"language-text","- 'mail__transport=SMTP'\n- 'mail__from=Ghost \u003Cxx@xxx.com>'\n- 'mail__options__host=smtp.qiye.aliyun.com'\n- 'mail__options__secureConnection=true'\n- 'mail__options__port=465'\n- 'mail__options__auth__user=xx@xxx.com'\n- 'mail__options__auth__pass=YOUR_PASSWORD'\n","text",[39,2406,2403],{"__ignoreMap":37},[28,2408,2409],{},"重新部署一下即可。",{"title":37,"searchDepth":81,"depth":81,"links":2411},[],"2019-01-09",{},"\u002Fposts\u002F2019\u002Fghost-docker-mail-config",{"text":2379,"minutes":2416,"time":2417,"words":2418},0.62,37200,124,{"title":2390,"description":2395},{"loc":2414},"posts\u002F2019\u002F20190109.ghost-docker-mail-config",[268,269,270,2423],"Docker","天气阴","yJjcNS7QIvqk0sWEB0_f7Ds-et57mbeIjVP1lrbEJOE",{"id":2427,"title":2428,"body":2429,"class":252,"cover":2374,"coverSize":252,"date":2545,"description":2433,"draft":255,"extension":256,"hideComments":255,"location":252,"meta":2546,"navigation":108,"path":2547,"readingTime":2548,"seo":2553,"sitemap":2554,"stem":2555,"tags":2556,"time":252,"weather":252,"__hash__":2557},"posts\u002Fposts\u002F2017\u002F20171102.transfer-blog-to-aliyun-docker.md","Ghost 博客迁移至阿里云 Docker",{"type":25,"value":2430,"toc":2543},[2431,2434,2437,2440,2443,2468,2471,2479,2482,2485,2488,2491,2494,2540],[28,2432,2433],{},"刚刚，将 Ghost 博客迁移到了阿里云 Docker 上。",[28,2435,2436],{},"由于近期网络问题，导致家里的 NAS 已经无法提供 443 端口的服务了，之前的临时解决方案是将 hadb.me 的域名解析到 DigitalOcean 的一台机器上，然后用 nginx 转发到 NAS 的 20443 端口，通过海外的服务器做了中转，访问速度可想而知。并且近期海外网络极不稳定，最终决定还是老老实实备案，迁移到阿里云上来。",[28,2438,2439],{},"近年来，Docker 容器化越来越火，我最近的几个项目也都是通过 Docker 来部署的，非常方便。",[28,2441,2442],{},"域名备案经历了几波周折，提交备案后，阿里云初检未通过，有如下问题：",[2444,2445,2446,2456,2459,2462,2465],"ol",{},[2447,2448,2449,2450,2455],"li",{},"根据要求已经取得备案号的网站最下方必须显示您的备案号，并能链接到工信部网站",[202,2451,2454],{"href":2452,"rel":2453},"http:\u002F\u002Fwww.miitbeian.gov.cn\u002F",[206],"www.miitbeian.gov.cn","，目前您网站“monkeyrun.net”最下方备案号无法链接工信部网站，请您修改",[2447,2457,2458],{},"根据要求网站名称必须与主办单位名称有一定的关联性。您备案的网站名称“HADB 的博客”与主办单位名称“上海猿奋网络科技有限公司”没有关联性，请修改",[2447,2460,2461],{},"根据要求域名持有者必须与主办单位名称一致，经查询您的域名“hadb.me”持有者与您备案信息中“邓斌 ”单位名称\u002F法人姓名不一致，请您先办理域名过户",[2447,2463,2464],{},"根据管局要求域名有效期需要大于 6 个月，您的域名“hadb.me”有效期不足 6 个月，请您修改",[2447,2466,2467],{},"“邓斌”证件号码在多个单位\u002F个人备案中重复出现多次，根据要求，一个证件号码只能出现在一个单位\u002F个人备案下，请您更换其它证件",[28,2469,2470],{},"问题 1、2 改起来都还好，很快改完了。",[28,2472,2473,2474,2478],{},"问题 3 操作的过程中遇到了一个很蛋疼的问题。域名原先在 Godaddy 上购买的，在过户前，手贱把域名里的持有者信息修改了下，从英文名改成了中文品拼音，然后就尴尬了，Godaddy 禁止域名转出了，锁定期貌似 60 天，后来给 Godaddy 打中文客服，一个妹子客服跟我说可以给",[202,2475,2477],{"href":2476},"mailto:review60@goaddy.com","review60@goaddy.com","发邮件申请解锁，发了邮件一天没回复。又打电话过去，这次是个男客服接的，他跟我说，这个锁定期是没办法解锁的，巴拉巴拉，口径竟然不一样。后来 Godaddy 的 review60 团队回复我邮件了，说已经解锁了 60 天的锁定期。如果有遇到同样问题的朋友，可以尝试给 review60 团队发邮件就可以解锁了。但是在万网进行域名过户的时候，一直提示“该域名产品暂时不允许转入，无法进行转入操作”，查了下，万网目前不支持.me 域名的新注册和转入。后来就尝试了下直接提交，没有做过户操作，也通过了初审。阿里云这里要求的过户其实是非必要的，只需要把持有者信息修改就可以了。",[28,2480,2481],{},"问题 4 续费了下就可以了。",[28,2483,2484],{},"问题 5，也费了些功夫。几年前上大学时，一个外包项目中用的我自己的身份证作为网站负责人备案的。之前一直没有要求说一个证件号码只能出现在一个备案下，不过既然现在提示了这个问题，那就去处理下。由于这个外包项目已经停止了，并且甲方的网站也已经不做了。所以处理起来很简单，直接登录原备案账号，把备案号注销掉就可以了。",[28,2486,2487],{},"几经周折，备案号终于下来了，接下来开始处理部署的问题。",[28,2489,2490],{},"在阿里云上部署与在自己的机器上部署 Docker 有些区别。",[28,2492,2493],{},"具体流程如下：",[2444,2495,2496,2499,2506,2516,2534,2537],{},[2447,2497,2498],{},"购买阿里云文件存储 NAS 服务，用来存放 Docker 数据卷",[2447,2500,2501,2502,2505],{},"在 ECS 上挂在 NAS，将以前的博客数据复制到 NAS 中的",[39,2503,2504],{},"\u002Fghost-hadb-data","目录下",[2447,2507,2508,2509,2512,2513,2515],{},"容器服务中创建 NAS 类型的数据卷",[39,2510,2511],{},"ghost-hadb-data","，指向",[39,2514,2504],{},"目录",[2447,2517,2518,2519,2522,2523,2526,2527,2530,2531],{},"创建应用，简单路由配置，将",[39,2520,2521],{},"hadb.me","指向容器端口",[39,2524,2525],{},"2368","，选择刚刚创建的数据卷，容器路径为",[39,2528,2529],{},"\u002Fvar\u002Flib\u002Fghost\u002Fcontent","，在环境变量中配置 url 为",[39,2532,2533],{},"https:\u002F\u002Fhadb.me\u002F",[2447,2535,2536],{},"配置负载均衡，添加 https 协议 443 端口监听，导入证书",[2447,2538,2539],{},"将域名解析切换到负载均衡 ip 地址",[28,2541,2542],{},"Done！以后可以愉快的写博客啦！",{"title":37,"searchDepth":81,"depth":81,"links":2544},[],"2017-11-02",{},"\u002Fposts\u002F2017\u002Ftransfer-blog-to-aliyun-docker",{"text":2549,"minutes":2550,"time":2551,"words":2552},"6 min read",5.875,352500,1175,{"title":2428,"description":2433},{"loc":2547},"posts\u002F2017\u002F20171102.transfer-blog-to-aliyun-docker",[268,269,270,2423],"Q9OzmZ88ueumMvvOGN6bGncIsjTRbiAg-qgAHmieR4k",{"id":2559,"title":2560,"body":2561,"class":252,"cover":253,"coverSize":252,"date":2963,"description":2565,"draft":255,"extension":256,"hideComments":255,"location":252,"meta":2964,"navigation":108,"path":2965,"readingTime":2966,"seo":2970,"sitemap":2971,"stem":2972,"tags":2973,"time":252,"weather":252,"__hash__":2974},"posts\u002Fposts\u002F2017\u002F20171010.using-ghost.md","开始使用 Ghost 啦！",{"type":25,"value":2562,"toc":2957},[2563,2566,2575,2582,2585,2588,2592,2650,2654,2831,2844,2847,2875,2879,2951,2954],[28,2564,2565],{},"关注 Ghost 很久很久了，14 年就尝试过 0.5.3 版，由于一直没有出正式版，所以一直处于关注和等待中。",[28,2567,2568,2569,2574],{},"终于在差不多一年前 Ghost 在 GitHub 上发布了",[202,2570,2573],{"href":2571,"rel":2572},"https:\u002F\u002Fgithub.com\u002FTryGhost\u002FGhost\u002Freleases\u002Ftag\u002F1.0.0-alpha.1",[206],"1.0.0-alpha.1","，本以为很快就能出正式版了，开始了焦急的等待。一开始基本上每天都会去 GitHub 上检查下他们的动态。后来变成了大约每周会去看一次，等了一个又一个版本，甚至等了大半年，终于在第 21 个 alpha 版后，推出了 beta 版，随后不久发布了 1.0.0 正式版。尝试去安装，结果发现挺多坑的，试了很久都没成功，正式版的 Docker 镜像也一直没出。再后面，Ghost 团队的更新也非常勤奋，基本每周都会发布新版本，那段期间我正好也比较忙，一直在默默关注，没有再去尝试安装，任务列表里的“博客迁移到 Ghost 上”也被一再推迟。",[28,2576,2577,2578,2581],{},"直到今天，突然想再去试下。看到 Docker 镜像也同步了最新的版本，于是直接上 Docker。几分钟就装完了，如丝般顺滑，很爽！（20171012 更新：通过默认命令安装，有些地址会显示成 localhost 开头的地址，通过",[39,2579,2580],{},"--env url=https:\u002F\u002Fhadb.me\u002F","可以修改这个地址，但是由于 Nginx 设置有问题，导致设置成 https 的地址后就陷入重定向循环，这个问题后来困扰了很久，解决方案下面会讲。）",[28,2583,2584],{},"作为一个技术博主，我觉得还是有必要把安装步骤写一下，方便后人。",[28,2586,2587],{},"我的博客是搭建在自己家里的 NAS 服务器上，具体细节以后再讲。",[2589,2590,2591],"h3",{"id":2591},"宿主机安装证书",[32,2593,2595],{"className":1109,"code":2594,"language":1111,"meta":37,"style":37},"service nginx stop && \\\ncertbot certonly --standalone --preferred-challenges tls-sni -d hadb.me && \\\nservice nginx start\n",[39,2596,2597,2614,2641],{"__ignoreMap":37},[42,2598,2599,2602,2605,2608,2611],{"class":44,"line":45},[42,2600,2601],{"class":1118},"service",[42,2603,2604],{"class":48}," nginx",[42,2606,2607],{"class":48}," stop",[42,2609,2610],{"class":226}," &&",[42,2612,2613],{"class":310}," \\\n",[42,2615,2616,2619,2622,2625,2628,2631,2634,2637,2639],{"class":44,"line":81},[42,2617,2618],{"class":1118},"certbot",[42,2620,2621],{"class":48}," certonly",[42,2623,2624],{"class":1128}," --standalone",[42,2626,2627],{"class":1128}," --preferred-challenges",[42,2629,2630],{"class":48}," tls-sni",[42,2632,2633],{"class":1128}," -d",[42,2635,2636],{"class":48}," hadb.me",[42,2638,2610],{"class":226},[42,2640,2613],{"class":310},[42,2642,2643,2645,2647],{"class":44,"line":105},[42,2644,2601],{"class":1118},[42,2646,2604],{"class":48},[42,2648,2649],{"class":48}," start\n",[2589,2651,2653],{"id":2652},"宿主机-nginx-设置","宿主机 Nginx 设置",[32,2655,2659],{"className":2656,"code":2657,"language":2658,"meta":37,"style":37},"language-nginx shiki shiki-themes material-theme-lighter github-light github-dark","server {\n    listen 443 ssl;\n    server_name hadb.me;\n    client_max_body_size 1024m;\n    ssl on;\n    ssl_certificate \u002Fetc\u002Fletsencrypt\u002Flive\u002Fhadb.me\u002Ffullchain.pem;\n    ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fhadb.me\u002Fprivkey.pem;\n    location \u002F {\n        proxy_redirect off;\n        proxy_read_timeout 300;\n        proxy_set_header host $host;\n        proxy_set_header x-real-ip $remote_addr;\n        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;\n        proxy_set_header x-forwarded-proto https;\n        proxy_pass http:\u002F\u002Flocalhost:12368;\n    }\n}\n","nginx",[39,2660,2661,2668,2681,2690,2700,2710,2720,2730,2740,2750,2760,2776,2790,2804,2813,2823,2827],{"__ignoreMap":37},[42,2662,2663,2666],{"class":44,"line":45},[42,2664,2665],{"class":306},"server",[42,2667,427],{"class":52},[42,2669,2670,2673,2676,2679],{"class":44,"line":81},[42,2671,2672],{"class":314},"    listen ",[42,2674,2675],{"class":1051},"443",[42,2677,2678],{"class":52}," ssl",[42,2680,404],{"class":226},[42,2682,2683,2686,2688],{"class":44,"line":105},[42,2684,2685],{"class":314},"    server_name ",[42,2687,2521],{"class":52},[42,2689,404],{"class":226},[42,2691,2692,2695,2698],{"class":44,"line":112},[42,2693,2694],{"class":314},"    client_max_body_size ",[42,2696,2697],{"class":1051},"1024m",[42,2699,404],{"class":226},[42,2701,2702,2705,2708],{"class":44,"line":118},[42,2703,2704],{"class":314},"    ssl ",[42,2706,2707],{"class":56},"on",[42,2709,404],{"class":226},[42,2711,2712,2715,2718],{"class":44,"line":123},[42,2713,2714],{"class":314},"    ssl_certificate ",[42,2716,2717],{"class":52},"\u002Fetc\u002Fletsencrypt\u002Flive\u002Fhadb.me\u002Ffullchain.pem",[42,2719,404],{"class":226},[42,2721,2722,2725,2728],{"class":44,"line":132},[42,2723,2724],{"class":314},"    ssl_certificate_key ",[42,2726,2727],{"class":52},"\u002Fetc\u002Fletsencrypt\u002Flive\u002Fhadb.me\u002Fprivkey.pem",[42,2729,404],{"class":226},[42,2731,2732,2735,2738],{"class":44,"line":138},[42,2733,2734],{"class":306},"    location",[42,2736,2737],{"class":1118}," \u002F ",[42,2739,483],{"class":52},[42,2741,2742,2745,2748],{"class":44,"line":143},[42,2743,2744],{"class":314},"        proxy_redirect ",[42,2746,2747],{"class":56},"off",[42,2749,404],{"class":226},[42,2751,2752,2755,2758],{"class":44,"line":151},[42,2753,2754],{"class":314},"        proxy_read_timeout ",[42,2756,2757],{"class":1051},"300",[42,2759,404],{"class":226},[42,2761,2762,2765,2768,2771,2774],{"class":44,"line":157},[42,2763,2764],{"class":314},"        proxy_set_header ",[42,2766,2767],{"class":52},"host ",[42,2769,2770],{"class":226},"$",[42,2772,2773],{"class":52},"host",[42,2775,404],{"class":226},[42,2777,2778,2780,2783,2785,2788],{"class":44,"line":162},[42,2779,2764],{"class":314},[42,2781,2782],{"class":52},"x-real-ip ",[42,2784,2770],{"class":226},[42,2786,2787],{"class":52},"remote_addr",[42,2789,404],{"class":226},[42,2791,2792,2794,2797,2799,2802],{"class":44,"line":188},[42,2793,2764],{"class":314},[42,2795,2796],{"class":52},"x-forwarded-for ",[42,2798,2770],{"class":226},[42,2800,2801],{"class":52},"proxy_add_x_forwarded_for",[42,2803,404],{"class":226},[42,2805,2806,2808,2811],{"class":44,"line":194},[42,2807,2764],{"class":314},[42,2809,2810],{"class":52},"x-forwarded-proto https",[42,2812,404],{"class":226},[42,2814,2815,2818,2821],{"class":44,"line":547},[42,2816,2817],{"class":314},"        proxy_pass ",[42,2819,2820],{"class":52},"http:\u002F\u002Flocalhost:12368",[42,2822,404],{"class":226},[42,2824,2825],{"class":44,"line":570},[42,2826,897],{"class":52},[42,2828,2829],{"class":44,"line":613},[42,2830,1359],{"class":52},[28,2832,2833,2834,2837,2838,2843],{},"其中 ",[39,2835,2836],{},"proxy_set_header x-forwarded-proto https;","很重要，如果不加的话，当启动 docker 设置 url 为 https 开头的地址时，就会陷入重定向循环，这个问题困扰了我很久，最终在",[202,2839,2842],{"href":2840,"rel":2841},"https:\u002F\u002Fgithub.com\u002FTryGhost\u002FGhost\u002Fissues\u002F2796",[206],"这个 issue","里找到了答案。",[2589,2845,2846],{"id":2846},"创建数据镜像",[32,2848,2850],{"className":1109,"code":2849,"language":1111,"meta":37,"style":37},"docker create -v \u002Fsrv\u002Fghost\u002Fhadb.me:\u002Fvar\u002Flib\u002Fghost\u002Fcontent --name ghost-hadb-me-data ubuntu:16.04\n",[39,2851,2852],{"__ignoreMap":37},[42,2853,2854,2857,2860,2863,2866,2869,2872],{"class":44,"line":45},[42,2855,2856],{"class":1118},"docker",[42,2858,2859],{"class":48}," create",[42,2861,2862],{"class":1128}," -v",[42,2864,2865],{"class":48}," \u002Fsrv\u002Fghost\u002Fhadb.me:\u002Fvar\u002Flib\u002Fghost\u002Fcontent",[42,2867,2868],{"class":1128}," --name",[42,2870,2871],{"class":48}," ghost-hadb-me-data",[42,2873,2874],{"class":48}," ubuntu:16.04\n",[2589,2876,2878],{"id":2877},"启动-docker","启动 docker",[32,2880,2882],{"className":1109,"code":2881,"language":1111,"meta":37,"style":37},"sudo docker run --detach \\\n    --name ghost-hadb-me \\\n    --env url=https:\u002F\u002Fhadb.me\u002F \\\n    --publish 12368:2368 \\\n    --volumes-from ghost-hadb-me-data \\\n    --tty \\\n    ghost:latest\n",[39,2883,2884,2900,2910,2920,2930,2939,2946],{"__ignoreMap":37},[42,2885,2886,2889,2892,2895,2898],{"class":44,"line":45},[42,2887,2888],{"class":1118},"sudo",[42,2890,2891],{"class":48}," docker",[42,2893,2894],{"class":48}," run",[42,2896,2897],{"class":1128}," --detach",[42,2899,2613],{"class":310},[42,2901,2902,2905,2908],{"class":44,"line":81},[42,2903,2904],{"class":1128},"    --name",[42,2906,2907],{"class":48}," ghost-hadb-me",[42,2909,2613],{"class":310},[42,2911,2912,2915,2918],{"class":44,"line":105},[42,2913,2914],{"class":1128},"    --env",[42,2916,2917],{"class":48}," url=https:\u002F\u002Fhadb.me\u002F",[42,2919,2613],{"class":310},[42,2921,2922,2925,2928],{"class":44,"line":112},[42,2923,2924],{"class":1128},"    --publish",[42,2926,2927],{"class":48}," 12368:2368",[42,2929,2613],{"class":310},[42,2931,2932,2935,2937],{"class":44,"line":118},[42,2933,2934],{"class":1128},"    --volumes-from",[42,2936,2871],{"class":48},[42,2938,2613],{"class":310},[42,2940,2941,2944],{"class":44,"line":123},[42,2942,2943],{"class":1128},"    --tty",[42,2945,2613],{"class":310},[42,2947,2948],{"class":44,"line":132},[42,2949,2950],{"class":48},"    ghost:latest\n",[28,2952,2953],{},"几行命令，Done！就可以开始愉快的写博客啦！哈哈哈哈哈！😃",[247,2955,2956],{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":37,"searchDepth":81,"depth":81,"links":2958},[2959,2960,2961,2962],{"id":2591,"depth":105,"text":2591},{"id":2652,"depth":105,"text":2653},{"id":2846,"depth":105,"text":2846},{"id":2877,"depth":105,"text":2878},"2017-10-10",{},"\u002Fposts\u002F2017\u002Fusing-ghost",{"text":2348,"minutes":2967,"time":2968,"words":2969},3.1,186000,620,{"title":2560,"description":2565},{"loc":2965},"posts\u002F2017\u002F20171010.using-ghost",[2386,269,270],"aQh0LmH4L7dkjrMd97oz4c-PPl_DvBo7RQ3snUK00OM",1777580269172]