前端部署实践(Docker) | 青训营

82 阅读3分钟

Docker 是一种工具,用于创建、部署和运行应用程序(通过使用容器)。 容器使开发人员可以将应用与需要的所有部件(库、框架、依赖项等)打包为一个包一起交付。

前提

如题,本文将记录使用 Docker 部署前端项目的过程,所以你得安装好 Docker。在 Linux 和 MacOS 上安装比较简单,只需要使用相应发行版自带的安装工具即可。如果是在 Windows 系统上,你先得安装 wsl2,再下载安装 Docker Desktop。具体操作可以看微软官方文档。本文在 Windows 11 系统上使用 Docker Desktop 演示。

项目代码

本文使用的项目代码为 vite 使用 react-ts 模板创建的项目。

# npm 7+
npm create vite@latest docker-demo -- --template react-ts

image.png

下载镜像

Docker 中有两个比较重要的概念镜像(image)和容器(container)。镜像类似于虚拟机镜像,可以理解为一个面向 Docker 引擎的只读模板,其中可以包含程序运行的环境。而容器是从镜像创建的应用运行实例,容器之间都是相互隔离、互不可见的。

首先,我们得下载 nginx 的镜像,你可以使用 docker pull <image-name>[:<tag>] 来下载,比如命令行 docker pull nginx:latest 就是用于下载 nginx 最新的镜像。下载完成后可以可以使用 docker images 查看已经下载的镜像。当然也可以直接在 Docker Desktop 中操作。

image.png

创建容器

首先得构建项目,可直接使用 npm run build,对于 vite 来说构建产物位于 dist 目录下。

在创建容器前还得了解一个 Docker 中的概念数据卷(volume)。当我们删除容器后,其中的数据将一同删除。“数据卷是一个可供一个或多个容器使用的位于宿主机上特殊目录”。也就是说容器的数据是保存在宿主中的,因而删除容器后数据不会丢失。对数据卷的修改会同时反应在容器和宿主中。

在运行 nginx 前得对其配置,以下是最简单得配置。

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"';

    sendfile        on;

    keepalive_timeout  65;

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

容器只能读取容器中的数据,所以我们的创建一个数据卷让其能够读取到配置,

如下是构建容器的命令行,在运行之前你的注意以下几点。如下参数 -v ${PATH_TO_CONFIG}/nginx.conf:/etc/nginx/nginx.conf 就是将宿主的配置 {PATH_TO_CONFIG}/nginx.conf 和容器中 /etc/nginx/nginx.conf 相关联。其中 ${PATH_TO_CONFIG}/html 是前端构建产物的目录,其关联容器中的目录 /usr/share/nginx/html

PATH_TO_CONFIG=/home/nginx
docker run -d \
  --name nginx --restart always \
  -p 80:80 \
  -v ${PATH_TO_CONFIG}/nginx.conf:/etc/nginx/nginx.conf \
  -v ${PATH_TO_CONFIG}/conf.d:/etc/nginx/conf.d \
  -v ${PATH_TO_CONFIG}/logs:/var/log/nginx \
  -v ${PATH_TO_CONFIG}/cert:/etc/nginx/cert \
  -v ${PATH_TO_CONFIG}/html:/usr/share/nginx/html \
  nginx:alpine

接下来就是配置 server,如下是配置应放在目录 ${PATH_TO_CONFIG}/conf.d 下,其监听 80,设置 root 目录位于容器的 /usr/share/nginx/html/,也就是宿主的 ${PATH_TO_CONFIG}/html

server {
    listen 80;
    server_name localhost;
    index index.html;
    root  /usr/share/nginx/html/;
    
    location / {
      try_files $uri $uri/ @router;
      index  index.html;
    }

    location @router {
      rewrite ^.*$ /index.html last;
    }
}

如果操作无误可以在 80 端口打开项目。

当然你也可以不创建数据卷,你可以直接将配置文件和构建产物从宿主中复制容器。使用 docker scp <source> <distance> 即可,比如 docker scp /home/nginx/nginx.conf nginx:/etc/nginx/nginx.conf 就是将宿主中的配置文件复制到容器中。反过来也可以将容器中的数据复制到宿主,其实只要不删除容器,数据也不会丢失。

总结

Docker 的出现使得开发人员可以专注于编写代码,而无需操心将运行代码的系统。但是你就是享受配置一下午环境而毫无收获的感觉,那完全可以不使用 Docker。