docker-compose實現(xiàn)容器任務(wù)編排的方法步驟
項目開發(fā)中,往往都需要啟動多個容器,容器之間又相互依賴,存在著啟動的順序。docker-compose就是可以通過命令控制依次啟動容器。
容器編排工具可以幫助我們批量地創(chuàng)建、調(diào)度和管理容器,幫助我們解決規(guī)?;萜鞯牟渴饐栴}。
Docker 三種常用的編排工具:Docker Compose、Docker Swarm 和 Kubernetes。
本文主要是使用 docker-compose 實現(xiàn)react【nginx】、express【node】、mysql【mysql】搭建項目前端通過express訪問mysql數(shù)據(jù)庫的功能。

項目目錄結(jié)構(gòu)
. ├── docker-compose.yml ├── express-mysql │ ├── app.js │ ├── bin │ ├── Dockerfile │ ├── node_modules │ ├── package.json │ ├── public │ ├── routes │ ├── src │ ├── views │ └── yarn.lock ├── init.sql ├── react-express │ ├── Dockerfile │ ├── Dockerfile.build │ ├── node_modules │ ├── package.json │ ├── public │ ├── react-express.conf │ ├── src │ └── yarn.lock └── start.sh
創(chuàng)建前端項目
使用 [create-react-app](https://create-react-app.bootcss.com/) 搭建前端項目,并安裝axios插件,進(jìn)行數(shù)據(jù)的調(diào)用。
npx create-react-app react-express cd react-express yarn add axios npm start
調(diào)整首頁內(nèi)容
下載好項目,修改src/App.js的內(nèi)容,實現(xiàn)可以請求后端接口返回的數(shù)據(jù)。
import "./App.css";
import { useState, useEffect } from "react";
import axios from "axios";
function App() {
const [user, setUser] = useState([]);
useEffect(() => {
axios.get("http://localhost:8088/sql").then((res) => {
setUser(res.data);
});
}, []);
return (
<div className="App">
<header className="App-header">
{user.map((u, i) => (
<p key={i}> {u.username}</p>
))}
</header>
</div>
);
}
export default App;
添加Dockerfile文件
使用Dockerfile構(gòu)建前端鏡像。
FROM nginx COPY ./build /usr/share/nginx/html COPY ./react-express.conf /etc/nginx/conf.d WORKDIR /usr/share/nginx/html EXPOSE 80 # 啟動ngnix CMD ["nginx", "-g", "daemon off;"]
添加.dockerignore文件,排除不需要打包到docker鏡像的文件
node_modules # testing /coverage # misc .DS_Store .env.local .env.development.local .env.test.local .env.production.local npm-debug.log* yarn-debug.log* yarn-error.log*
添加nginx配置文件
添加react-express.conf文件
server {
listen 80;
server_name localhost; # 如 www.baidu.com
root /usr/share/nginx/html; # 指向打包后的目錄
location / {
index index.html;
}
}
生成前端鏡像
只需要將編譯后的build文件添加到docker鏡像中,生成鏡像前,先執(zhí)行下 npm run build。
npm run build docker build -t react-express .
可以看到成功生成react-express鏡像。并暴露端口為80,該鏡像為后面執(zhí)行docker-compose做準(zhǔn)備。
創(chuàng)建后端項目
首先確保本地安裝express;
npm install -g express
使用[express-generator](https://www.expressjs.com.cn/starter/generator.html)生成器生產(chǎn)express-mysql項目
mkdir express-mysql cd express-mysql npx express-generator
下載完成后,目錄結(jié)構(gòu)如下:
. ├── Dockerfile ├── app.js ├── bin │ └── www ├── package.json ├── public │ ├── images │ ├── javascripts │ └── stylesheets ├── routes │ ├── index.js │ └── users.js ├── views │ ├── error.jade │ ├── index.jade │ └── layout.jade └── yarn.lock
為了連接mysql數(shù)據(jù)庫,新增src目錄結(jié)構(gòu)
. ├── Dockerfile ├── app.js ├── bin │ └── www ├── package.json ├── public │ ├── images │ ├── javascripts │ └── stylesheets ├── routes │ ├── index.js │ └── users.js + ├── src + │ ├── config.js + │ ├── db.js ├── views │ ├── error.jade │ ├── index.jade │ └── layout.jade └── yarn.lock
修改app.js設(shè)置跨域
// 在路由調(diào)用之前設(shè)置
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By",' 3.2.1')
res.header("Content-Type", "application/json;charset=utf-8");
next();
});
// ...
連接mysql的配置
src/config.js文件
module.exports = {
port: 3333, // express 服務(wù)啟動端口
/* 數(shù)據(jù)庫相關(guān)配置 */
db: {
host: 'localhost', // 主機(jī)名
port: 8808, // MySQL 默認(rèn)端口為 3306
user: 'root', // 使用 root 用戶登入 MySQL
password: '123456', // MySQL 密碼,用你自己的
database: 'blog', // 使用數(shù)據(jù)庫
useConnectionPooling: true, // 使用連接池進(jìn)行連接,否則過一會node連接的mysql就會斷開,出現(xiàn)錯誤
connectionLimit: 50,
queueLimit: 0,
waitForConnection: true
}
}
src/db.js文件內(nèi)容
const mysql = require("mysql");
// 獲取數(shù)據(jù)庫配置信息
const config = require("./config").db;
//創(chuàng)建一個mysql連接對象
let connection;
function handleError(err) {
if (err) {
// 如果是連接斷開,自動重新連接
if (err.code === "PROTOCOL_CONNECTION_LOST") {
connect();
} else {
console.error(err.stack || err);
}
}
}
// 連接數(shù)據(jù)庫
function connect() {
console.log("連接數(shù)據(jù)庫 connect");
//創(chuàng)建一個mysql連接對象
connection = mysql.createPool(config);
connection.getConnection(handleError);
connection.on("error", handleError);
}
connect();
module.exports = connection;
進(jìn)行sql查詢
在routes/index.js下設(shè)置sql查詢
var express = require("express");
var router = express.Router();
const connection = require("../src/db");
/* GET home page. */
router.get("/sql", function (req, res, next) {
/* 使用 connection.query 來執(zhí)行 sql 語句 */
// 第一個參數(shù)為 sql 語句,可以透過 js 自由組合
// 第二個參數(shù)為回調(diào)函數(shù),err 表示查詢異常、第二個參數(shù)則為查詢結(jié)果(這里的查詢結(jié)果為多個用戶行)
connection.query("select username from user", (err, users) => {
if (err) {
res.send("query error"+ err);
} else {
// 將 MySQL 查詢結(jié)果作為路由返回值
res.send(users);
}
});
});
module.exports = router;
構(gòu)建后端鏡像
新建Dockerfile文件
FROM node:16.11.0 COPY ./ /app WORKDIR /app RUN npm config set registry https://registry.npm.taobao.org && npm install EXPOSE 3000 CMD npm start
新建.dockerignore文件
node_modules *.lock *.log yarn-error.log package-lock.json
在當(dāng)前目錄下,執(zhí)行docker構(gòu)建鏡像的命令,測試下是否有問題。
docker build -t express-mysql .
初始化數(shù)據(jù)庫
創(chuàng)建sql腳本,在容器啟動后給mysql容器初始化數(shù)據(jù)?!境跏蓟瘮?shù)據(jù)有很多其它方案,可以在創(chuàng)建鏡像時通過修改配置將初始化數(shù)據(jù)存入鏡像,有興趣可自行搜索】,在這里只使用簡單的手動處理方案,降低認(rèn)知難度。
DROP TABLE IF EXISTS `user`;
create table user
(
id bigint auto_increment
primary key,
username varchar(255) not null
)
collate = utf8mb4_unicode_ci;
INSERT INTO blog.user (id, username) VALUES (1, 'admin');
INSERT INTO blog.user (id, username) VALUES (2, 'docker');
創(chuàng)建 mysql容器
docker run -d --name mysql-user -p 8087:3306 \ -v /data/docker-data/docker_mysql/conf:/etc/mysql/conf.d \ -v /data/docker-data/docker_mysql/logs:/logs \ -v /data/docker-data/docker_mysql/data:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=123456 \ mysql:5.7
登錄mysql并初始化數(shù)據(jù)
mysql -hlocalhost -P8087 -uroot -p123456 <<EOFuse blog;source /data/compose/init.sql;quitEOF
mysql -hlocalhost -P8087 -uroot -p123456 <<EOF use blog; source /data/compose/init.sql; quit EOF
docker-compose編排容器
到目前已經(jīng)完成了前端、后端、數(shù)據(jù)庫的創(chuàng)建,項目執(zhí)行依賴多個容器啟動,上面的過程非常繁瑣,而且容易出現(xiàn)錯誤。接下來就使用docker-compose可以使用一個命令將3個容器同時啟動。
安裝[docker-compose](https://docs.docker.com/compose/)
安裝完成后查看版本信息
docker-compose version --- docker-compose version 1.29.2, build unknown docker-py version: 5.0.3 CPython version: 3.6.8 OpenSSL version: OpenSSL 1.0.2k-fips 26 Jan 2017
新建yml文件
docker-compose.yml是docker-compose啟動的默認(rèn)文件
version: "3.1"
services:
react:
build:
context: "./react-express"
dockerfile: Dockerfile
depends_on:
- express
ports:
- "8086:80"
mysql:
image: mysql:5.7
container_name: mysql5
ports:
- "8087:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: "blog"
volumes:
- "/data/docker-data/docker_mysql/conf:/etc/mysql/conf.d"
- "/data/docker-data/docker_mysql/logs:/logs"
- "/data/docker-data/docker_mysql/data:/var/lib/mysql"
express:
build:
context: "./express-mysql"
dockerfile: Dockerfile
ports:
- "8088:3000"
depends_on:
- mysql
設(shè)置完成 yml 文件,執(zhí)行啟動命令
docker-compose up # 或者 后臺啟動 docker-compose up -d
docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------------------------
compose_express_1 docker-entrypoint.sh /bin/ ... Up 0.0.0.0:8088->3000/tcp,:::8088->3000/tcp
compose_react_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:8086->80/tcp,:::8086->80/tcp
mysql5 docker-entrypoint.sh mysqld Up 0.0.0.0:8087->3306/tcp,:::8087->3306/tcp, 33060/tcp
一個命令就可以啟動多個容器,并且組織好容器之間的依賴關(guān)系。
繼續(xù)優(yōu)化
創(chuàng)建前端鏡像存在的問題.
每次打包前端鏡像時,需要先完成 build 的階段,也就是前端編譯的過程。該過程其實也可以自動處理。
方案1:使用shell執(zhí)行
在項目目錄下創(chuàng)建 start.sh 文件, 將前端編譯的過程放到外部node環(huán)境【jenkins、或者服務(wù)器】執(zhí)行。
#!/bin/bash cd react-express yarn run build cd .. docker-compose up -d mysql -hlocalhost -P8087 -uroot -p123456 <<EOF use blog; source ./init.sql; quit EOF
方案2:采用鏡像多階段構(gòu)建
思路:將編譯過程放到node環(huán)境中,打包出來build目錄,然后將build目錄拷貝到后邊鏡像內(nèi)。
新建一個Dockerfile.build文件。
# 第一階段,先對前端項目進(jìn)行編譯打包 FROM node:16.11.0 AS nodeapp COPY ./ /app WORKDIR /app RUN yarn && yarn build #多階段構(gòu)建,最終會以最后的鏡像作為基礎(chǔ)鏡像 # 第二階段,將打包的數(shù)據(jù)拷貝到后邊鏡像內(nèi),并創(chuàng)建nginx鏡像 FROM nginx COPY --from=nodeapp /app/build /usr/share/nginx/html COPY ./react-express.conf /etc/nginx/conf.d WORKDIR /usr/share/nginx/html EXPOSE 80 # 啟動ngnix CMD ["nginx", "-g", "daemon off;"]
然后同步修改下docker-compose.yml文件
version: "3.1"
services:
react:
build:
context: "./react-express"
dockerfile: Dockerfile.build
depends_on:
- express
ports:
- "8086:80"
mysql:
image: mysql:5.7
container_name: mysql5
ports:
- "8087:3306"
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: "blog"
volumes:
- "/data/docker-data/docker_mysql/conf:/etc/mysql/conf.d"
- "/data/docker-data/docker_mysql/logs:/logs"
- "/data/docker-data/docker_mysql/data:/var/lib/mysql"
express:
build:
context: "./express-mysql"
dockerfile: Dockerfile
ports:
- "8088:3000"
depends_on:
- mysql
到此這篇關(guān)于docker-compose實現(xiàn)容器任務(wù)編排的方法步驟的文章就介紹到這了,更多相關(guān)docker-compose 容器任務(wù)編排內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用?trap?在?docker?容器優(yōu)雅關(guān)閉前執(zhí)行環(huán)境清理的方案
這篇文章主要介紹了利用?trap?在?docker?容器優(yōu)雅關(guān)閉前執(zhí)行環(huán)境清理的問題,需要在容器的啟動腳本中,加入 trap 指令,來完成容器在退出前需要做的所有事情,本文通過腳本示例給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-12-12
Docker中優(yōu)化Mysql運(yùn)行內(nèi)存的操作
這篇文章主要介紹了Docker當(dāng)中優(yōu)化Mysql運(yùn)行內(nèi)存的操作,經(jīng)過一番操作可以優(yōu)化為只占用100mb內(nèi)存,具體優(yōu)化方法及技巧跟隨小編一起看看吧2022-01-01
Docker容器內(nèi)部無法訪問外網(wǎng)原因以及解決辦法
最近在工作時遇到一個問題,這里給大家總結(jié)下,這篇文章主要給大家介紹了關(guān)于Docker容器內(nèi)部無法訪問外網(wǎng)原因以及解決辦法,文中給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
Docker部署nginx并修改配置文件的實現(xiàn)方法
這篇文章主要介紹了Docker部署nginx并修改配置文件的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
使用Nexus創(chuàng)建Docker倉庫的方法步驟
這篇文章主要介紹了使用Nexus創(chuàng)建Docker倉庫的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
解決docker容器中出現(xiàn)Access denied for user &apo
這篇文章主要介紹了解決docker容器中出現(xiàn)Access denied for user 'root'@'172.17.0.2'(using password: YES)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
docker容器環(huán)境安裝及鏡像基礎(chǔ)操作
容器是一種輕量級虛擬化技術(shù),能夠快速構(gòu)建業(yè)務(wù)環(huán)境并便于業(yè)務(wù)遷移,解決兼容性問題,這篇文章主要介紹了docker容器環(huán)境安裝及鏡像基礎(chǔ)操作,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-09-09

