Docker折騰記: (1)構建yapi容器,從構建發佈到可用

前言

yapi是什麼?javascript

YApi 是一個可本地部署的、打通先後端及QA的、可視化的接口管理平臺 yapi.ymfe.orghtml

文章會穿插部分相關的知識點,能夠節省你爬坑的時間,都是一步一步爬出來的,java

從定製構建的思路,優化,實現的姿式, 感興趣的小夥伴往下走~~~node

效果圖

登陸

登陸成功

項目區域

yapi容器

已經內置了bash爲默認shell,vim也配置了一些經常使用的設置git

  • vim的預設

前置基礎

知識儲備

Docker/Linux/Node基礎, 好比Linux和docker的經常使用命令,shell的編寫等等github

構建基礎環境

  • Docker version 18.03.1-ce
    • 基於alpine ,alpine是一個很是輕量級的Linux,裸版本只有5M
  • Docker Compose(從 pip3 安裝的默認版本)

構建的目標: 能用/能升級,數據庫獨立,第一次構建是拉取最新的版本!!!!mongodb

實用科普

如果走Docker Hub自動化構建,由於是在國外服務器構建,不存在慢的問題,docker

下面的僅限於你本地構建的時候採納

衆所周知國外的資源都比較慢,因此咱們構建優先選擇境內提供的

Docker中國源:

Linux鏡像源用的科大源

alpine的倉庫列表,官方的且支持查詢

隔天同步Github的碼雲

儘量最小化配置,因此不配置什麼個性化的東西了,好比oh my zsh,neovim這些

經過這篇文章,你能大致學會docker的簡單部署,基本的dockerfile編寫, 以及如何發佈本身定製化的容器

我提供的yapi 鏡像走自動化構建,因此內部依賴的仍是國際源,不在本地打包,不會有慢之說

因此要拉取的小夥伴,只要考慮docker拉取源就行啦

常規構建yapi

我這裏選擇的是基於alpine來構建, 構建的姿式不少,

你能夠從一個空容器也能從別人打包好的node容器

鏡像的功能儘量保持單一化,這樣有利於編排,

如果一個鏡像提供多個服務,維護起來是比較麻煩的.

特別是更新亦或者須要暫停某些服務的時候,要考慮的東西不少

版本一:中規中矩

Dockfile

