什么是Docker
Docker 是一個開源的應用容器引擎,基於 Go 語言 並遵從 Apache2.0 協議開源。
Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然后發布到任何流行的 Linux 機器上,也可以實現虛擬化。
容器是完全使用沙箱機制,相互之間不會有任何接口(類似 iPhone 的 app),更重要的是容器性能開銷極低。
為什么要用Docker
為了線下線上環境一致,更方便的部署
大家一定經歷過環境配置的折磨
“明明在我這台機器上都可以運行,為什么跑你那去就出錯了?”
很大的可能環境不一致,如果線下更新了環境,那么服務器上也要更新一大堆。
為了減少這些痛苦,Dokcer提供了很好的解決方案:打包我們的應用以及依賴到Docker容器中,從而避免了環境不一致
Docker的一些概念
- 鏡像(Image):Docker 鏡像(Image),就相當於是一個 root 文件系統。比如官方鏡像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系統的 root 文件系統。
- 容器(Container):鏡像(Image)和容器(Container)的關系,就像是面向對象程序設計中的類和實例一樣,鏡像是靜態的定義,容器是鏡像運行時的實體。容器可以被創建、啟動、停止、刪除、暫停等。
- 倉庫(Repository):倉庫可看着一個代碼控制中心,用來保存鏡像。
安裝Docker
支持的平台:
DESKTOP
- Docker Desktop for Mac (macOS)
- Docker Desktop for Windows (Microsoft Windows 10)
SERVER
- CentOS
- Debian
- Fedora
- Ubuntu
Docker倉庫
我們搭建環境使用的鏡像都可以在上面的倉庫找到
在開發過程中如何使用Docker
接下來我們就使用一個最簡單的實例搭建一個基於koa的開發環境
開發環境使用的配置
Node
- node:12-alpine
- koa 基礎框架
- koa-router 路由
- promise-mysql mysql
- nodemon 自動重啟服務
Nginx
- nginx:1.17
Mysql
- mysql:5.6
目錄結構
- koa-docker
- conf
- data
- docker-compose.yml
- node_modules
- package.json
- server.js
- static
- yarn.lock
1.Node環境配置
要先安裝好本地的node環境,新建一個項目
所有操作命令都在項目根目錄中進行
本地環境為Linux Mint,和Win平台的某些命令不一致,可以適當修改
mkdir koa-docker
cd koa-docker
初始化項目
# 進入根目錄執行cmd命令,生成package.json
npm init -y
# 修改npm啟動腳本package.json
{
"scripts":{
"start":"nodemon server.js"
}
}
安裝node包
包管理工具yarn,或者npm,cnpm,隨意
yarn add koa koa-router promise-mysql nodemon
server服務
# server.js
const Koa = require('koa')
const Router = require('koa-router')
const mysql = require('promise-mysql')
let app = new Koa()
let router = new Router()
// 根路由
router.get('/', async ctx=>{
ctx.body = 'index'
})
// 測試mysql連接路由
router.get('/db', async ctx=>{
let db = await mysql.createPool({
host: 'mysql',
port: 3306,
user: 'root',
password: '123456'
})
let res = await db.query('SHOW DATABASES')
ctx.body = res
})
app.use(router.routes())
app.listen(3000)
docker-compose
Compose 是用於定義和運行多容器 Docker 應用程序的工具。通過 Compose,您可以使用 YML 文件來配置應用程序需要的所有服務。然后,使用一個命令,就可以從 YML 文件配置中創建並啟動所有服務。
配置docker-compose
如果我們只需要一個容器,可以用Dockerfile進行單獨配置,(當然每個容器都可以寫一個Dockerfile,然后docker-compose來build)
現在我們有多個容器需要管理
docker-compose.yml
根目錄新建docker-compose.yml文件
我們一步一步構建服務
version: "3"
services:
web:
image: node:12-alpine #node鏡像名稱
working_dir: /code #工作目錄
volumes: #掛載點
- .:/code #把本地當前目錄掛載到容器的/code目錄
ports: #端口映射
- "3000:3000" #本地端口:容器端口
command: npm start #這條命令會在工作目錄下執行
關於volumes掛載點:
由於容器刪除了數據也會刪除,我們把容器里的目錄掛載到本地目錄,容器掛載了的目錄有任何改變,都會保存到本地
我們現在只有一個web服務,先跑起來看看能否正確運行
docker-compose up
如果你訪問localhost:3000能夠顯示內容,說明容器正常運行起來了
2.Mysql配置
接着上面的配置,我們再添加一個mysql的配置
# docker-compose.yml
version: "3"
services:
...
mysql:
image: mysql:5.6
volumes:
- ./data:/var/lib/mysql #掛載當前的data目錄到容器默認mysql存儲目錄
environment: #環境變量
- MYSQL_ROOT_PASSWORD=123456 #mysql的root密碼
- MYSQL_DATABASE=koa_docker #mysql的初始化數據庫
ports:
- "3306:3306"
我們現在有2個服務,web和mysql,一次同時運行兩個服務
docker-compose up
不出意外,服務跑起來了,我們測試一下mysql是否能正常連接,訪問localhost:3000/db,如果能夠看到以下信息,說明mysql也正常連接了
[{"Database":"information_schema"},{"Database":"koa_docker"},{"Database":"mysql"},{"Database":"performance_schema"}]
3.Nginx配置
我們需要nginx的默認配置文件,先把一個nginx容器跑起來,復制容器里面的配置
運行一個nginx容器
docker run -itd --rm nginx:1.17
# -i 交互式操作
# -t 終端
# -d 后台運行
# --rm 容器停止后自動銷毀
我們會得到一個容器ID
35c5c3671780
也可以用docker ps查看運行的容器
復制容器里面的文件
# 復制nginx容器里的配置文件到當前目錄
docker cp 35c5c3671780:/etc/nginx/conf.d/default.conf .
default.conf配置文件
server {
listen 80;
server_name localhost;
location /static {
alias /code/static; #路徑可以自定義,放在什么目錄都可以
}
location / {
proxy_pass http://web:3000; #地址web是docker-compose.yml里面的web服務名
}
...
}
移動配置文件到conf文件夾
mv default.conf conf/
docker-compose.yml
version: "3"
services:
...
...
nginx:
image: nginx:1.17
volumes:
- ./static:/code/static
- ./conf/default.conf:/etc/nginx/conf.d/default.conf #掛在nginx服務的配置文件到容器里
ports:
- "80:80"
我們有一個配置文件的掛載點,用於更改默認配置,如果mysql也需要更改配置文件,也可以添加一個配置文件的掛載點(也可以是掛載一個配置目錄:./conf:/etc/nginx/conf.d)
讓我們一次跑3個服務,web,mysql,nginx,看看是否正確運行
docker-compose up
我們配置了nginx的代理,現在默認訪問端口為80,不用再寫端口號了
注意,如果本地安裝了nginx需要先停止本地nginx服務 systemctl stop nginx
- 訪問
localhost不帶端口號(默認80),是否正常 - 訪問
localhost/db數據庫是否連接正常 - 訪問
localhost/static/1.jpg測試static服務是否正常(靜態文件就放在本地目錄的static下)
總結
到此一個基於node的koa,nginx,mysql,開發環境就搭建完成,基於掛載點,開發調試也很方便
如果你本地修改了server.js里面的文件(隨便什么文件),nodemon會監聽文件變化,自動重啟服務
還有一個疑問,本地開發環境好了,是和線上環境一致的,那么怎樣部署到服務器呢?
我們下一篇見:Docker + node(koa) + nginx + mysql 線上環境部署
附錄
docker-compose.yml
version: "3"
services:
web:
image: node:12-alpine
working_dir: /code
volumes:
- .:/code
ports:
- "3000:3000"
command: npm start
mysql:
image: mysql:5.6
volumes:
- ./data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=koa_docker
ports:
- "3306:3306"
nginx:
image: nginx:1.17
volumes:
- ./static:/code/static
- ./conf/default.conf:/etc/nginx/conf.d/default.conf
ports:
- "80:80"
