Docker教程前端有这篇就够了!!!

Docker

前言

日趋复杂的运维开发环境,对虚拟服务器及应用服务的要求更加的多元化。咱们须要更加容易扩展、性能优越、方便监控的管理服务,容器化应用、容器化运维应运而生。javascript

【工欲善其事,必先利其器】须要准备的环境(三选一):php

  • Linux环境(Centos 7以上/Debian 8以上/Ubuntu 16.04LTS以上版本)
  • Windows 64位专业版/企业版/教育版(Build 15063以上)
  • macOS Sierra 10.12以上的版本

若是,你有了上面的环境,就能够很快速的学习。html

【收获什么】:前端

  1. 理解/安装docker容器技术
  2. 秒级快速部署mysql、nginx、tomcat等服务
  3. 搭建本身的git服务器
  4. 使用容器技术发布nodejs + mongodb + koa + vue的应用

概念

1. 什么是容器化?

容器化是将应用程序或服务、其依赖项及其配置(抽象化为部署清单文件)一块儿打包为容器映像的一种软件开发方法。vue

软件容器充当软件部署的标准单元,其中能够包含不一样的代码和依赖项。 按照这种方式容器化软件,开发人员和 IT 专业人员只需进行极少修改或不修改,便可将其部署到不一样的环境。java

容器化应用程序在容器主机上运行,而容器主机在 OS(Linux 或 Windows)上运行。所以,容器的占用比虚拟机 (VM) 映像小得多。node

【容器化的特色】:mysql

  • 一致的运行环境
  • 可伸缩性
  • 更方便的移植
  • 隔离性

2. 了解Docker

Docker是用GO语言开发的应用容器引擎,基于容器化,沙箱机制的应用部署技术。可适用于自动化测试、打包,持续集成和发布应用程序等场景,包括阿里云,亚马逊在内的云计算服务商都采用了docker来打造serverless服务平台。它不只仅能够部署项目,还能够用于数据库搭建,nginx服务搭建,nodejs、php等编程语言环境搭建。nginx

PS: docker现已更名为mobygit

Docker中的三个重要概念

镜像(image)

分片的(只读)文件系统,由Dockerfile建立,它独立、易扩展、更效率

容器(container):

由Docker进程建立和管理的:文件系统 + 系统资源 + 网络配置 + 日志管理 Docker是docker镜像的运行环境,因此容器的概念就比较好理解了

仓库(registry):

用来远端存储docker镜像版本控制、变动管理、为持续集成与快速部署提供便利

image.png 容器与镜像的关系相似于面向对象编程中的对象与类。

Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和建立Docker容器。

Docker 容器经过 Docker 镜像来建立。

image.png

image.png

3. Docker vs 虚拟机

image.png

【区别】:

  1. 容器是应用层的抽象,它将代码和依赖关系打包在一块儿。 多个容器能够在同一台机器上运行,并与其余容器共享操做系统内核,每一个容器在用户空间中做为独立进程运行。 容器占用的空间比VM少(容器映像的大小一般为几十MB),能够处理更多的应用程序,而且须要更少的VM和操做系统。
  2. 虚拟机(VM)是物理硬件的抽象,将一台服务器转变为多台服务器。 管理程序容许多台VM在单台机器上运行。 每一个VM都包含操做系统的完整副本,应用程序,必要的二进制文件和库 - 占用数十GB。 虚拟机也可能很慢启动。

【总结】:

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 通常为 MB 通常为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 通常几十个
开发/环境定制 方便(命令行、面向对象式) 进入虚拟机

【相同点】:

  1. 文件隔离/文件共享(沙箱)
  2. 资源隔离
  3. 网络隔离
  4. 支持多种宿主环境(扩展)
  5. 快照/镜像(版本控制/变动管理)

【不一样点】:

  1. 不一样的资源管理/依赖//释放(虚拟机占用更多的系统资源)
  2. 不一样的应用运行环境
  3. Docker是写时复制
  4. 不一样的日志方式(Docker收集日志,而虚拟机须要在虚拟系统里面看日志)
  5. 不一样的交互方式(Docker偏shell,虚拟机偏GUI)

