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
下载镜像
Docker 中有两个比较重要的概念镜像(image)和容器(container)。镜像类似于虚拟机镜像,可以理解为一个面向 Docker 引擎的只读模板,其中可以包含程序运行的环境。而容器是从镜像创建的应用运行实例,容器之间都是相互隔离、互不可见的。
首先,我们得下载 nginx 的镜像,你可以使用 docker pull <image-name>[:<tag>] 来下载,比如命令行 docker pull nginx:latest 就是用于下载 nginx 最新的镜像。下载完成后可以可以使用 docker images 查看已经下载的镜像。当然也可以直接在 Docker Desktop 中操作。
创建容器
首先得构建项目,可直接使用 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。