笔者以前和朋友一直在讨论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数据可视化等前端知识和实战,欢迎在公号《趣谈前端》加入咱们的技术群一块儿学习讨论,共同探索前端的边界。