4. Docker的工做原理(重点)

Docker是容器化部署技术,它主要做用在于经过运行容器来实现应用部署,而容器基于镜像运行。

简单地说,就是将你的项目和依赖包(基础镜像)打成一个带有启动指令的项目镜像,而后在服务器建立一个容器,让镜像在容器内运行,从而实现项目的部署。

服务器就是容器的宿主机,docker容器与宿主机之间是相互隔离的。

Docker 的基础是Linux容器(LXC:Linux Containers)等技术。

通常状况流程:

image.png

Docker流程:

image.png

这其中,发生了什么?

  1. Docker会本身拉取镜像,若本地已经存在该镜像,则不用到网上去拉取
  2. 建立新的容器
  3. 分配文件系统而且挂着一个可读写的层,任何修改容器的操做都会被记录在这个读写层上,你能够保存这些修改为新的镜像,也能够选择不保存,那么下次运行改镜像的时候全部修改操做都会被消除
  4. 分配网络\桥接接口,建立一个容许容器与本地主机通讯的网络接口
  5. 设置ip地址,从池中寻找一个可用的ip地址附加到容器上,换句话说,localhost并不能访问到容器
  6. 运行你指定的程序
  7. 捕获而且提供应用输出,包括输入、输出、报错信息

Docker的价值:

从应用架构角度:统一复杂的构建环境;

从应用部署角度:解决依赖不一样、构建麻烦的问题,结合自动化工具(如jenkins)提升效率。

从集群管理角度:规范的服务调度,服务发现,负载均衡

应用

1. Docker安装和配置(偷个懒)

  1. 安装教程地址:

    www.runoob.com/docker/maco…

  2. 配置镜像加速地址:

    www.runoob.com/docker/dock…

2. Docker的命令

1. 查看docker版本

docker --version
复制代码

2. 运行第一个Docker应用

// 使用docker run命令

docker run hell-world

// 下载ubuntu镜像打印“from ububtu”
// -i: 以交互模式运行容器,一般与 -t 同时使用
// -t: 为容器从新分配一个伪输入终端,一般与 -i 同时使用

docker run -it ubuntu echo "from ubuntu"  

复制代码

3. 查看容器运行状态

使用docker ps命令来查看正在运行的容器的状态,-a参数来查看全部的已经运行的容器(不管是否中止)

4. 重要命令

run 建立一个新的容器并运行一个命令

exec能够进入到容器里面去

-it是提供交互式的终端工具

-d 是让镜像容器在后台去持续运行

--name 指定容器的名称

-p 容器内部端口映射到主机的端口

-v 挂载宿主机的文件目录到镜像里面去

-e 设置环境变量

// 运行镜像 
docker run -it -d  --name test ubuntu
// 进入容器
docker exec -it test /bin/bash 
// 把本机的Downloads文件映射到ubuntu的home文件下
docker run -v ~/Downloads/:/home -itd --name test1 ubuntu

复制代码

5.容器的管理

  • 启动start
  • 中止stop
  • 重启restart
  • 删除已中止容器rm
docker stop test
复制代码

3. 常见的应用场景介绍

Docker提供了轻量级的虚拟化,相比于虚拟机,能够在同一台机器上建立更多数量的容器。

【常见的应用场景】:

  1. 快速部署
  2. 隔离应用
  3. 提升开发效率
  4. 版本控制

1. 快速部署

咱们尝试着来部署一个mysql:

docker run -d --name mysql-test -e MYSQL_ROOT_PASSWORD=123456 mysql
复制代码

1.gif

一样的道理,咱们来部署一个nginx:

2.gif

注意:这里没有映射服务端口,因此在80端口是看不到index.html中的内容的。须要加入-p参数来映射端口!!

docker run -d --name web -p 8000:80 -v ${your_dir}:/usr/share/nginx/html nginx
复制代码

2. 隔离应用

咱们能够同时跑两个mysql,两个nginx,指定不一样的端口进行映射:

mysql-test1映射到8001端口,把mysql-test2映射到8002端口。