# 基於 alpine鏡像構建
FROM alpine:3.8
# 鏡像維護者的信息
LABEL MAINTAINER = 'crper@outlook.com(https://github.com/crper)' # 基礎環境構建
# - 替換國內源,速度槓槓的
# - 更新源
# - 安裝基礎環境包
# - 更改用戶的默認shell , 由於容器只是給yapi用,因此就不考慮建立用戶組和獨立用戶這種東西,因此只有root用戶了
# ,如果容器包括多功能就須要用戶組這些好一些(不推薦容器有太多功能),儘量保持容器功能的單一性
# - 最後是刪除一些緩存
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \ && apk update \ && apk add --no-cache shadow git nodejs nodejs-current-npm bash vim tar curl python python-dev py-pip gcc libcurl make\ && usermod -s /bin/bash root \ && rm -rf /var/cache/apk/* # 克隆項目以及初始化項目
# yapi 官方的內網部署教程: https://yapi.ymfe.org/devops/index.html
# install-server會初始化數據庫索引和管理員帳號,管理員帳號名可在 config.json 配置
RUN npm i -g node-gyp --registry https://registry.npm.taobao.org \ && npm install -g yapi-cli --registry https://registry.npm.taobao.org \ && mkdir /yapi && cd /yapi \ && git clone https://github.com/YMFE/yapi.git vendors \ && cd vendors \ && npm install --production --registry https://registry.npm.taobao.org # 工做目錄
WORKDIR /yapi/vendors # 配置yapi的配置文件
COPY config.json /yapi/ # 複製執行腳本到容器的執行目錄
COPY entrypoint.sh /usr/local/bin/ 
# 向外暴露的端口
EXPOSE 3000

# 指定配置文件
ENTRYPOINT ["entrypoint.sh"] 


複製代碼

entrypoint.sh

#!/bin/sh 
# yapi初始化後會有一個init.lock文件
lockPath="/yapi/init.lock"

# 若是初始化文件文件存在,則直接運行,不然初始化
if [ ! -f "$lockPath" ]; then
  node /yapi/vendors/server/install.js
else
  node /yapi/vendors/server/app.js
fi

複製代碼

.dockerignore

這個文件是個好東西,跟.gitignore相似的,就是專門用來忽略提交文件的,不至於讓咱們鏡像帶上一些沒必要要的東西

.git/
node_modules/
複製代碼

本地打包鏡像後才發現,雖能夠用,但有兩個問題暴露出來(體積,構建速度)

因此我考慮下能不能優化,

版本二:減少鏡像體積,減小構建時間

選一個好的父容器,一個是減小構建的層數,一個是減小依賴包

第一步不能改了,雖然也有node-alpine這些,只能從後面兩個入手

Dockfile

# 基於 alpine鏡像構建
FROM alpine:3.8
# 鏡像維護者的信息
LABEL MAINTAINER = 'crper@outlook.com(https://github.com/crper)' # 基礎環境構建
# - 替換國內源,速度槓槓的
# - 更新源
# - 安裝基礎環境包
# - 更改用戶的默認shell , 由於容器只是給yapi用,因此就不考慮建立用戶組和獨立用戶這種東西,因此只有root用戶了
# ,如果容器包括多功能就須要用戶組這些好一些(不推薦容器有太多功能),儘量保持容器功能的單一性
# - 最後是刪除一些緩存
# - 克隆項目
# !! yapi 官方的內網部署教程: https://yapi.ymfe.org/devops/index.html
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \ && apk update \ && apk add --no-cache shadow git nodejs nodejs-current-npm bash vim tar curl python python-dev py-pip gcc libcurl make\ && usermod -s /bin/bash root \ && rm -rf /var/cache/apk/* \ && mkdir /yapi && cd /yapi && git clone https://gitee.com/mirrors/YApi.git vendors # 工做目錄
WORKDIR /yapi/vendors # 配置yapi的配置文件
COPY config.json /yapi/ # 複製執行腳本到容器的執行目錄
COPY entrypoint.sh /usr/local/bin/ # 寫好的vim配置文件複製進去
COPY .vimrc /root/ # 向外暴露的端口
EXPOSE 3000

# 指定配置文件
ENTRYPOINT ["entrypoint.sh"] 

# `shadow`: `alpine`默認不集成`usermod`,因此須要這個額外包,由於要用來更改默認`shell`
# `vim` : 編輯神器
# `tar` : 解壓縮
# `make`: 編譯依賴的
# `gcc`: GNU編譯器套裝
# `python`: `python python-dev py-pip`這三個包包括了基本開發環境
# `curl` 能夠測試鏈接也能下載內容的命令行工具
# `git` : 不用說了
# `nodejs` : node
# `nodejs-current-npm` : `alpine`Linux版本須要依賴這個版本,才能讓`npm`識別到

複製代碼

entrypoint.sh

#!/bin/sh 
# yapi初始化後會有一個init.lock文件
lockPath="/yapi/init.lock"

# 設置源爲淘寶源
npm config set registry http://registry.npm.taobao.org/;

# 進入yapi項目
cd /yapi/vendors


# 若是初始化文件文件存在,則直接運行,不然初始化
if [ ! -f "$lockPath" ]; then
  # 全局安裝用來更新yapi的cli
  npm i -g node-gyp yapi-cli;
  # 安裝初始化的依賴模塊
  npm i --production;
  # 啓動Yapi初始化
  node server/install.js
else
  node server/app.js
fi
複製代碼

從500多M的鏡像減少到400出頭,百分之二十仍是挺可觀,能不能再優化下呢!!!

vim,tar,bash,shadow,py-pip都能去掉了,其餘都是構建須要的(好比yapi初始化依賴python這些)

emm..... 去掉了這些,打包出來就減小了40多M,仍是還原吧,優化下構建時間

版本三: 下降初始化失敗的機率

由於用了dockerhub 的自動化構建,因此npm直接在構建的時候選擇官方源

Dockerfile

# 基於 alpine鏡像構建
FROM alpine:latest
# 鏡像維護者的信息
LABEL MAINTAINER = 'crper@outlook.com(https://github.com/crper)' # 基礎環境構建
# - 更新源
# - 安裝基礎環境包
# - 不用更改默認shell了,只要進入的鏡像的時候指定shell便可
# - 最後是刪除一些緩存
# - 克隆項目
# - 採用自動化構建不考慮國內npm源了 , 能夠下降初始化失敗的機率
# !! yapi 官方的內網部署教程: https://yapi.ymfe.org/devops/index.html
RUN apk update \ && apk add --no-cache git nodejs nodejs-current-npm bash vim python python-dev gcc libcurl make\ && rm -rf /var/cache/apk/* \ && mkdir /yapi && cd /yapi && git clone https://github.com/YMFE/yapi.git vendors \ && npm i -g node-gyp yapi-cli \ && cd /yapi/vendors && npm i --production; # 工做目錄
WORKDIR /yapi/vendors # 配置yapi的配置文件
COPY config.json /yapi/ # 複製執行腳本到容器的執行目錄
COPY entrypoint.sh /usr/local/bin/ # 寫好的vim配置文件複製進去
COPY .vimrc /root/ # 向外暴露的端口
EXPOSE 3000

# 指定配置文件
ENTRYPOINT ["entrypoint.sh"] 

# `vim` : 編輯神器
# `tar` : 解壓縮
# `make`: 編譯依賴的
# `gcc`: GNU編譯器套裝
# `python`: `python python-dev py-pip`這三個包包括了基本開發環境
# `curl` 能夠測試鏈接也能下載內容的命令行工具
# `git` : 不用說了
# `nodejs` : node
# `nodejs-current-npm` : `alpine`Linux版本須要依賴這個版本,才能讓`npm`識別到

複製代碼

entrypoint.sh

#!/bin/sh 
# yapi初始化後會有一個init.lock文件
lockPath="/yapi/init.lock"



# 進入yapi項目
cd /yapi/vendors


# 若是初始化文件文件存在,則直接運行,不然初始化
if [ ! -f "$lockPath" ]; then
  # 啓動Yapi初始化
  node server/install.js
else
  # 運行yapi管理系統
  node server/app.js
fi
複製代碼

打包鏡像

格式: docker build [option] tagName path

docker build -t yapi .;

默認不帶:來獨立版本號,打包出來爲latest

這裏的意思就是在當前目錄下,基於Dockfile構建一個鏡像,

你也能夠本身構建你的維護版本號,好比

docker build -t yapi:0.0.1 .

若須要壓縮鏡像爲gz格式,帶上--compress

發佈鏡像

常規終端手動發佈

登陸帳號

這裏的帳號就是docker官方註冊的帳號,總體的過程很相似git

  • 打開終端-> docker login

  • commit:提交你本身寫的或者二次定製的鏡像

規格: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] [flags]

  • push : 推送鏡像到遠程docker hub , 啊咧,報錯了?

提示咱們沒有權限,爲何會有這個問題,

docker hub的提交規範須要咱們用本身用戶名開頭,改一下便可

版本一的鏡像體積

版本二的鏡像體積

我提交的compress的版本,因此你在docker hub看到只有這麼大

走完這一步,你的做品就能夠在Dock Hub看到了

你能夠直接基於本地構建的鏡像搭建了,

如果你基於你本身的包再作二次構建,不須要走commit那一步也能夠的,改完直接push就好了

自動化構建發佈

Docker Hub提供了automated build,簡言之就是自動化構建,

咱們能夠關聯github倉庫來構建,bitbucket也能夠,可是我不用這個;

不論是從這裏仍是從用戶管理那裏,都須要提早綁定github(受權)

受權後,就能讀取到你的倉庫列表.選擇一個倉庫來構建,倉庫的要求,基本目錄以下

├── .dockerignore  //docker打包忽略的文件
├── .gitignore     //git提交忽略的文件
├── Dockerfile     //docker 構建配置文件
├── README.md      // 不用多說了
├── config.json    // yapi的配置文件
└── entrypoint.sh   // 構建入口的腳本
複製代碼

初始化能夠設置那些分支會觸發構建,亦或者觸發endpoint來構建, 最傻瓜化的就是勾選監聽push事件自動構建

如果你想把鏡像上傳到國內的阿里雲,dao這些,

有些須要註冊開發者帳號,根據他們的文檔要求來提交

鏡像部署

寫完的做品無法部署那就搞笑了,如今跟着我來部署你的鏡像以及初始化;

部署yapi

第一次初始化默認拉取的最新的版本,因此不用指定版本,

如果yapi代碼不嚴謹,連新版本初始化都會報錯則無解!

建立volume

  • docker volume create yapi-mongo

建立一個儲存卷,用來專門存放yapi使用的mongodb的數據

爲何要獨立出來,這是爲了之後升級的着想,數據庫保留,只要啓動的時候關聯一下就好了

啓動mongodb

  • docker run -d --name yapi-mongo -v yapi-mongo:/data/db mongo

爲何要先啓動mongodb,由於yapi初始化的時候依賴mongodb,好比建立用戶表這些

這條命令是什麼意思呢?

-d : 是啓動的時候輸出容器的id
--name : 是給容器設置一個名字,方便咱們控制,好比start,stop
-v : 指定關聯的卷 => 本地卷:容器內儲存位置 , 就是映射數據保存的地方

複製代碼

如果須要外部管理這個數據庫的話,最好也暴露出來端口, mongodb容器默認也暴露了27017端口

  • docker run -d --name yapi-mongo -v yapi-mongo:/data/db -p 27017:27017 mongo

初始化Yapi和啓動Yapi

  • 初始化yapi

docker run -d --name yapi -p 3000:3000 --link yapi-mongo crper/yapi

這裏比上面多的一個參數就是--link,用來使連個容器通信的,過期命令,官方已經不推薦

  • 啓動yapi

docker restart yapi

過程都可用docker logs details 容器ID或者name來看到內部的狀況

就是shell執行過程,好比這個項目就能夠在初始化的時候,看到初始化的帳號密碼(成功)

不論是mongo仍是crper/yapi ,當你請求一個容器不存在的時候,

會嘗試往dockhub上面找,默認拉取鏡像latest版本,找不到纔會報錯

如下就是基本的初始化信息

訪問連接: 127.0.0.1:3000
默認的帳戶名: config.json =>  adminAccount 這個字段的值
密碼: ymfe.org
複製代碼

-----而可能發生的錯誤,就是npm掛了------

在初始化的時候,執行

docker logs --details 容器ID

查看內部終端的執行過程,npm的一些源也不必定靠譜,

如果提示npm安裝報錯了,就須要進去換其餘源了

先啓動crper/yapi鏡像,而後跟着教程走

// npm config set registry [url]
// npm ---- https://registry.npmjs.org/
// cnpm --- http://r.cnpmjs.org/
// taobao - http://registry.npm.taobao.org/
// eu ----- http://registry.npmjs.eu/
// au ----- http://registry.npmjs.org.au/
// sl ----- http://npm.strongloop.com/
// nj ----- https://registry.nodejitsu.com/


// 進入到vendors目錄
// 如果有node_modules目錄,
// 咱們都應該先幹掉node_modules
// 這樣從新安裝依賴纔會比較乾淨

// 進到vendors目錄, 好比設置回官方源
npm config set registry https://registry.npmjs.org/;

// 安裝全局升級工具和依賴編譯的npm模塊
npm i -g node-gyp yapi-cli \
npm i --production;

// 初始化 yapi
node server/install.js

複製代碼

依賴安裝完成就能夠再從新初始化,而後重啓容器便可

進入容器操做

  • docker ps : 從這個看到你的鏡像運行容器的信息列表
  • docker exec -it 容器ID bash : 這句話就是非侵入式的進入容器內部,而且調用的shellbash,這個exit不會幹掉容器

docker attach這個命令慎用,會在終端退出的會把容器中止,這條命令是看狀況使用的!!!!

升級yapi

由於不涉及到容器處理..只是單純的文件替換,官方也提供了方案,那個cli已經默認集成到容器裏面

// https://yapi.ymfe.org/devops/index.html
cd  {項目目錄}
yapi ls //查看版本號列表
yapi update //升級到最新版本
yapi update -v v1.1.0 //升級到指定版本
複製代碼

升級完畢重啓node程序亦或者重啓容器便可!!

Github地址: yapi-docker

GUI管理數據庫

咱們暴露了27017端口,因此咱們宿主機能夠用工具連接到數據庫內部,

蘿蔔青菜各有所愛,效果圖

喜歡用命令行的也同樣

錯誤彙總

構建yapi過程發生的一些錯誤

  • /bin/sh: npm: not found , 構建的時候安裝nodejs-current-npm
  • usermod not found : 構建的時候安裝shadow
  • gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.
    • 這個是初始化yapi遇到的,須要補全python的基礎環境,構建的時候加入相關安裝包
  • mongodb無法訪問,就是當你配置文件設置127.0.0.1的時候..
    • docker中,容器名默認映射容器的訪問ip,因此config.json必須指定爲mongo的容器名(這個坑浪費了賊多的時間,國外的社區都蒐羅了一遍,基本都是說什麼--network這些)

還有一些錯誤忘記截圖收錄了

------------舒適提示------------

爲何看到的dockerfile用了大量的\來連接命令 ,

那是由於RUN一次是構建一個鏡像,再以此爲基礎傳遞給下面二次編排,

如果裏面大量的使用了RUN,那就至關於你這個鏡像從頭至尾要構建不少層(體積也會變大)...官方推薦是不超過七層!!

構建層目前最多不能超過127層!

對於--link來連接容器(互相訪問),這個docker官方已經不推薦了,屬於過期特性,新的網絡模式很健全,

提供了橋接,宿主,子網這些模式,可是這些並不適用於--link結合

因此,對於多容器的編排,更推薦用docker-compose來配置,可配置的東西賊多並且好維護,好比最新的3.6版本

傳送門: docs.docker.com/v17.09/comp…

總結

寫這文章各類截圖,復現過程(修改文件,打包,運行,調試依次重複)問題花了挺多時間(先後花了一週),

爲何會有這個教程, 感受能幫助挺多想試水docker的小夥伴,

所謂的"微服務"就是基於docker來實現的,保持容器功能的單一,方便維護測試

原本還想繼續寫基於docker-compose的版本,這樣文章的篇幅就太長了...抽空再寫一篇

docker-compose部署的書寫很優雅,配置一目瞭然,並且能夠作比較複雜的容器編排...

有人確定會提到Kubernetes,這貨很流行,有興趣的能夠去看看,通常都是作大廠運維纔會用到這貨

有不對之處亦或者改善的方案請及時留言,會及時修正和改善.感謝閱讀~~~

相關文章
相關標籤/搜索