日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

docker脚本安装 阿里云_让运行在 Docker 中的 Ghost 支持阿里云 OSS

發布時間:2025/3/19 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 docker脚本安装 阿里云_让运行在 Docker 中的 Ghost 支持阿里云 OSS 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文使用「署名 4.0 國際 (CC BY 4.0)」許可協議,歡迎轉載、或重新修改使用,但需要注明來源。 署名 4.0 國際 (CC BY 4.0)

本文作者: 蘇洋

創建時間: 2020年03月14日 統計字數: 8133字 閱讀時間: 17分鐘閱讀 本文鏈接: https://soulteary.com/2020/03/14/ghost-running-in-docker-supports-alibaba-cloud-oss.html


讓運行在 Docker 中的 Ghost 支持阿里云 OSS

最近在優化 Ghost 作為線上使用的內容管理后臺,作為線上使用的系統,不同于內部 MIS ,可靠性和應用性能需要有一定保障。

解決性能問題,最簡單的方案便是進行水平擴展,而我們知道,如果想要讓一個服務做到水平可擴展,除了要將應用運行狀態單獨持久化外,也必須做到文件儲存的持久化,云平臺的對象儲存就是一個很好的文件持久化方案。

Ghost 是一個典型的單體應用,v3.x 版本的容器化文檔其實不多,而介紹如何使用 Aliyun OSS 的文檔更是沒有,折騰過程還是挺有趣的,記錄下來,希望能夠幫助到后面有需求的同學。

寫在前面