docker run -d --name mysql-test1 -p 8001:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
docker run -d --name mysql-test2 -p 8002:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
复制代码

把web1映射到8100端口,把web2映射到8200端口。

docker run -d --name web1 -p 8100:80 -v ${your_dir}:/usr/share/nginx/html nginx
docker run -d --name web2 -p 8200:80 -v ${your_dir}:/usr/share/nginx/html nginx
复制代码

3. 提升开发效率

  1. 一致的运行环境

    因为 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 能够在不少平台上运行,不管是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。所以用户能够很轻易的将在一个平台上运行的应用,迁移到另外一个平台上,而不用担忧运行环境的变化致使应用没法正常运行的状况。

  2. 更快速的启动时间

    传统的虚拟机技术启动应用服务每每须要数分钟,而 Docker 容器应用,因为直接运行于宿主内核,无需启动完整的操做系统,所以能够作到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

  3. 更高效的复用系统资源

    因为容器不须要进行硬件虚拟以及运行完整操做系统等额外开销,Docker 对系统资源的利用率更高。不管是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。所以,相比虚拟机技术,一个相同配置的主机,每每能够运行更多数量的应用。

  4. 仓库/镜像机制

    使用仓库能够方便的在任何有docker进程的虚拟机/服务器/主机上运行docker应用,环境的统一,让它们的部署变的很是的简单。

4. 版本控制

Docker容器还能够像git仓库同样,可让你提交变动到Docker镜像中并经过不一样的版原本管理它们,来看看下面的例子:

咱们以前建立了一个mysql,如今,咱们使用commit命令就能够给它作一个快照,打上一个tag

3.gif 在后面的课程中,咱们会详细的介绍Docker的常见命令

4. 制做Docker镜像

Dockerfile 是一个由一堆命令+参数构成的脚本,使用 docker build 便可执行脚本构建镜像,自动的去作一些事,主要用于进行持续集成。

通常,Dockerfile 共包括四部分:

  • 基础镜像信息
  • 维护者信息
  • 镜像操做指令
  • 容器启动时执行指令

1. Dockerfile文件示例:

FROM node:10

LABEL maintainer=atiedan666666@163.com

# 建立 app 目录
WORKDIR /app

# 把 package.json,package-lock.json(npm@5+) 或 yarn.lock 复制到工做目录(相对路径)
COPY ["package.json","*.lock","./"]

# 打包 app 源码
# 特别注意:要指定工做目录中的文件名
COPY src ./src

# 使用.dockerignore文件,上面两个COPY合并成一个
# COPY . .

# 使用Yarn安装 app 依赖
# 若是你须要构建生产环境下的代码,请使用:
# --prod参数
RUN yarn --prod --registry=https://registry.npm.taobao.org

# 对外暴露端口 -p 4000:3000
EXPOSE 3000

CMD [ "node", "src/index.js" ]
复制代码

2. 本地生成node应用

当Node.js碰见Docker,下面介绍Docker在前端中的应用:

一个简单的Koa应用:

const Koa = require('koa');
const app = new Koa();

// response
app.use(ctx => {
  ctx.body = 'Hello Koa!!';
});

app.listen(3000);
复制代码

3. 打包镜像

使用docker build打包:

docker build -t ${your_name}/${image_name}:${tag} .
复制代码

这里的your_name表明的是远程仓库中的用户名,或者仓库地址; image_name为镜像名称,tag是给镜像打的标签,用于版本控制。. 表明当前目录例如:

docker build -t tiedan/node-demo:1.0 .
复制代码

4. 使用镜像

使用docker run运行

// 运行
docker run -d --name nodedemo -p 4000:3000 tiedan/node-demo:1.0
// 查看
docker ps
复制代码

5. Docker-compose

经过 Docker-Compose 用户能够很容易地用一个配置文件定义一个多容器的应用,而后使用一条指令安装这个应用的全部依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。

Compose 中有两个重要的概念:

  • 服务 (service) :一个应用的容器,实际上能够包括若干运行相同镜像的容器实例。
  • 项目 (project) :由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

