docker本地如何启动前端项目

1,594 阅读7分钟

概述

Docker 是一个应用程序开发、部署、运行的平台,使用 go 语言开发。相较于传统的主机虚拟化,Docker提供了轻量级的应用隔离方案,并且为我们提供了应用程序快速扩容、缩容的能力。
Docker依赖于LXC(Linux Containers)技术,充分利用了其中的Namespace这个内核级特性,实现了容器之间的资源隔离。本质上来看,每一个Docker容器就是宿主机进程,不同 Docker 容器就对应不同的宿主机进程,这样,不同容器(即不同进程)就可以采用 Namespace 资源隔离,使得每一个容器看起来都像是一个独立的小虚拟机

docker其它核心技术:

cgroup:资源控制
rootfs:文件系统隔离
aufs:高级分层文件系统(Advanced Multi-layered unification filesytem)

架构

静态部件描述

Docker采用的是CS架构,包含了三个主要部分:dockerd守护进程、REST API接口层、cli接口层(管理容器、镜像、网络、存储等等),docker client 通过Unix套接字或者网络接口访问 docker daemon,从而完成容器、镜像等内容的管理

流程描述

对象

镜像

镜像是一个用来构建容器的只读模版,通常一个镜像会依赖其他的镜像。例如我们编写的一个Node程序需要依赖Node环境,那在构建这个应用镜像时就需要依赖基础的Node镜像。
我们可以创建自己的镜像,也可以使用仓库中已经创建好的镜像。创建镜像需要创建一个Dockerfile文件。每个Dockerfile定义镜像文件中的一层,当定义发生变化的时候,只需要更新着一层的文件即可。

容器

容器是一个运行时状态下的镜像,通过docker命令我们可以创建、启动、停止、删除容器

启动我们的第一个容器:

docker run --rm hello-world

  1. 如果本地没有hello-world镜像,那么首先拉取镜像
  2. 自动创建一个容器,相当于命令dock container create
  3. Docker分配一块文件系统给容器
  4. Docker创建网络接口、分配网络地址
  5. 启动容器,并且执行目标入口命令
  6. 容器关闭并退出
  7. 容器销毁

网络

Docker的网络子系统是可插拔的,支持bridge、host、overlay、macvlan、none等网络模式

  • bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将主机上的Docker容器连接到docker0虚拟网桥上,docker0网桥由docker后台服务启动时创建,默认在172.17.0.0/16段
    每一个容器运行时会生成一对veth网络设备直连,再通过网桥使得同一个主机上的容器间可以相互通信
+-------------------------------------------------------------------------------+
|                                                                               |
|       +---------------------------------------------------------------+       |
|       |                           docker0                             |       |
|       +---------------------------------------------------------------+       |
|                             ↑               ↑                                 |
|.............................|...............|.................................|
|                             ↓               ↓                                 |
|        +----------+    +-----------+   +-----------+    +-----------+         |
|        |   vth2   |<-->|   veth1   |   |   veth3   |<-->|   veth4   |         |
|        +----------+    +-----------+   +-----------+    +-----------+         |
|             ↑                                                 ↑               |
|             +-------------------------------------------------+               |
|        172.16.17.2                                       172.16.17.3          |
+-------------------------------------------------------------------------------+
  • host模式下,容器会共享主机的network namespace,所以拥有主机的全部网络通信能力,通常用于docker容器测试

存储

默认情况下,容器中的应用生成的所有文件都存放在一个可写的容器层,意味着这些数据的生命周期和容器保持一致,这些文件与容器高度关联,因此会带来下面几个问题:

  • 不能在宿主机上很方便地访问容器中的文件
  • 无法在多个容器之间共享数据
  • 当容器删除时,容器中产生的数据将丢失

为此,Docker提供了两种方案解决数据问题:

  • bind mount volumes:将host上已存在的目录或文件挂载到容器中使用
  • docker managed volumes:docker自己管理的数据卷存储

对比一下两种方式各自的特点:

-bind mount Volumesdocker managed volumes
volume 位置可任意指定/var/lib/docker/volumes/...
对已有mount point 影响隐藏并替换为 volume原有数据复制到 volume
是否支持单个文件支持不支持,只能是目录
权限控制可设置为只读,默认为读写权限无控制,均为读写权限
移植性移植性弱,与 host path 绑定移植性强,无需指定 host 目录

不管使用哪种方式,容器内看起来都是一样的,或者作为一个文件夹存在、或者作为一个文件存在。
上图说明了不同方式的区别,Volumes 是存在本地文件系统中的一部分,其他应用程序不能对这个文件系统进行修改,Linux下在/var/lib/docker/volumes。这是数据持久化的最好方案。Bind Mount 允许将主机中任何位置的数据挂载,这些数据的读写没有收到保护。tmps是存储在主机内存中的数据。