官方文檔在使用三方自定義儲存部分其實寫的不是很好:

  • 文檔有效性不敢恭維,雖然內容中提到支持阿里云,但是列表中的阿里云OSS插件僅針對于 1.x 版本,其中阿里云的 SDK 也比較舊,當時的 Node 環境也很陳舊。
  • 自定義文檔缺少技術細節、以及完整描述,需要通過實踐和閱讀源碼去驗證。
  • 完全沒提到如何在容器鏡像,尤其是官方鏡像中使用插件。
  • 本文將通過相對流程化的容器方案,來解決以上問題。

    之前的文章《從定制 Ghost 鏡像聊聊優化 Dockerfile》、修理 Ghost 中文輸入法的 BUG 有提過,“如何對 Ghost 進行容器化封裝”,感興趣的同學可以了解下。

    在“反復橫跳”踩了一堆坑之后,相對穩妥的低成本維護方案便是為 Ghost 編寫適合當前版本的儲存插件,并制作基于官方容器鏡像的補丁鏡像了。

    在編寫插件之前,需要先確認官方環境中的 Node 版本,以確定符號語法:

    docker run --rm -it --entrypoint /usr/local/bin/node ghost:3.9.0-alpine -v

    執行完上述命令,你將得到 v12.16.1 的結果,看來可以直接使用 async/await 來編寫插件減少代碼量了。

    編寫 OSS 儲存插件

    參考官方模版,以及阿里云 OSS SDK 完成儲存插件大概十幾分鐘就搞定了,相關代碼我已經上傳至 GitHub,如果需要二次封裝,可以參考使用。

    /*** Ghost v3 Storage Adapter (Aliyun OSS)* @author soulteary(soulteary@gmail.com)*/const AliOSS = require("ali-oss"); const GhostStorage = require("ghost-storage-base"); const { createReadStream } = require("fs"); const { resolve } = require("path");class AliOSSAdapter extends GhostStorage {constructor(config) {super();this.config = config || {};this.oss = new AliOSS({region: config.region,accessKeyId: config.accessKeyId,accessKeySecret: config.accessKeySecret,bucket: config.bucket});this.ossURL = `${config.bucket}.${config.region}.aliyuncs.com`;this.regexp = new RegExp(`^https?://${this.ossURL}`, "i");this.domain = config.domain || null;this.notfound = config.notfound || null;}async exists(filename, targetDir = this.getTargetDir("/")) {try {const { status } = await this.oss.head(resolve(targetDir, filename));return status === 404;} catch (err) {return false;}}delete() {// it's unnecessary// Ghost missing UX}serve() {return function(req, res, next) {next();};}async read(options) {try {const { meta } = await this.oss.head(options.path);if (meta && meta.path) {return meta.path;} else {return this.notfound;}} catch (err) {console.error(`Read Image Error ${err}`);return this.notfound;}}async save(image, targetDir = this.getTargetDir("/")) {try {const filename = await this.getUniqueFileName(image, targetDir);const { url } = await this.oss.put(filename, createReadStream(image.path));if (url && url.indexOf(`://${this.ossURL}`) > -1) {return this.domain ? url.replace(this.regexp, this.domain) : url;} else {return this.notfound;}} catch (err) {console.error(`Upload Image Error ${err}`);return this.notfound;}} }module.exports = AliOSSAdapter;

    這里支持的配置內容有:

    {"storage": {"active": "ghost-aliyun-oss-store","ghost-aliyun-oss-store": {"accessKeyId": "YOUR_ACCESS_KEY_ID","accessKeySecret": "YOUR_ACCESS_SERCET","bucket": "YOUR_BUCKET_NAME","region": "oss-cn-beijing","domain": "https://your-public-domian","notfound": "https://s3-img.meituan.net/v1/mss_3d027b52ec5a4d589e68050845611e68/ff/n0/0k/4n/3s_73850.jpg"}} }

    其中 domian、是可選項,如果你需要使用 CDN 域名,請在這個字段里配置。

    封裝支持 OSS 插件的鏡像

    為了保證運行鏡像性能足夠高、尺寸相對較小,我們需要使用 docker multistage build方案。

    先定義基礎鏡像,并安裝剛剛編寫的 Ghost Aliyun OSS 插件。

    FROM ghost:3.9.0-alpine as oss LABEL maintainer="soulteary@gmail.com" WORKDIR $GHOST_INSTALL/current RUN su-exec node yarn --verbose add ghost-aliyun-oss-store

    接著定義運行使用的鏡像。

    FROM ghost:3.9.0-alpine LABEL maintainer="soulteary@gmail.com" COPY --chown=node:node --from=oss $GHOST_INSTALL/current/node_modules $GHOST_INSTALL/current/node_modules RUN mkdir -p $GHOST_INSTALL/current/content/adapters/storage/ RUN echo "module.exports = require('ghost-aliyun-oss-store');" > $GHOST_INSTALL/current/content/adapters/storage/ghost-aliyun-oss-store.js

    參考之前的兩篇文章,如果想解決“不能正常進行中文輸入”的問題,并且提取出了構建后的內容,可以在鏡像中添加下面的內容:

    COPY ./docker-assets/admin-views $GHOST_INSTALL/current/core/server/web/admin/views COPY ./docker-assets/built/assets $GHOST_INSTALL/current/core/built/assets

    如果你不希望將配置單獨抽象為文件,可以添加下面的內容。

    RUN set -ex; su-exec node ghost config storage.active ghost-aliyun-oss-store; su-exec node ghost config storage.ghost-aliyun-oss-store.accessKeyId YOUR_ACCESS_KEY_ID; su-exec node ghost config storage.ghost-aliyun-oss-store.accessKeySecret YOUR_ACCESS_SERCET; su-exec node ghost config storage.ghost-aliyun-oss-store.bucket YOUR_BUCKET_NAME; su-exec node ghost config storage.ghost-aliyun-oss-store.region oss-cn-beijing; su-exec node ghost config storage.ghost-aliyun-oss-store.domain https://your-public-domian; su-exec node ghost config storage.ghost-aliyun-oss-store.notfound https://s3-img.meituan.net/v1/mss_3d027b52ec5a4d589e68050845611e68/ff/n0/0k/4n/3s_73850.jpg; su-exec node ghost config privacy.useUpdateCheck false; su-exec node ghost config privacy.useGravatar false; su-exec node ghost config privacy.useRpcPing false; su-exec node ghost config privacy.useStructuredData false;

    當然,為了更方便更新內容,抽象為單獨的文件是更好的選擇,比如像下面這樣編寫 config.production.json 配置文件。

    {"server": {"port": 2368,"host": "0.0.0.0"},"privacy": {"useUpdateCheck": false,"useGravatar": false,"useRpcPing": false,"useStructuredData": false},"storage": {"active": "ghost-aliyun-oss-store","ghost-aliyun-oss-store": {"accessKeyId": "YOUR_ACCESS_KEY_ID","accessKeySecret": "YOUR_ACCESS_SERCET","bucket": "baai-news-upload","region": "oss-cn-beijing","domain": "https://your-public-domian","notfound": "https://s3-img.meituan.net/v1/mss_3d027b52ec5a4d589e68050845611e68/ff/n0/0k/4n/3s_73850.jpg"}} }

    完整的容器編排文件

    上面聊了許多定制化的選項,那么一個最小可用的容器編排配置是什么樣的呢?其實大概不到十行,就足以滿足我們的基礎需求。

    FROM ghost:3.9.0-alpine as oss WORKDIR $GHOST_INSTALL/current RUN su-exec node yarn --verbose add ghost-aliyun-oss-storeFROM ghost:3.9.0-alpine LABEL maintainer="soulteary@gmail.com" COPY --chown=node:node --from=oss $GHOST_INSTALL/current/node_modules $GHOST_INSTALL/current/node_modules RUN mkdir -p $GHOST_INSTALL/current/content/adapters/storage/ RUN echo "module.exports = require('ghost-aliyun-oss-store');" > $GHOST_INSTALL/current/content/adapters/storage/ghost-aliyun-oss-store.js

    將上面的內容保存為 Dockerfile,如果需要其他的功能,可以參考上面的內容進行適當修改。

    docker build -t soulteary/ghost-with-oss:3.9.0 -f Dockerfile .

    執行上面的命令,稍等片刻,一個衍生自Ghost官方鏡像,支持 OSS 的容器鏡像就構建完畢了。

    如何使用鏡像

    這里給出一個完整編排文件供大家參考,如果不想使用 Traefik,只需要將端口單獨暴露出來即可。

    至于 Traefik 如何使用,參考我以往的文章,熟悉之后,你將會發現一片新的天地。

    version: "3.6"services:ghost-with-oss:image: soulteary/ghost-with-oss:3.9.0expose:- 2368environment:url: https://ghost.lab.iodatabase__client: mysqldatabase__connection__host: ghost-dbdatabase__connection__port: 3306database__connection__user: rootdatabase__connection__password: ghostdatabase__connection__database: ghostNODE_ENV: productionvolumes:# 這里參考前篇文章,或者本篇文章內容,選擇性使用# 解決 Ghost 中文輸入的問題# - ./docker-assets/built/assets:/var/lib/ghost/versions/current/core/built/assets:ro# - ./docker-assets/admin-views:/var/lib/ghost/current/core/server/web/admin/views:ro- ./config.production.json:/var/lib/ghost/config.production.json extra_hosts:- "ghost.lab.io:127.0.0.1"networks:- traefiklabels:- "traefik.enable=true"- "traefik.docker.network=traefik"- "traefik.http.routers.ghostweb.entrypoints=http"- "traefik.http.routers.ghostweb.middlewares=https-redirect@file"- "traefik.http.routers.ghostweb.rule=Host(`ghost.lab.io`)"- "traefik.http.routers.ghostssl.middlewares=content-compress@file"- "traefik.http.routers.ghostssl.entrypoints=https"- "traefik.http.routers.ghostssl.tls=true"- "traefik.http.routers.ghostssl.rule=Host(`ghost.lab.io`)"- "traefik.http.services.ghostbackend.loadbalancer.server.scheme=http"- "traefik.http.services.ghostbackend.loadbalancer.server.port=2368"networks:traefik:external: true

    將上面內容保存為 docker-compose.yml,使用 docker-compose up -d 啟動應用,最后訪問配置里定義的域名即可開始使用這個支持 OSS 功能的 Ghost 。

    當然,如果你沒有線上數據庫,也可以使用 docker-compose 啟動一個數據庫:

    version: '3' services:db:image: mysql:5.7container_name: ghost-dbexpose:- 3306networks:- traefikrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: ghostvolumes:- ./localdb:/var/lib/mysqlnetworks:traefik:external: true

    最后

    本篇內容,以封裝 Ghost 定制鏡像簡單說明了如何基于官方鏡像進行擴展,并簡單示范了 Docker Multistage Build,以及 Ghost 3.x 版本如何使用 Aliyun OSS。

    或許下一篇內容會聊聊,Ghost 這類原本不支持 SSO 單點登錄的應用如何快速接入 SSO。

    --EOF


    我現在有一個小小的折騰群,里面聚集了一些喜歡折騰的小伙伴。

    在不發廣告的情況下,我們在里面會一起聊聊軟件、HomeLab、編程上的一些問題,也會在群里不定期的分享一些技術沙龍的資料。

    喜歡折騰的小伙伴歡迎掃碼添加好友。(請注明來源和目的,否則不會通過審核)

    蘇洋:關于折騰群入群的那些事?zhuanlan.zhihu.com

    總結

    以上是生活随笔為你收集整理的docker脚本安装 阿里云_让运行在 Docker 中的 Ghost 支持阿里云 OSS的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。