Docker Compose 是 Docker 的独立产品,所以须要安装 Docker 以后在单独安装 Docker Compose .

1. 安装

Window和Mac 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其余 Docker 应用程序,所以 Mac 用户不须要单独安装 Compose, Linux 上咱们能够从 Github 上下载它的二进制包来使用,

#下载
sudo curl -L https://github.com/docker/compose/releases/download/1.20.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
#安装
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose --version
复制代码

2. 使用

docker-compose.yml改写:

version: '3'
services:
  mysql:
    image: mysql
    container_name: test-mysql
    ports:
    - "8001:3306"
    environment:
    - MYSQL_ROOT_PASSWORD=123456
复制代码

在此文件的当前目录下,使用docker-compose up -d来执行。

生命周期管理:

建立:run/up

启动/中止/删除/重启:start/stop/rm/restart

检视/日志:logs/ps

3. 应用

搭建本地mongo + mongo-express服务

# docker-compose.mongo.yml配置文件
version: '3.1'
services:
  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456

  mongo-express:
    image: mongo-express
    restart: always
    ports:
      - 8081:8081
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: 123456
复制代码

执行:

# 执行 docker-compose.mongo.yml 若是不加 docker-compose -f 默认执行 docker-compose.mongo.yml
docker-compose -f docker-compose.mongo.yml up -d
复制代码

4. 搭建git服务器

项目地址: github.com/sameersbn/d…

docker-compose.git.yml文件

// 运行该文件 docker-compose -f docker-compose.git.yml up -d
version: '2.3'

