使用Docker和Nginx部署单页面应用
使用Docker和Nginx部署单页面应用
一、简介
1.背景
Docker 是一个容器引擎,它使用 Linux 内核功能(如命名空间和控制组)在操作系统之上创建容器
Docker Compose是一个命令行工具,可以简化容器镜像的构建以及容器的运行,将命令行的选项翻译成配置文件
Nginx是一个高性能的HTTP和反向代理服务器
2.Docker基础命令
#构建镜像
docker build [可选参数] 构建上下文目录
#列出所有镜像
docker images
#删除镜像
docker rmi 镜像ID
#启动容器,运行镜像
docker run [可选参数] 镜像
#列出所有正在运行的容器
docker ps
#列出所有容器
docker ps -a
#停止容器
docker stop [容器ID]
#删除容器
docker rm [容器ID]
docker build的部分可选参数
可选参数 | 说明 |
---|---|
-t | 指定镜像标签名 |
-f | 指定其他目录下的Dockerfile文件,可以是远程地址 |
docker run的部分可选参数
可选参数 | 说明 |
---|---|
-p | 指定端口映射,-p 3000:80,把容器的80端口映射到宿主机的3000端口 |
-d | 后台运行 |
--rm | 容器退出时自动删除该容器 |
二、准备要部署的单页面应用
以create-react-app为例,创建React项目,并执行打包,项目根目录下build文件夹为打包产物,其中index.html为入口文件
在项目文件夹(如D:\Projects),执行以下命令
npx create-react-app app-deploy
cd app-deploy
npm install --registry https://registry.npmmirror.com
npm run build
打包产物如下
三、准备环境(Linux)
以Ubuntu为例
1.安装Docker
进入Docker官方文档:https://docs.docker.com/engine/install/ubuntu/,按照顺序执行文档中的命令,即以下命令
# Add Docker's official GPG key:
# 更新apt软件包索引
sudo apt-get update
# 安装必要的软件包以使用HTTPS源
sudo apt-get install ca-certificates curl gnupg
# 创建一个目录,用于存储Docker GPG密钥
sudo install -m 0755 -d /etc/apt/keyrings
# 从Docker官方站点下载GPG密钥并将其解压缩到前面创建的目录中
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 设置密钥文件的权限,允许所有用户读取
sudo chmod a+r /etc/apt/keyrings/docker.gpg
# Add the repository to Apt sources:
# 添加Docker软件包源列表
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 再次更新apt软件包索引
sudo apt-get update
# 安装所需的Docker软件包及插件
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
安装完成后,执行以下命令
sudo docker run hello-world
出现以下输出说明Docker安装成功
2.安装Docker-Compose
1)安装pip(如果没有安装的话)
sudo apt install -y python3-pip
2)安装Docker-Compose
sudo pip install docker-compose -i https://mirrors.aliyun.com/pypi/simple/
安装完成后,执行以下命令
docker-compose --version
出现以下输出说明Docker-Compose安装成功
3.使用Docker Hub镜像源
编辑以下文件
/etc/docker/daemon.json
在该文件中添加registry-mirrors属性
{
"registry-mirrors": [
"https://dockerproxy.com"
]
}
然后重新加载Docker Daemon并重启Docker
sudo systemctl daemon-reload # 重新加载Docker Daemon
sudo systemctl restart docker # 重启Docker
4避免Docker磁盘占用空间膨胀
1)限制日志文件的大小和数量
编辑以下文件
/etc/docker/daemon.json
在该文件中添加以下两个属性
{
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
然后重新加载Docker Daemon并重启Docker,该配置将对新建的容器生效
sudo systemctl daemon-reload # 重新加载Docker Daemon
sudo systemctl restart docker # 重启Docker
2)定时清理未使用的镜像、容器、网络、构建缓存
# 编辑当前用户的定时任务列表
crontab -e
在打开的定时任务配置文件中添加以下配置
# 每天凌晨1点删除24小时前创建的未使用的镜像、容器、网络、构建缓存
0 1 * * * docker system prune --force --filter "until=24h"
# Linux创建定时任务命令:分 时 天 月 星期 命令
# docker system prune命令是删除未使用的镜像、容器、网络、构建缓存的快捷方式,可以用--filter做过滤
四、准备环境(Windows)
1.安装WSL
1)简介
WSL是“Windows Subsystem for Linux”的缩写,顾名思义,WSL就是Windows系统的Linux子系统,其作为Windows组件搭载在Windows10周年更新(1607)后的Windows系统中
2)操作
进入https://learn.microsoft.com/zh-cn/windows/wsl/install-manual#step-4---download-the-linux-kernel-update-package,执行到步骤5,即WSL安装成功即可
2.安装Docker Desktop
1)简介
Docker Desktop是可以部署在windows运行docker的应用服务,其基于windos的Hyper-V服务和WSL2内核在windos上创建一个子系统(linux),从而实现其在windows上运行docker
必须先安装WSL,否则Docker Desktop无法正常启动Docker
2)操作
进入https://www.docker.com/get-started/,下载并安装
3.验证Docker和Docker-Compose的安装
查看版本并运行HelloWorld
执行以下命令
docker -v
docker-compose -v
docker run hello-world
出现以下输出说明Docker安装成功
4.使用Docker Hub镜像源
打开Docker Desktop,点击设置按钮,切换到Docker Engine标签,在下面的配置文件中添加registry-mirrors属性
{
"registry-mirrors": [
"https://dockerproxy.com"
]
}
即
然后点击Apply & restart
五、编写相关配置文件
1.编写nginx配置文件
在项目根目录(D:\Projects\app-deploy),新建一个文件,命名为nginx.conf,内容为
server {
listen 80; #监听本地80端口,由于nginx运行在容器内,这个本地指的是容器
server_name localhost;
root /usr/share/nginx/html; #为该目录做静态资源服务
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html; #在单页面应用中将不存在的资源重定向到root目录下的index.html
expires -1; #资源默认不缓存,避免浏览器缓存
}
location /static {
expires 1y; #打包产物static文件夹下的文件的名称带有hash值,可设置一年的长期缓存
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
2.编写Dockerfile文件
在项目根目录(D:\Projects\app-deploy),新建一个文件,命名为Dockerfile(没有后缀名),内容为
# 继承nginx:alpine镜像
# Alpine是一种轻量级的Linux发行版,专为作为容器而设计
FROM nginx:alpine
# 将当前目录build文件夹下的所有文件都复制到当前镜像的/usr/share/nginx/html文件夹中
ADD build /usr/share/nginx/html
# 将node镜像/temp文件夹下的nginx.conf文件复制到当前镜像的/etc/nginx/conf.d文件夹中,命名为default.conf
COPY --from=node /temp/nginx.conf /etc/nginx/conf.d/default.conf
3.编写Docker-Compose配置文件
在项目根目录(D:\Projects\app-deploy),新建一个文件,命名为docker-compose.yaml,内容为
version: "3" #使用Docker-Compose的v3版本语法,是目前的主流版本
services:
app: #服务命名为app
build: . #从当前路径构建镜像
ports:
- 3000:80 #容器与宿主机之间的端口映射,冒号前面是宿主机端口,冒号后面是容器端口,可以配置多个
六、构建镜像并启动容器(部署应用)
使用Docker-Compose或不使用Docker-Compose
1.使用Docker-Compose
在项目根目录(D:\Projects\app-deploy),执行以下命令
docker-compose up --build
#up代表创建并启动容器,--build代表每次启动容器前构建镜像
命令行输出如下
Linux:
Windows:
在浏览器访问http://localhost:3000,将显示部署成功的单页面应用
在浏览器控制台查看响应头,将显示nginx版本信息
2.不使用Docker-Compose
在项目根目录(D:\Projects\app-deploy),执行以下命令
# 使用当前目录的Dockerfile文件构建镜像,镜像标签为app
docker build -t app .
#启动容器,运行镜像标签为app的镜像
#-p代表端口,把容器的80端口映射到宿主机的3000端口
docker run -p 3000:80 app
在浏览器访问http://localhost:3000,将显示部署成功的单页面应用
在浏览器控制台查看响应头,将显示nginx版本信息
七、使用Dockerfile指令安装依赖、打包
持续集成工具通常会直接从Git仓库拉取代码,拉取的代码不包含依赖,需要下载依赖
将下载依赖、打包的操作放到Dockerfile指令中,并且使用构建缓存和多阶段构建
将项目根目录的Dockerfile文件(D:\Projects\app-deploy\Dockerfile)的内容修改为
# 继承node:20-alpine镜像,在本次构建中命名为node
# Alpine是一种轻量级的Linux发行版,专为作为容器而设计
# 引入node镜像是为了执行npm命令
FROM node:20-alpine as node
# 改变工作目录为镜像根目录下/temp,如果目录不存在将被自动创建
WORKDIR /temp
# 把项目根目录的package.json复制到镜像根目录下的/temp目录中,再下载依赖
# 在镜像的构建过程中,Dockerfile指令会从上往下执行,每一步的结果都会被缓存起来
# package.json相比上次构建没有变化时,下面两行指令会直接读取缓存,不会再次执行
ADD package.json /temp
RUN npm install --registry https://registry.npmmirror.com
# 把项目根目录的所有文件复制到镜像根目录下的/temp目录中,再执行npm run build打包
ADD . /temp
RUN npm run build
# 继承nginx:alpine镜像,作为部署的最终镜像
FROM nginx:alpine
# 将node镜像/temp/build文件夹下的所有文件都复制到当前镜像的/usr/share/nginx/html文件夹中
COPY --from=node /temp/build /usr/share/nginx/html
# 将node镜像/temp文件夹下的nginx.conf文件复制到当前镜像的/etc/nginx/conf.d文件夹中,命名为default.conf
COPY --from=node /temp/nginx.conf /etc/nginx/conf.d/default.conf
在项目根目录(D:\Projects\app-deploy),执行以下命令构建并启动容器
docker-compose up --build
#up代表创建并启动容器,--build代表每次启动容器前构建镜像
命令行输出如下,显示下载了依赖,下载耗时33.1秒
使用Ctrl + C停止运行,再次执行命令构建并启动容器
命令行输出如下,显示读取了缓存