筆者以前和朋友一直在討論web技術方向的話題,也一直想了解web運維方面的知識,因此特地請教了一下個人朋友老胡,他對web運維和後端技術有很是多的實戰經驗,因此在本文中他也提供了很多幫助。本文主要會介紹Docker的基礎知識和應用領域,並經過實際部署一個web項目來帶你們瞭解Docker的使用方式。javascript
做爲一名前端工程師,爲何要學習Docker呢?首先筆者先來介紹一下Docker:css
Docker 是一個基於 Go 語言開發的開源應用容器引擎, 可讓咱們把咱們的應用和包打包到一個輕量級、可移植的容器中,而後發佈到任何流行的 Linux 機器上,而且能夠實現虛擬化。所謂容器,就是徹底使用沙箱機制,相互之間沒有任何接口,而且性能開銷極低。html
回憶一下,咱們傳統的Web應用部署方式通常都是將Web應用手動上傳到服務器,並手動安裝相關依賴和環境,再高級一點的咱們能夠用jenkins來自動化部署咱們的應用,包括自動化測試等等,雖然已經解決了咱們大部分部署的繁瑣問題,可是若是咱們服務器變動,或者遇到須要部署到多臺服務器的場景,那麼傳統的操做將會繁瑣。你們也許會問這種狀況會出現嗎?答案是會的。作過B端系統或有Saas系統開發經驗的朋友也許會清楚其中的繁瑣,爲了客戶安全和私有化每每須要研發人員給企業配置和部署獨立的Web應用,若是你有上百家客戶上千家客戶,咱們一個個部署顯然是效率極低的,並且不能保證環境的一致性和穩定性,由於一旦咱們的Web系統使用的環境或者包更新了,應用極可能不能正常Work,這種狀況下采用Docker容器化技術能夠很好的解決這一問題。前端
再者,前幾年比較火的雲計算服務,最爲直接的要求就是標準化和快速交付,而Docker技術就很是適合這樣的要求。vue
目前大部分企業都在採用Docker來實現軟件開發部署中的自動化和部署效率安全等問題,做爲前端工程師,也須要掌握必定的Docker技術來更好的配合後端和運維來推動這一過程。java
在開始正文以前首先咱們先來了解一下Docker的應用場景,這樣才能更好的理解爲何要使用它。 node
Docker 的三個基本概念以下:linux
其採用客戶端-服務器 (C/S) 架構模式,使用遠程API來管理和建立Docker容器。 Docker 容器經過 Docker鏡像來建立。容器與鏡像的關係相似於面向對象編程中的對象與類。爲了方便你們理解,筆者特地畫了一張Docker的架構圖,以下: webpack
由上圖對比可得,兩種虛擬化技術本質的區別是:主機虛擬化須要在父操做系統上運行一套子操做系統;而操做系統虛擬化是以進程的方式管理子容器,子容器與宿主機共用一套操做系統。css3
主機虛擬化 | 操做系統虛擬化 | |
---|---|---|
隔離性 | 環境強隔離,父子操做系統底層無關 | 只能運行類似的操做系統,使用相似的庫 |
網絡 | 網絡傳輸效率低,啓動慢 | 傳輸效率高,啓動較快,響應快 |
佔用 | 必須增長操做系統的大量佔用 | 佔用較少 |
安全 | 子系統與宿主系統無關 | 有風險,但在可控範圍 (daemon) |
參照docker官網安裝文檔強烈建議不使用windows 操做(本人沒有試過在windows上開發docker 相關,雖然官網提供了,但不知道),建議使用osx或linux)考慮服務器上國內使用centos 7 爲大部分介紹下centos 7的安裝(使用非root 帳號,自行加上sudo)
# 1.清除舊版本的docker 安裝
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# 2.安裝依賴 官網介紹 yum-utils 爲了引入yum-config-manager 其餘的是docker 自身依賴
yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
# 3.添加yum源
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# 4.列出對應的安裝版本
yum list docker-ce --showduplicates | sort -r
# 5.安裝 建議根據實際狀況選擇版本 不要追求最新
yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
# 6。設置開機啓動docker,並啓動docker
systemctl enable docker && systemctl start docker
複製代碼
# 查看docker 服務狀態
systemctl docker status
# 運行 第一個應用,前端接觸最多的容器就是nginx 了
# 查詢官方 nginx stable 版本是1.16.1 因而選用 stable-alpine 版本
docker run -p 80:80 nginx:stable-alpine
複製代碼
docker全部命令可閱讀使用docker 命令行並可經過docker --help 查詢用法
docker --help
Usage: docker [OPTIONS] COMMAND
A self-sufficient runtime for containers
Options:
--config string Location of client config files (default "/Users/mac/.docker")
-c, --context string Name of the context to use to connect to the daemon (overrides DOCKER_HOST env var and default context set with "docker context use")
-D, --debug Enable debug mode
-H, --host list Daemon socket(s) to connect to
-l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info")
--tls Use TLS; implied by --tlsverify
--tlscacert string Trust certs signed only by this CA (default "/Users/mac/.docker/ca.pem")
--tlscert string Path to TLS certificate file (default "/Users/mac/.docker/cert.pem")
--tlskey string Path to TLS key file (default "/Users/mac/.docker/key.pem")
--tlsverify Use TLS and verify the remote
-v, --version Print version information and quit
Management Commands:
builder Manage builds
config Manage Docker configs
container Manage containers
context Manage contexts
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes
複製代碼
官方給的關於鏡像的描述是:"An image is a read-only template with instructions for creating a Docker container",含義是說 鏡像是一個只讀的用於指導建立容器的模板,至關於面向對象裏的類的含義 而容器即是對應的實例,經常使用的命令以下
# 下載鏡像
+ docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
423ae2b273f4: Pull complete
de83a2304fa1: Pull complete
f9a83bce3af0: Pull complete
b6b53be908de: Pull complete
Digest: sha256:04d48df82c938587820d7b6006f5071dbbffceb7ca01d2814f81857c631d44df
Status: Downloaded newer image for ubuntu:latest
docker.io/library/ubuntu:latest
# 查看鏡像列表
+ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 72300a873c2c 2 weeks ago 64.2MB
# 導出鏡像爲文件,方便在不聯網的機器上使用docker image
+ docker save ubuntu -o ubuntu.tar
# 刪除鏡像,可見它的操做是先清除tag 若是沒有其餘相同image佔用再清理layer
+ docker rmi ubuntu
Untagged: ubuntu:latest
Deleted: sha256:72300a873c2ca11c70d0c8642177ce76ff69ae04d61a5813ef58d40ff66e3e7c
Deleted: sha256:d3991ad41f89923dac46b632e2b9869067e94fcdffa3ef56cd2d35b26dd9bce7
Deleted: sha256:2e533c5c9cc8936671e2012d79fc6ec6a3c8ed432aa81164289056c71ed5f539
Deleted: sha256:282c79e973cf51d330b99d2a90e6d25863388f66b1433ae5163ded929ea7e64b
Deleted: sha256:cc4590d6a7187ce8879dd8ea931ffaa18bc52a1c1df702c9d538b2f0c927709d
# 從文件導入鏡像,方便在不聯網的機器上使用docker image
+ docker load -i ubuntu.tar
cc4590d6a718: Loading layer [=====================>] 65.58MB/65.58MB
8c98131d2d1d: Loading layer [=====================>] 991.2kB/991.2kB
03c9b9f537a4: Loading layer [=====================>] 15.87kB/15.87kB
1852b2300972: Loading layer [=====================>] 3.072kB/3.072kB
Loaded image: ubuntu:latest
# 構建鏡像, 可自定義構建本身的鏡像 下一部份詳細講
docker build -t $image:$tag $DockerfilePath
# 給鏡像打一個新標籤,通常用於推送到其餘倉庫
docker tag ubuntu $image:$tag
# 將鏡像推送到遠程registry
docker push $image:$tag
複製代碼
copy-on-write: docker 鏡像是以層爲結構的,底層通常爲基礎的操做系統,當文件系統發生變化時,首先從只讀層複製一個文件到讀寫層操做當該層讀寫完畢並提交後即在原來基礎上累加一層,當一個鏡像構建時會緩存全部成功的層提高構建速度.
嘗試經過物理安裝的方式講述一下本身構建nginx,咱們在物理機上安裝nginx 的步驟(源碼安裝能最大化保證穩定性和用到新的feature)可歸納爲如下幾步
# 1. 下載源碼包及依賴
yum install pcre-devel zlib-devel openssl-devel gcc make
wget http://nginx.org/download/nginx-1.16.1.tar.gz /usr/local/source/
# 2. 設置編譯nginx 的模塊
./configure \
--prefix=/usr/local/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_ssl_module \
--with-pcre \
--with-http_gzip_static_module
# 3. 編譯 & 安裝
make && make install
# 4. 啓動nginx
./nginx
複製代碼
實際在Dockerfile下也是這麼完成的。
1.編輯文件命名Dockerfile
FROM centos:centos7.2.1511
MAINTAINER xujiang@test.com
ADD http://nginx.org/download/nginx-1.16.1.tar.gz /usr/local/source/ RUN ["bash","-c","cd /usr/local/source && \ tar -xf nginx-1.16.1.tar.gz --strip-components 1 && \ yum update -y > /dev/null 2>&1 && \ yum install -y -q pcre-devel zlib-devel openssl-devel gcc make && \ ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-pcre --with- http_gzip_static_module && \ make && make install && \ ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx && \ rm -rf /usr/local/source"] CMD ["nginx", "-g", "daemon off;"] 複製代碼
2.在當前目錄下運行構建,即可構建成功 .
表示當前目錄下構建
+ docker build -t mynginx:20200311 .
Step 1/4 : FROM centos:centos7.2.1511
---> 9aec5c5fe4ba
Step 2/4 : ADD http://nginx.org/download/nginx-1.16.1.tar.gz /usr/local/source/
Downloading [======================================>] 1.033MB/1.033MB
---> ac3b840c5563
Step 3/4 : RUN ["bash","-c","cd /usr/local/source && tar -xf nginx-1.16.1.tar.gz --strip-components 1 && yum update -y > /dev/null 2>&1 && yum install -y -q pcre-devel zlib-devel openssl-devel gcc make && ./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-pcre --with-http_gzip_static_module && make && make install && ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx && rm -rf /usr/local/source"]
---> 22efc447e0c2
Step 4/4 : CMD ["nginx", "-g", "daemon off;"]
---> 8f74bded71e9
Successfully built 8f74bded71e9
Successfully tagged mynginx:20200311
複製代碼
3.運行該鏡像並暴露內部80端口指向外部8000:docker run -d -p 8000:80 --name mynginx-container mynginx:20200311
注:實際上nginx 構建全部內容遠遠比這個複雜,這裏可貼上nginx 構建的Dockerfile
更多指令可參考Dockerfile Reference
上文提到容器是鏡像的運行時實例,一個鏡像能夠經過不一樣的命令運行不同的容器實例,如下是對容器的基本操做的經常使用命令
+ docker run --help
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
# -d 將容器運行在後臺並打印容器ID
-d, --detach Run container in background and print container ID
-e, --env list Set environment variables
--env-file list Read in a file of environment variables
--rm Automatically remove the container when it exits
-v, --volume list Bind mount a volume
-w, --workdir string Working directory inside the container
--restart string Restart policy to apply when a container exits (default "no")
複製代碼
# 查看當前正在運行的容器 docker ps -a 表示查看全部容器(包含已經退出)
+ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a5f7f9710db8 mynginx:20200311 "nginx -g 'daemon of…" 59 seconds ago Up 58 seconds 0.0.0.0:80->80/tcp mynginx-container
# 進入容器內部執行命令(打開標準輸入流併爲容器建立僞終端)
docker exec -it mynginx-container bash
# 查看容器日誌
docker logs -f mynginx-container
複製代碼
1.準備
* 一個前端項目
* 一臺安裝好docker 的機器
* [docker hub](https://hub.docker.com/)查詢編譯所須要的鏡像[node](https://hub.docker.com/_/node?tab=tags),[nginx](https://hub.docker.com/_/nginx)
複製代碼
# 克隆antd-admin.git 項目
git clone https://github.com/zuiidea/antd-admin.git
# 使用docker 編譯的優點 能夠在任意一臺只裝了docker的環境下編譯不一樣的語言 消除對環境依賴
docker run --network=host --rm -v "$(cd $(dirname .);pwd):/app" -w /app node:10-alpine3.9 yarn && yarn build
複製代碼
server {
listen 80;
server_name _;
access_log /var/log/nginx/host.access.log main;
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST;
root /app;
index index.html index.htm;
}
}
複製代碼
FROM nginx:stable-alpine
ENV LANG en_US.UTF-8
COPY dist /app COPY app.conf /etc/nginx/conf.d/default.conf WORKDIR /app 複製代碼
#!/bin/bash
current_dir=$(cd $(dirname .);pwd)
function compire(){
docker run --network=host --rm -v "$current_dir:/app" -w /app node:10-alpine3.9 yarn && yarn build
}
function package(){
if [ ! -d "$current_dir/dist" ] ;then
compire
fi
docker build -t myapp:`date -u +"%Y%m%d"` $current_dir
}
function clean(){
rm -rf $current_dir/dist
}
case "$1" in
compire)
compire
;;
package)
package
;;
clean)
clean
;;
*)
echo "USAGE:$0 package | compire | clean "
esac
複製代碼
docker run -d -p 80:80 myapp:20200311
至此,基本的配置就完成了,你們能夠本身手動試試,基於Docker部署一個本身的Web應用。
本文只涉及到了Docker基本的使用配置,後期筆者有空會繼續和朋友總結編排,docker network,docker volume,docker daemon等技術,並以一個node的案例部署做爲實戰來教你們在實際項目中去落地Docker自動化部署。
若是想獲取更多項目完整的源碼, 或者想學習更多H5遊戲, webpack,node,gulp,css3,javascript,nodeJS,canvas數據可視化等前端知識和實戰,歡迎在公號《趣談前端》加入咱們的技術羣一塊兒學習討論,共同探索前端的邊界。