services:
  redis:
    restart: always
    image: redis:5.0.9
    command:
    - --loglevel warning
    volumes:
    - redis-data:/var/lib/redis:Z

  postgresql:
    restart: always
    image: sameersbn/postgresql:12-20200524
    volumes:
    - postgresql-data:/var/lib/postgresql:Z
    environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production
    - DB_EXTENSION=pg_trgm,btree_gist

  gitlab:
    restart: always
    image: sameersbn/gitlab:13.11.2
    depends_on:
    - redis
    - postgresql
    ports:
    - "10080:80"
    - "10022:22"
    volumes:
    - gitlab-data:/home/git/data:Z
    healthcheck:
      test: ["CMD", "/usr/local/sbin/healthcheck"]
      interval: 5m
      timeout: 10s
      retries: 3
      start_period: 5m
    environment:
    - DEBUG=false

    - DB_ADAPTER=postgresql
    - DB_HOST=postgresql
    - DB_PORT=5432
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production

    - REDIS_HOST=redis
    - REDIS_PORT=6379

    - TZ=Asia/Kolkata
    - GITLAB_TIMEZONE=Kolkata

    - GITLAB_HTTPS=false
    - SSL_SELF_SIGNED=false

    - GITLAB_HOST=localhost
    - GITLAB_PORT=10080
    - GITLAB_SSH_PORT=10022
    - GITLAB_RELATIVE_URL_ROOT=
    - GITLAB_SECRETS_DB_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_SECRET_KEY_BASE=long-and-random-alphanumeric-string
    - GITLAB_SECRETS_OTP_KEY_BASE=long-and-random-alphanumeric-string

    - GITLAB_ROOT_PASSWORD=12345678
    - GITLAB_ROOT_EMAIL=atiedan666666@163.com

    - GITLAB_NOTIFY_ON_BROKEN_BUILDS=true
    - GITLAB_NOTIFY_PUSHER=false

    - GITLAB_EMAIL=notifications@example.com
    - GITLAB_EMAIL_REPLY_TO=noreply@example.com
    - GITLAB_INCOMING_EMAIL_ADDRESS=reply@example.com

    - GITLAB_BACKUP_SCHEDULE=daily
    - GITLAB_BACKUP_TIME=01:00

    - SMTP_ENABLED=false
    - SMTP_DOMAIN=www.example.com
    - SMTP_HOST=smtp.gmail.com
    - SMTP_PORT=587
    - SMTP_USER=mailer@example.com
    - SMTP_PASS=password
    - SMTP_STARTTLS=true
    - SMTP_AUTHENTICATION=login

    - IMAP_ENABLED=false
    - IMAP_HOST=imap.gmail.com
    - IMAP_PORT=993
    - IMAP_USER=mailer@example.com
    - IMAP_PASS=password
    - IMAP_SSL=true
    - IMAP_STARTTLS=false

    - OAUTH_ENABLED=false
    - OAUTH_AUTO_SIGN_IN_WITH_PROVIDER=
    - OAUTH_ALLOW_SSO=
    - OAUTH_BLOCK_AUTO_CREATED_USERS=true
    - OAUTH_AUTO_LINK_LDAP_USER=false
    - OAUTH_AUTO_LINK_SAML_USER=false
    - OAUTH_EXTERNAL_PROVIDERS=

    - OAUTH_CAS3_LABEL=cas3
    - OAUTH_CAS3_SERVER=
    - OAUTH_CAS3_DISABLE_SSL_VERIFICATION=false
    - OAUTH_CAS3_LOGIN_URL=/cas/login
    - OAUTH_CAS3_VALIDATE_URL=/cas/p3/serviceValidate
    - OAUTH_CAS3_LOGOUT_URL=/cas/logout

    - OAUTH_GOOGLE_API_KEY=
    - OAUTH_GOOGLE_APP_SECRET=
    - OAUTH_GOOGLE_RESTRICT_DOMAIN=

    - OAUTH_FACEBOOK_API_KEY=
    - OAUTH_FACEBOOK_APP_SECRET=

    - OAUTH_TWITTER_API_KEY=
    - OAUTH_TWITTER_APP_SECRET=

    - OAUTH_GITHUB_API_KEY=
    - OAUTH_GITHUB_APP_SECRET=
    - OAUTH_GITHUB_URL=
    - OAUTH_GITHUB_VERIFY_SSL=

    - OAUTH_GITLAB_API_KEY=
    - OAUTH_GITLAB_APP_SECRET=

    - OAUTH_BITBUCKET_API_KEY=
    - OAUTH_BITBUCKET_APP_SECRET=
    - OAUTH_BITBUCKET_URL=

    - OAUTH_SAML_ASSERTION_CONSUMER_SERVICE_URL=
    - OAUTH_SAML_IDP_CERT_FINGERPRINT=
    - OAUTH_SAML_IDP_SSO_TARGET_URL=
    - OAUTH_SAML_ISSUER=
    - OAUTH_SAML_LABEL="Our SAML Provider"
    - OAUTH_SAML_NAME_IDENTIFIER_FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:transient
    - OAUTH_SAML_GROUPS_ATTRIBUTE=
    - OAUTH_SAML_EXTERNAL_GROUPS=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_EMAIL=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_USERNAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_FIRST_NAME=
    - OAUTH_SAML_ATTRIBUTE_STATEMENTS_LAST_NAME=

    - OAUTH_CROWD_SERVER_URL=
    - OAUTH_CROWD_APP_NAME=
    - OAUTH_CROWD_APP_PASSWORD=

    - OAUTH_AUTH0_CLIENT_ID=
    - OAUTH_AUTH0_CLIENT_SECRET=
    - OAUTH_AUTH0_DOMAIN=
    - OAUTH_AUTH0_SCOPE=

    - OAUTH_AZURE_API_KEY=
    - OAUTH_AZURE_API_SECRET=
    - OAUTH_AZURE_TENANT_ID=

volumes:
  redis-data:
  postgresql-data:
  gitlab-data:
复制代码

5. 实战案例

docker-compose在前端里面的使用:

Nodejs + mongodb + koa + vue的应用组合:

docker-compose.yml

version: '3'
services:
  web:
    image: web:1.0
    ports:
    - "8080:80"

  server:
    image: server:1.0
    ports:
    - "3000:3000"
    depends_on:
    - mongodb
    links:
    - mongodb:db

  mongodb:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456
复制代码

depends_on 决定了容器加载的前后顺序,这里mongdbweb先加载,mongdb建立完成以后,再来建立server

相关文章
相关标签/搜索