本文是我經過三個星期業餘時間學習後而寫的文章,對docker的瞭解還處於入門階段。但願本文能幫忙一些想學習docker的朋友快速入門。練習及實戰代碼都在github倉庫中。若是個人文章能幫助到你的話,能夠給個人docker項目點個贊哦javascript
本次實戰案例是todolist。技術棧爲vue、node、mysql。具體代碼見項目目錄todolist,下面就不一一貼代碼了。就講下重點。html
下面我就順着依賴關係來說,因此先從mysql開始講起vue
執行:docker run --name mymysql -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
java
在執行該語句以前,假如你以前沒有pull過mysql鏡像。docker在本地找不到你要的鏡像就會幫你從docker倉庫拉取mysql:latest鏡像。node
這個時候容器就啓動成功了。mysql
嘗試下用navicat鏈接下試試git
鼠標放入黃色小三角出現以下報錯。github
2013 - Lost connection to MySQL server at 'reading initial communication packet', system error: 0 "Internal error/check (Not system error)"
這是由於mysql8以上,都會使用新的驗證方式。sql
不妨查下信息: select host,user,plugin,authentication_string from mysql.user;
vue-cli
mysql> select host,user,plugin,authentication_string from mysql.user; +-----------+------------------+-----------------------+------------------------------------------------------------------------+ | host | user | plugin | authentication_string | +-----------+------------------+-----------------------+------------------------------------------------------------------------+ | % | root | caching_sha2_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | | localhost | mysql.infoschema | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.session | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | | localhost | mysql.sys | caching_sha2_password | $A$005$THISISACOMBINATIONOFINVALIDSALTANDPASSWORDTHATMUSTNEVERBRBEUSED | )7k44VulAglQJgGpvgSG.ylA/rdbkqWjiqQJiq3DGsug5HIy3 |ord | $A$005$0pU+sGm[on +-----------+------------------+-----------------------+------------------------------------------------------------------------+
plugin一欄可看到都是caching_sha2_password。
那麼如何才能將其改爲可鏈接的呢?只須要將其plugin改爲mysql_native_password就能夠訪問了。
ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
你能夠先用上面查詢帳戶信息查下是否修改爲功了。
修改爲功後,能夠嘗試下用navicat鏈接下mysql。不出意外的話就能成功鏈接上了。
固然我下面的例子用mysql:5.6,方便操做,不須要修改plugin。
執行命令:docker run --name mymysql -d -e MYSQL_ROOT_PASSWORD=123456 -p 3308:3306 mysql:5.6
啓動容器後能夠執行:docker exec -it mymysql bash
進入容器
執行:mysql -uroot -p123456
進入mysql控制檯
執行:show databases;
查看mysql數據庫
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ 3 rows in set (0.00 sec)
執行:create database todolist;
建立todolist應用的數據庫
執行:show databases;
查看剛剛建立的todolist數據庫
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | todolist | +--------------------+ 4 rows in set (0.00 sec)
能夠看到數據庫中多了個todolist數據庫
接下來選擇該todolist數據庫
執行:use todolist;
選中該數據庫
建立表:
CREATE TABLE list ( id INT(11) AUTO_INCREMENT PRIMARY KEY, text VARCHAR(255), checked INT(11) DEFAULT 0 );
執行:show tables;
查看todolist數據庫下的表
mysql> show tables; +--------------------+ | Tables_in_todolist | +--------------------+ | list | +--------------------+ 1 row in set (0.00 sec)
執行:describe list;
查看錶
mysql> describe list; +---------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | text | varchar(255) | YES | | NULL | | | checked | int(11) | YES | | 0 | | +---------+--------------+------+-----+---------+----------------+ 3 rows in set (0.01 sec)
執行:insert into list set checked = 0, text = 'haha';
往表中插入一條數據;
執行:select * from list;
mysql> select * from list; +----+------+---------+ | id | text | checked | +----+------+---------+ | 1 | haha | 0 | +----+------+---------+ 1 row in set (0.01 sec)
一切正常
mysql服務啓動好了,接下來就是啓動node服務,並鏈接剛啓動的mysql服務了。
話很少說,直接上代碼,解釋看註釋
// index.js const mysql = require('mysql'); // mysql包 const express = require('express'); const app = express(); const bodyParser = require('body-parser'); // post請求須要引入的包 app.use(bodyParser.json()); // mysql配置(用於鏈接剛啓動的mysql服務) const opt = { host: 'localhost', user: 'root', port: '3308', password: '123456', database: 'todolist' }; const connection = mysql.createConnection(opt); const sqlFn = (sql) => { return new Promise((resolve, reject) => { connection.query(sql, (err, results, filelds) => { if (err) throw err; resolve(results); }); }) } connection.connect(async (err) => { if (err) throw err; console.log('mysql connncted success!'); }) // todolist 列表查詢 app.get('/getList', async (req, res) => { const sql = `SELECT * FROM list`; const data = await sqlFn(sql); res.json({ code: 0, data, message: 'success' }) }) // todolist 插入數據 app.post('/insert', async (req, res) => { const sql = `INSERT INTO list SET checked = ${req.body.checked}, text = '${req.body.text}'`; const data = await sqlFn(sql); res.json({ code: 0, data, message: 'success' }) }) app.listen(3000);
執行: node index.js
後,控制檯輸入
➜ server git:(master) ✗ node index.js mysql connncted success!
表示node服務鏈接mysql服務成功;
瀏覽器能夠訪問下localhost:3000/getList
{"code":0,"data":[{"id":1,"text":"haha","checked":0}],"message":"success"}
頁面將會出現剛纔咱們sql插入到數據庫的數據
既然代碼沒有問題,那麼咱們接下來就把他構建成鏡像。
構建以前須要把代碼中opt的host localhost改成本身主機的ip。由於容器啓動的話,鏈接mysql須要經過主機的3308端口訪問。
在當前文件夾新建名爲Dockerfile的文件
# 基於最新的 node 鏡像 FROM node:8 # 複製當前目錄下全部文件到目標鏡像 /app/ 目錄下 COPY . /todolist/server # 修改工做目錄 WORKDIR /todolist/server # 安裝依賴 RUN ["npm", "install"] # 啓動 node server ENTRYPOINT ["node", "index.js"]
執行:docker build -t mynode .
,生成node鏡像
可經過docker images
查看本地的鏡像。
➜ server git:(master) ✗ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mynode latest 3e8de2825063 4 seconds ago 898MB
能夠看到第一個鏡像就是咱們剛剛構建的鏡像
➜ server git:(master) ✗ docker images REPOSITORY TAG IMAGE ID CREATED SIZE mynode latest 3e8de2825063 4 seconds ago 898MB
接下來運行基於這個鏡像的容器
執行:docker run --name mynode -d -p 4000:3000 mynode
啓動成功後,訪問下localhost:4000/getList
{"code":0,"data":[{"id":1,"text":"haha","checked":0}],"message":"success"}
能夠看到頁面輸出咱們上面執行sql語句插入的數據
上面貼的代碼只是基礎的查看列表與插入數據兩個方法,其餘的請參考server
todolist的靜態頁面,我是經過vue-cli3搭建的。
執行vue create app
建立項目。
進入項目根目錄執行npm run serve
頁面是否正常執行。
而後編寫簡易的具備增刪改查的todolist應用。具體代碼見todolist。
注意vue.config.js中的devServer配置的target: 'http://127.0.0.1:4000'代理到咱們剛啓動的node容器
頁面啓動成功後,訪問localhost:8080
能夠看到頁面加載成功,列表也成功渲染出上面構建mysql時,sql插入的數據。
本地啓動靜態並請求服務端成功後,接下來也將靜態頁面打包成鏡像,而後啓動靜態頁面容器
在打包鏡像容器以前,記得先將vue.config.js中的devServer配置的target: 'http://<主機ip地址>:4000'代理到咱們剛啓動的node容器
編寫Dockerfile
# 基於最新的 node 鏡像 FROM node:8 # 複製當前目錄下全部文件到目標鏡像 /app/ 目錄下 COPY . /todolist/app # 修改工做目錄 WORKDIR /todolist/app RUN npm config set registry https://registry.npm.taobao.org && npm install # RUN ["npm", "install"] # 啓動 node server ENTRYPOINT ["npm", "run", "serve"]
cd到靜態頁面的根目錄執行: docker build -t static .
執行:docker run --name static -d -p 9000:8080 static
啓動靜態容器
打開瀏覽器訪問localhost:9000
,能夠看到頁面成功渲染出列表頁。
至此,mysql、node、vue容器均已互通。代碼須要完善的地方詳見todolist
咱們不可能每次部署一個應用,須要手動啓動好幾個服務。這個時候就須要使用docker-compose
關於命令就不介紹了,這裏貼下連接
docker-compose命令
在根目錄下新建docker-compose.yml
配置文件
version: '2' services: static: build: ./app/ container_name: static ports: - 7001:8080 depends_on: - nodejs - db nodejs: build: context: ./server/ dockerfile: sleep-dockerfile container_name: nodejs ports: - 4000:3000 environment: - IS_START_BY_COMPOSE=1 command: sh ./sleep.sh depends_on: - db db: image: mysql:5.6 container_name: db environment: MYSQL_ROOT_PASSWORD: "123456" command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4
具體配置,詳見上面貼的連接。下面我介紹下我所寫的配置
接下來解釋下上面用compose啓動的服務
值得一提的是,mysql的Dockerfile中作了建立數據庫與表的操做。會涉及到關閉數據庫密碼登陸功能。由於關閉以後,操做數據庫就不須要輸入密碼了。等表建完以後在恢復密碼。
nodejs中的sleep.sh腳本是由於depends_on這個依賴只是單純的等待其餘服務開始啓動,並非等待依賴的服務啓動完成以後纔開始構建自身的服務。這個時候node初始化會在mysql啓動完成以前啓動。這樣的話,node啓動的時候鏈接mysql就會報錯,致使node服務掛掉。因此引用了sleep.sh,讓node延遲一段時間啓動。
最後在docker-compose
文件所在的目錄下執行docker-compose build
再執行:docker-compose up
就能夠啓動todolist這個應用的全部服務了。