在下最近遇到要在服務器上安裝 Mysql、Nginx、EasyMock 等工具的場景,這裏記錄一下我使用 Docker 安裝的過程,但願也能在相似的場景中幫助到你們~ html
本文前備知識須要一些 Linux 的一些基本命令,推介先看一下 <半小時搞會 CentOS 入門必備基礎知識> 這篇文章。前端
CentOS 版本: 7.6
mysql
Nginx 版本: 1.16.1
linux
Docker 版本: 19.03.12
nginx
你多學同樣本事,就少說一句求人的話
先後端開發到測試到生產的過程當中,常常會遇到一個問題,明明我在本地跑沒問題,爲何到測試環境或者生產環境就報錯了了呢,經常這是由於開發、測試、生產的環境與配置不一樣致使的。git
折騰過環境配置的人都明白其中麻煩,換一臺系統、虛擬機、機器,就又要重來一次,費力費時。因爲環境和配置的緣由,各類奇奇怪怪由於環境和配置的 Bug,老是像打地鼠遊戲裏面的地鼠同樣不斷冒出來 🐹github
Docker 對這個問題給出了一個很好的解決方案,經過鏡像將除了系統以外所須要的系統環境由下而上打包,達到服務跨平臺的無縫運做。也就是說,安裝的時候,把特定的環境如出一轍地搬過來,從而解決「在個人電腦上能跑,在 xx 環境就跑不了」的狀況。web
另一個重要的緣由,就是輕量,基於容器的虛擬化,Docker 的鏡像僅包含業務運行所需的 runtime 環境,一個 CentOS/Ubuntu 基礎鏡像僅 170M,由於輕量一個宿主機能夠輕鬆安裝數百個容器。redis
Docker 是基於 Go 語言實現的雲開源項目,從 2013 年發佈到如今一直廣受關注。Docker 可讓你像使用集裝箱同樣快速的組合成應用,而且能夠像運輸標準集裝箱同樣,儘量的屏蔽代碼層面的差別。它將應用程序與該程序的依賴,打包在一個文件裏面。運行這個文件,就會生成一個虛擬容器。sql
程序在這個虛擬容器裏運行,就好像在真實的物理機上運行同樣。有了 Docker,就不用擔憂環境問題。
本文就不對比虛擬機跟 Docker 的區別和優劣了,每一個文章都有,說爛了,想了解的話能夠百度一下 😂,我這裏就很少說了,下面直接看看怎麼安裝怎麼用起來吧。
在下直接使用 Homebrew Cask 來安裝,Mac 下:
# Homebrew 安裝 $ braw cask install docker
便可,安裝完輸入命令,直接報錯!
➜ ~ docker zsh: command not found: docker # 報錯
遇到這個報錯別擔憂,安裝完以後要在應用列表裏面雙擊 Docker 應用,輸入密碼以後就可使用這個命令了 😅。
Docker 要求 CentOS 版本必須在 6.5 及以上才能夠安裝。
# 安裝 $ sudo yum install yum-utils device-mapper-persistent-data lvm2 $ sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo $ sudo yum install docker-ce # 開啓 Docker $ sudo systemctl start docker
在 Windows 上能夠直接下載安裝包來安裝,或者 Mac 上不使用 Homebrew 也能夠去官網直接下載安裝包來安裝,百度一下處處都是安裝方法,其餘的就不用多說。
在 MacOS 的 Docker 配置 Perferences -> Docker Engine
或者 Windows 的 Settings -> Deamon
中的 JSON 中增長一項 registry-mirrors
以下
配置完以後在命令行中 docker info
就能夠查看到咱們配置的鏡像加速地址了。
➜ ~ sudo docker info ... Registry Mirrors: https://reg-mirror.qiniu.com/ http://hub-mirror.c.163.com/ https://registry.docker-cn.com/ ...
若是你的系統的 Docker 沒有客戶端,好比 CentOS 中,能夠直接修改 deamon 配置文件:
# 修改/建立 docker 的 deamon 配置文件 $ sudo vi /etc/docker/daemon.json # 修改成以下配置 { "experimental": false, "debug": true, "registry-mirrors": [ "https://reg-mirror.qiniu.com", "http://hub-mirror.c.163.com", "https://registry.docker-cn.com" ] } # 修改完 :wq 重啓 $ sudo systemctl restart docker
而後就能夠快樂跑起來咱們第一個 Docker 指令 Hello World 了
Good start ! 🎉
鏡像和容器的關係就像類和類的實例,一個鏡像能夠同時跑多個容器,單個容器實例又能夠建立新的鏡像。以下圖:
下面解釋一下這個圖裏面出現的元素
概念 | 說明 |
---|---|
Docker 鏡像 Images | 用於建立 Docker 容器的只讀模板,好比 Ubuntu 16.04系統、Nginx 1.16.0 等,是一個特殊的文件系統,包括容器運行時須要的程序、庫、資源、參數等,但不包含任何動態數據,內容在構建後也不會被改變,一個鏡像能夠建立多個容器 |
Docker 容器 Container | 容器是獨立運行、相互隔離的一個或一組應用,是鏡像建立的運行實例,實質是進程,能夠看做爲一個簡易版的 Linux 環境 + 運行在其中的應用程序 |
Docker 客戶端 Client | 客戶端經過命令行或者其餘工具使用 Docker SDK (https://docs.docker.com/devel... 與 Docker 的守護進程通訊 |
Docker 主機 Host | 一個物理或者虛擬的機器用於執行 Docker 守護進程和容器 |
Docker 倉庫 Repository | 集中存放鏡像文件的地方,分爲公有倉庫和私有倉庫。 |
Docker 註冊服務器 Registry | 是一個集中存儲、分發鏡像的服務,官方的叫 Docker Hub。一個 Docker Registry 中可包含多個倉庫,每一個倉庫能夠包含多個標籤 Tag 的鏡像,不一樣的標籤對應不一樣的版本 |
Docker Machine | Docker Machine 是一個簡化 Docker 安裝的命令行工具,經過一個簡單的命令行便可在相應的平臺上安裝Docker,好比 VirtualBox、 Digital Ocean、Microsoft Azure |
容器的生命週期圖示
容器的五個核心狀態,也就是圖中色塊表示的:Created、Running、Paused、Stopped、Deleted:
本文主要關注於使用,就不太贅述這些狀態的切換等,下面直接上手。
# 開啓 Docker 開機自啓動 $ sudo systemctl enable docker # 關閉 Docker 開機自啓動 $ sudo systemctl disable docker
# 去下載鏡像,先從本地找,沒有去鏡像,最後沒有去 hub,標籤不寫默認爲 lastest $ docker pull [鏡像名]:[標籤Tag] # 列出本機的全部 image 文件,-a 顯示本地全部鏡像(包括中間鏡像),-q 只顯示鏡像ID,--digests 顯示鏡像的摘要信息 $ docker image ls $ docker images # 刪除 image 文件, -f 強制刪除鏡像 $ docker rmi [鏡像名][:標籤Tag] $ docker rmi [鏡像名1][:標籤Tag] [鏡像名2][:標籤Tag] # 刪多個 $ docker rmi $(docker ps -a -q) # 刪所有,後面是子命令 # 查詢鏡像名稱,--no-trunc 顯示完整的鏡像描述,--filter=stars=30 列出star很多於指定值的鏡像,--filter=is-automated=true 列出自動構建類型的鏡像 $ docker search [關鍵字] # 下載鏡像,標籤 tag 不寫默認爲 lastest,也能夠本身加好比 :3.2.0 $ docker pull [鏡像名][:標籤Tag]
# 列出本機正在運行的容器,-a 列出本機全部容器包括終止運行的容器,-q 靜默模式只顯示容器編號,-l 顯示最近建立的容器 $ docker container ls # 等價於下面這個命令 $ docker ps # 新建並啓動容器 $ docker run [option] [容器名] # 啓動容器 $ docker start [容器ID]/[容器Names] # 重啓容器 $ docker restart [容器ID]/[容器Names] # 終止容器運行 $ docker kill [容器ID] # 強行終止,至關於向容器裏面的主進程發出 SIGKILL 信號,那些正在進行中的操做會所有丟失 $ docker kill $(docker ps -a -q) # 強行終止全部容器 $ docker stop [容器ID] # 從容終止,至關於向容器裏面的主進程發出 SIGTERM 信號,而後過一段時間再發出 SIGKILL 信號 $ docker stop $(docker ps -a -q) # 終止全部容器 # 終止運行的容器文件,依然會佔據硬盤空間,可使用 docker container rm 命令刪除,-f 強制刪除能夠刪除正在運行的容器 $ docker rm [容器ID] $ docker rm `docker ps -aq` # 刪除全部已經中止的容器,由於沒中止的rm刪不了須要加-f # 查看容器的輸出,-t加入時間戳,-f跟隨最新日誌打印,--tail數字顯示最後多少條,若是docker run時,沒有使用-it,就要用這個命令查看輸出 $ docker logs [容器ID] # 查看容器進程信息 $ docker top [容器ID]/[容器Names] $ docker port [容器ID]/[容器Names] # 退出容器 $ exit # 容器退出 ctrl + p + q # 容器退出,快捷鍵 # 進入容器 $ docker attach [容器ID] # 退出容器時會讓容器中止,本機的輸入直接輸到容器中 $ docker exec -it [容器ID] # 退出容器時不會讓容器中止,在已運行的容器中執行命令,不建立和啓動新的容器 # 設置容器在docker啓動時自動啓動 $ docker container update --restart=always [容器名字]
這裏要特別說一下 docker run
的 option
,由於最經常使用:
--name
爲容器指定一個名稱;-d
容器啓動後進入後臺,並返回容器 ID,即啓動守護式容器;-P
隨機端口映射;-p 80:8080
將本地 80 端口映射到容器的 8080 端口;bash
容器啓動之後,內部第一個執行的命令。這裏啓動 bash,保證用戶可使用 Shell;-i
以交互模式運行容器,一般與 -t
同時使用;-t
爲容器從新分配一個僞輸入終端,容器的 Shell 會映射到當前的 Shell,而後在本機窗口輸入的命令,就會傳入容器,一般與 -i
同時使用;--rm
在容器終止運行後自動刪除容器文件;--restart=always
設置容器自啓動;-v /xxx:/yyy
映射命令,把本機的 xxx 目錄映射到容器中的 yyy 目錄,也就是說改變本機的 xxx 目錄下的內容, 容器 yyy 目錄中的內容也會改變;好比我在 CentOS 下跑起來一個 CentOS 的 Docker 容器:
# 下載 $ docker pull centos # 在上面下載的 centos 鏡像基礎上,新建一個容器名爲 mycentos0901 的 centos 實例,並進入這個容器的 bash $ docker run -it --name mycentos0901 0d120b6ccaa8 [root@169c9fffeecd /] # 進入容器,下面輸入命令,注意這裏 root 後面的一串 ID $ ls # 能夠看到centos的根目錄文件列表 $ docker # bash: docker: command not found 這個容器沒有安裝docker
是否是很神奇,咱們能夠在一開始的 CentOS 下面執行 docker ps
來查看容器列表:
你會發現上面那個 ID,正是下面列表中跑起來的這個容器的 ID,鏡像的 ID 也是咱們前面 pull
下來的 CentOS 鏡像 ID,名字也是咱們起的 mycentos0901
。
若是 docker run
以後報 Conflict. The container name "xxxx" is already in use by container
就直接運行 docker rm $(docker ps -a -q)
刪除已中止的容器,或者精確刪除 docker rm [containerID]
也能夠,就能夠了。
使用 centos
之後臺模式啓動一個容器 docker run -d --name mycentos0903 0d120b6ccaa8
,啓動以後 docker ps -a
查看,發現容器並不在運行中,這是由於 Docker 的運行機制:Docker 容器後臺運行,必須有一個前臺進程。
容器運行的命令若是不是那些一直掛起的命令,好比 top
、tail
,運行結束會自動退出。因此爲了讓容器持續在後臺運行,那麼須要將運行的程序之前臺進程的形式運行。
好比這裏在後臺運行一個命令,這個命令一直在打印 docker run -d centos /bin/sh -c "while true; do echo hello zzyy; sleep 2; done"
,而後咱們 logs
查看一下:
退出容器後能夠經過 exec
方法對正在運行的容器進行操做:
拷貝文件使用 cp
命令
$ docker cp [容器ID]/[容器Names]:[要拷貝的文件目錄] [本機目錄] # 容器文件拷貝到本機 $ docker cp [本機目錄] [容器ID]/[容器Names]:[要拷貝的文件目錄] # 本機文件拷貝到容器
cp
不只能把容器中的文件/文件夾拷貝到本機,也能夠把本機中的文件/文件夾拷貝到容器。
演示一下,這裏先到容器裏面建立一個無聊的文件 xixi.txt
,而後拷貝到本機:
實用的時候,咱們能夠拷貝配置、日誌等文件到本地。
# 查詢鏡像 $ docker search mysql # 下載鏡像,實測沒配置鏡像加速的時候會比較慢,配置了就好一些 $ docker pull mysql # 查看鏡像 $ docker images # 建立並運行容器 $ docker run -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=888888 -v /Users/sherlocked93/Personal/configs/mysql.d:/etc/mysql/conf.d --name localhost-mysql mysql
稍微解釋一下上面的參數:
-p 3307:3306
將本機的 3307 端口映射到 mysql 容器的 3306 端口,根據須要自行更改;-e MYSQL_ROOT_PASSWORD=<string>
設置遠程登陸的 root 用戶密碼;--name <string>
可選,設置容器別名;-v xxx/mysql.d:/etc/mysql/conf.d
將本地目錄下設置文件夾映射到容器的 /etc/mysql/conf.d
-v xxx/logs:/logs
將本機指定目錄下的 logs
目錄掛載到容器的 /logs
-v xxx/data:/var/lib/mysql
將主機制定目錄下的 data
目錄掛載到容器的 /var/lib/mysql
運行截圖:
而後去 Navicat 中就能夠鏈接到 MySQL 了。
這也太爽了!真的是幾行命令就裝好了啊,比以前真是快樂多了 😂
Nginx 的安裝和其餘的相似,若是你還不太瞭解 Nginx 如何使用,能夠參看 <Nginx 從入門到實踐,萬字詳解> 這篇文章,看完基本就瞭解如何使用和配置了。
# 查詢/下載鏡像 $ docker search nginx $ docker pull nginx
而後建立一個臨時的容器,目的是把默認配置拷貝到本機,我這裏把配置文件放到 /mnt
目錄下,主要是三個配置文件夾:
/etc/nginx
放置 Nginx 配置文件;/var/log/nginx/
放置 Nginx 日誌文件;/usr/share/nginx/html/
放置 Nginx 前端靜態文件都放在這個文件夾;分別把這幾個目錄都拷貝到本機的 /mnt
文件夾下的 nginx
、nginx_logs
、html
文件夾。
剛剛建立的臨時容器沒用了 docker rm -f [臨時容器ID]
把臨時容器幹掉,而後 docker run
從新建立 Nginx 容器:
$ docker run -d --name localhost-nginx -p 8082:80 \ -v /mnt/nginx:/etc/nginx \ -v /mnt/nginx_logs:/var/log/nginx \ -v /mnt/html:/usr/share/nginx/html \ --privileged=true nginx
--privileged=true
表示容器內部對掛載的目錄擁有讀寫等特權。
其餘配置剛剛上面以前已經講過,應該不用講了。
而後在你本身瀏覽器上就能夠訪問了,若是是雲服務器,記得開放對應端口。
由於 Easy Mock 依賴 Redis 和 MongoDB,所以本地環境使用 docker-compose 來搭建 Easy Mock 應該算是最佳實踐了。
官方文檔: https://docs.docker.com/compose/install/
首先你得肯定擁有 docker 環境,若是你是 Windows / Mac 用戶,那麼安裝客戶端,就會自帶 docker-compose 了。
由於本次咱們是在雲服務器 CentOS7.6 上搭建,因此咱們須要自行安裝 docker-compose,運行以下命令,下載當前穩定版本的 docker-compose
$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
修改文件權限爲可執行文件
$ sudo chmod +x /usr/local/bin/docker-compose
驗證是否安裝成功
$ docker-compose version
能夠參考官方文檔給出的部署文檔,也能夠參考我下面的配置過程。
首先新建文件 docker-compose.yml
並將下面 docker-compose 文件內容複製進入 docker-compose.yml
,而後將內容中註釋位置替換爲本身須要的本地地址
version: '3' services: mongodb: image: mongo:3.4.1 volumes: # /apps/easy-mock/data/db 是數據庫文件存放地址,根據須要修改成本地地址 - '/apps/easy-mock/data/db:/data/db' networks: - easy-mock restart: always redis: image: redis:4.0.6 command: redis-server --appendonly yes volumes: # /apps/easy-mock/data/redis 是 redis 數據文件存放地址,根據須要修改成本地地址 - '/apps/easy-mock/data/redis:/data' networks: - easy-mock restart: always web: image: easymock/easymock:1.6.0 # easy-mock 官方給出的文件,這裏是 npm start,這裏修改成 npm run dev command: /bin/bash -c "npm run dev:server" ports: - 7300:7300 # 改成你本身指望的映射 volumes: # 日誌地址,根據須要修改成本地地址 - '/apps/easy-mock/logs:/home/easy-mock/easy-mock/logs' networks: - easy-mock restart: always networks: easy-mock:
在 docker-compose 文件目錄下,運行以下命令:
$ docker-compose up -d
若是遇到 easymock docker 實例報文件權限錯誤
Error: EACCES: permission denied....
要在項目根目錄執行如下命令
$ chmod 777 /yourfile/logs
而後就能夠經過瀏覽器上的 你的域名.com:7300
訪問到 easy-mock 了!
若是你以爲域名後面跟着端口號挺難看的,你能夠經過配置 Nginx 的二級域名來訪問你部署的 easy-mock,配置二級域名的方法參見 這篇文章
關於可視化查詢工具,這裏就簡單推介一個 LazyDocker,因爲是在終端運行的,並且支持鍵盤操做和鼠標點擊,就挺騷氣的,有了這個一些查詢語句能夠少打幾回了。
安裝比較簡單,運行下面的命令:
$ docker run --rm -it -v \ /var/run/docker.sock:/var/run/docker.sock \ -v ~/.config/lazydocker:/.config/jesseduffield/lazydocker \ lazyteam/lazydocker
能夠設置一個終端的 alias
$ alias lzd='docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v ~/.config/lazydocker:/.config/jesseduffield/lazydocker lazyteam/lazydocker'
而後你在終端輸入 lzd
就能夠瀏覽你的鏡像、容器、日誌、配置、狀態等等內容了。
因爲在下目前使用 Docker 的主要場景是 MySQL、Nginx 之類工具的安裝,因此本文所介紹的內容也大多屬於這個場景。
篇幅緣由 Docker 還有一些內容本文沒有介紹,但上面的內容已基本知足平常的使用,其餘 Docker 的內容能夠關注一下在下的後續文章~
網上的帖子大多深淺不一,甚至有些先後矛盾,在下的文章都是學習過程當中的總結,若是發現錯誤,歡迎留言指出~
參考文檔:
做者其餘高贊文章:
PS:本人博客地址 Github - SHERlocked93/blog,也歡迎你們關注個人公衆號【前端下午茶】,一塊兒加油吧~