常用操作

cli

下载镜像

docker pull urlpath:[tag]

查询镜像

docker images

运行镜像(启动容器)

docker run [-d] \
  [--rm] \
  [--name {container_name}] \
  [-p {hostport:containerport}] \
  [-v {hostpath:containerpath}:[ro] ] \
  [-e "key=value"] \
  {image_name:[tag]}
  • -d可以指定当前容器在后台运行,释放当前终端控制台不阻塞,用户可以继续往下输入命令
  • --rm可以指定容器停止即刻销毁删除
  • -p可以指定主机和容器的端口映射,可以重复指定多个映射
  • -v可以指定主机的存储目录挂载至容器中,可以重复指定多个挂载,默认读写,ro选项可以指定只读保护数据
    • hostpath为绝对路径:开户bind mount模式
    • hostpath为一个变量或连同“:”一起省略:开户docker managed模式
    • 使用hostpath变量时只能为:[a-zA-Z0-9][a-zA-Z0-9_.-]
  • -e可以预置一些环境变量供容器使用,可以重复指定多个环境变量

构建镜像(打包)

docker build -t {image_name}:[tag] [Dockerfile目录]

查询容器

docker ps [-a] docker inspect {container_name|container_id}

进入容器

docker exec -ti {container_name|container_id} sh/bash ...

查看容器日志

docker logs {container_name|container_id} [--tail n] [-f]

查看网络

docker network ls docker network inspect {network_name}

查看存储

docker volume ls docker volume inspect {volume_name}

注:docker volume只能查看docker managed volumes,对于bind mount volumes只能通过docker inspect来查看

Restful api

操作API
查询镜像curl -X GET http://{IP}:{PORT}/images/json
查询容器curl -X GET http://{IP}:{PORT}/containers/json
启动容器curl -X POST http://{IP}:{PORT}/images/create?fromImage=hello-world:lates

参考文档

yeasy.gitbooks.io/docker_prac…

接下来利用docker本地启动一个前端项目

前置条件,本地安装了docker

你本地项目已经build过,然后本地任意目录创建文件夹,假如名为:docker_build

将你npm run build 后的dist文件复制到docker_build文件夹中

再次新建Dockerfile文件和default.conf文件

# Dockerfile配置文件
# 指定基础镜像为最新版 nginx
FROM nginx  
ADD dist/ /usr/share/nginx/html 
ADD default.conf /etc/nginx/conf.d/default.conf  


# 运行 nginx
CMD [ "nginx", "-g", "daemon off;" ]
# 和你本地dev_server启动端口一致
EXPOSE 80 
    # nginx简单配置
    server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    access_log  /var/log/nginx/host.access.log  main;
    error_log  /var/log/nginx/error.log  error;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

完成以上配置后,在docker_build目录下;执行命令

1、从dockerhub拉取nginx最新镜像

docker pull nginx
2、查看本地镜像

docker image ls
3、运行image到container

docker run --name nginx1 -it -p 12345:80 -d nginx:latest

4、查看本地容器

docker ps -a / docker container ls -a
5、测试

打开浏览器,输入http://localhost:12345,效果如下


图片.png

接下来构建镜像:

docker build -t docker_demo:v1 .
参数说明:

-   -t 参数给镜像命名 docker-demo-vue
-   . 是基于当前目录的 Dockerfile 来构建镜像
-   :v1 添加tag

如下效果说明构建成功

图片.png

接下来运行容器

docker run -d -p 3000:80 --name docker-01 docker-demo

参数说明:

参数解释:

-   -d 设置容器在后台运行
-   -p 表示端口映射,把本机的 80 端口映射到 container 的 80 端口(这样外网就能通过本机的 80 端口访问
-   --name 设置容器名 docker-01
-   docker-demo 是上面构建的镜像名


运行 curl -v -i localhost:3000

如下效果说明已成功

图片.png

浏览器效果:

图片.png

Dockerfile本地还可以指定基础镜像为node,基本操作和nginx差不多

服务器部署,将本地3个文件上传到服务器目录,假设名为:fronted,执行build 然后run 即可;值得注意的是最好是在规定的容器里安装nginx等

解释; 如果远程服务已有镜像仓库

本地build镜像后,需执行docker logo ; docker tag; docker push,然后进入服务器拉取最新镜像即可,

但正常情况下企业都有自己的devops,前端结合CI/CD(我一般使用runner)build后自己创建镜像

图片.png

CI/CD行业配置及实践可前往参考:www.yuque.com/lufeilizhix…