docker在前端的使用 - 实践篇

265 阅读5分钟
  1. docker在前端的使用 - 入门篇
  2. docker在前端的使用 - 实践篇
  3. docker在前端的使用 - 命令篇

这是docker在前端的使用实践篇,本文从一个小Demo入手,来学习一下基本的使用姿势。

拿一个场景来说,如果我们想要搭建一个网站,那我们常规操作需要这几部:

  1. 买一个云服务器,或者自己搞一个树莓派。
  2. 给服务器上装一个系统,无论是CentOS还是Ubuntu。
  3. 然后装nginx,如果需要数据库,那可能装一个套装。
  4. 前端在本地开发好项目,然后build出产物。
  5. 将产物同步到服务器上,然后配置一下nginx.conf,指定一个端口,配置上域名。

那就可以正常访问了。常规操作没有什么问题。

那我们现在用Docker来构建一个web的前端项目流程。

创建一个项目

因为这个过程和Docker没有什么关系,所以我们就直接用React来演示了,使用 create-react-app 创建项目,进入目录后使用 npm run build 命令构建出部署所需要的静态资源。

npx create-react-app docker-demo
cd docker-demo
npm run start

不出什么意外的话,你会看到这个页面。

本地能看到到是因为webpack-dev-server在本地给我们搭建了一个server,默认端口3000,这个大家都懂。

最终的产物需要build出来

npm run build

选一个服务器

ok,现在我们能在build文件夹中看到最终产物了。

如果我们在index.html上右键Open with Live Server(前提是你装了Live Server插件),当前插件会帮我们起一个服务,并在浏览器中打开页面。

但是页面白屏,原因是html文件中的src和href链接是 '/static'的写法,我们的Live Server是在docker-demo维度起的服务。所以我们将连接改成'./static' 就可以了。

但是这波操作显然我们是不愿意做的。且最终的产物其实是应该独立出docker-demo项目,独自运行的。

这种情况下,我们可以用Nginx起一个服务。Nginx是一款轻量级的 HTTP 服务器,具有很多非常优越的特性:轻量、高性能、并发能力强,用来部署静态页面很便捷。

既然使用docker,那我们就直接用docker的镜像来做就可以了。

我们先在docker-demo的项目中新建一个nginx.conf,毕竟docker只解决环境,自己的配置还是要自己写的。

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen 80 default_server;
        server_name _;
        # 重要的是location
        location  / {
          root /usr/share/nginx/html;
          index  index.html ;
          try_files $uri $uri/ /index.html;
        }
    }
}

来一个镜像配置

基础镜像这种东西,就和写代码一样,能C的就直接V了。

我们要在根目录创建 Dockerfile 文件来定制我们的镜像

  1. 使用 FROM 指令指定基础镜像,官方已经给我们准备好了 Nginx 的镜像
  2. 使用 LABEL 指令为构建的镜像设置作者信息
  3. 使用 ADD 指令将 build 文件夹下的所有文件拷贝至 Nginx 的根目录
  4. 使用 ADD 指令添加上一步准备好的 Nginx 配置文件
  5. 使用 EXPOSE 指令声明运行时容器提供的服务端口,暴露 80 端口
FROM nginx:latest
LABEL maintainer "英姿飒爽的翩翩少年"
# 这个和我们的nginx.conf是对应的。
ADD ./build/ /usr/share/nginx/html  
# 将我们的配置文件放到nginx中。 
ADD nginx.conf /etc/nginx/
EXPOSE 80

当然 /usr/share/nginx/html 这个路径可以自己定义。只要是docker和nginx的配置相同就行。

提醒一点:有的小朋友执行完docker的命令后就会去本地的 /usr/share/nginx/html 路径中去找,发现没有我们build的产物,会怀疑是不是我们的ADD命令有问题?

有这样的疑问是对docker的虚拟化还不了解。上篇文章中有说到,docker创建出的容器是和我们本地的环境完全隔离的。所以先想要查看文件得进入到docker的容器中查看,下面有进入的方式介绍。

构建一个镜像

这里我们使用 docker build 命令来进行构建 执行

docker build -t demo/nginx:v1 .

这个时候我们执行 docker images 会显示

REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
demo/nginx   v1        7ae06402eb54   4 minutes ago   142MB

如果你的vscode 中装了Docker的插件,也可以看到。

测试一下

docker run -d -p 8080:80 demo/nginx:v1

打开浏览器,访问 localhost:8080。出现如下页面表示工作正常,测试通过。

上面说到如果我们想进入容器内看一看,要怎么做。

首先 docker ps -a 查看一下当前启动了哪些容器

CONTAINER ID   IMAGE           COMMAND                  CREATED         STATUS         PORTS                  NAMES
5111127fb413   demo/nginx:v1   "/docker-entrypoint.…"   8 minutes ago   Up 7 minutes   0.0.0.0:8080->80/tcp   inspiring_rubin

拿到CONTAINER ID,然后执行 docker exec -it 5111127fb413 /bin/bash

这样我们就进入到当前容器中了,我们一直cd到 /usr/share/nginx/html 路径中,可以发现我们的build出来的产物。

命令行用起来还是比较麻烦,所以我们直接使用VSCode的插件 或者和是 Docker的客户端,用起来事倍功半。

这是我们一直在本地去做的。放到服务器上也是很容易的。服务器上装上docker。吧我们的Dockerfile和nginx.conf传上去,run一下就ok。

当然这只是一个简单的Demo,实际的业务我们要处理的东西还有很多,要写的Dockerfile也很长。这个要随业务灵活变动。

即使这样Docker依旧能很大程度上提升我们部署的效率,我们不需要自己部署nginx或其他的服务器。也不需要担心本地环境和线上环境的不同,只要Image相同,就是相同的。

代码地址

总结

平时我们只做业务开发是很少会用到docker的,但是要涉及到的部署或者是运维的话,Docker是绕不开的为数不多的选择。Docker 为前端应用提供了一致的运行环境,带来了快速部署、回滚等特性。除此之外,还需要考虑容器化应用的部署,容器的编排、调度等问题,可以使用 Kubernetes 等容器管理平台。