使用 docker 在本地搭建 nginx 环境,docker desktop 自带了一个 nginx 镜像和示例,其实在首页点击大大的 Run 就能跑一个最简单的包含 nginx 进程的容器了。
首页
但这个极简的容器距离成为我们在本地的开发环境还差一点点。至少我们需要解决几个问题:
基础命令缺失
nginx 的标准镜像基于 debian slim 镜像,这是一个很干净的极简的环境,所以当我们跑起了 nginx 容器,尝试对它做一些常规操作的时候,会发现很多常用的命令找不到。
比如 top,ps,netstat,vi,less,ping 等,这对于我们玩这个容器非常不友好。
常用命令缺失
文件管理问题
nginx 进程启动了并不等于部署完整了,因为如果我们要在本地环境对 nginx 做些什么,一定会涉及到诸多文件如何管理的问题。比如配置文件,log,静态资源文件等。
网络管理问题
更复杂的情况是要在本地搭建架构里的所有元素,那么 nginx 可能还要承担反向代理的角色,需要与其他的服务或者资源互通,那么如何管理网络,也会成为一个问题。
1. 安装一个 nginx 容器:先让它跑起来
有了标准镜像,跑起来非常的简单,只需要一行指令即可。
docker run -p 80:80 -d --name myNginx1 nginx:latest
-p 为容器指定了一个映射到本机的端口,即把nginx容器暴露的80端口映射到本地的80端口上。
-- name 为容器指定了一个独一无二的名字。
复制代码
启动的nginx容器
再为其创建一个 hello world 文件。
cd /usr/share/
echo "hello world" > index.html
复制代码
创建index文件
这样我们就可以在本地访问到这个页面了。
访问第一个页面
2. 安装常用命令
现在我们来解决上面的问题,将常用的命令安装起来,以便我们玩这个容器。
报错 1: 安装命令失败
有一种尝试是直接通过 apt-get 工具安装常用命令,但是会失败。
apt-get install vim
E: Unable to locate package vim
复制代码
安装失败
报错 2: 更新 apt-get 工具失败
为了解决报错 1,需要更新 apt-get 工具,但是也会因为找不到 deb 源失败。
apt-get update
Err:1 http://deb.debian.org/debian bullseye InRelease
403 connecting to deb.debian.org:80
复制代码
找不到deb源
deb.debian.org 不是很稳定,如果连不上,反复多试几次。
按照顺序更新 apt 工具
更新apt工具
更新成功之后再执行一众常用命令的安装指令
apt-get install vim
apt-get install procps
apt-get install curl
apt-get install iputils-ping
apt-get install net-tools
apt-get install telnet
复制代码
这样一些常用的命令就安装好了,可以在容器内使用。如果还有命令没有覆盖到,也对应安装起来即可。
使用top命令
映射本地文件
容器启动了,常用命令也安装好了,理论可以直接进入容器对文件进行操作。但很明显搭建本地环境,不可能所有的文件都进到容器里修改,这样就成玩具了。我们需要完善的方案。docker 提供了文件挂载的支持,简单说就是把本地的文件映射到容器里,这样实际操作的时候就可以通过修改本地文件的方式来影响容器内部署的内容。
搭建本地 workspace
因为有了文件挂载的支持,我们可以把需要动态调整/需要操作的文件当作本地文件来处理。总结来看就是 nginx 的配置和日志。
mkdir %workspace%/dist
mkdir %workspace%/dist/conf
mkdir %workspace%/dist/static
mkdir %workspace%/log
复制代码
在你的 workspace 里创建 dist 作为部署目录,包含 conf 目录存放配置文件,static 目录存放静态部署文件; 创建 log 作为日志输出目录。
启动容器
docker run -d -p 80:80
-v %workspace%/dist/conf/nginx.conf:/etc/nginx/nginx.conf
-v %workspace%/dist/conf/conf.d:/etc/nginx/conf.d
-v %workspace%/dist/static:/usr/share/nginx/html
-v %workspace%/log:/var/log/nginx
nginx:latest
复制代码
访问挂载后的首页
挂载之后,对本地文件的修改也会实时反映在容器内部署的文件上。
3. 复杂一点的情况:反向代理
如果只是作为静态资源服务器,部署成功之后就可以玩起来了。复杂一点的情况是让 nginx 扮演反向代理的角色,这样部署的 nginx 还需要通过网络与下游的服务通信。
我们使用 docker 的 network 命令在本地搭建一个网络,通过指定 ip 的方式来为容器赋予 ip。实际的企业级应用对于内部网络分区、ip 管理一定会有更加专业的方式,这里我们的目标只是为了搭建一个简单易用的本地环境,所以不做参考和对比。
创建一个网络
docker network create --subnet=172.1.0.0/16 native-dev-net
复制代码
启动 nginx 容器
修改一下 nginx 容器启动命令,使其加入网络,并且拥有一个固定 ip。
docker run -d -p 8082:80
--network native-dev-net --ip 172.1.0.2
-v %workspace%/nginx1/dist/conf/nginx.conf:/etc/nginx/nginx.conf
-v %workspace%/nginx1/dist/conf/conf.d:/etc/nginx/conf.d
-v %workspace%/nginx1/dist/static:/usr/share/nginx/html
-v %workspace%/nginx1/log:/var/log/nginx
nginx:latest
docker run -d -p 8083:80
--network native-dev-net --ip 172.1.0.3
-v %workspace%/nginx2/dist/conf/nginx.conf:/etc/nginx/nginx.conf
-v %workspace%/nginx2/dist/conf/conf.d:/etc/nginx/conf.d
-v %workspace%/nginx2/dist/static:/usr/share/nginx/html
-v %workspace%/nginx2/log:/var/log/nginx
nginx:latest
复制代码
启动前置反向代理 nginx 容器
修改 nginx 配置文件,加上代理转发相关信息。
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forward_for;
proxy_pass http://172.1.0.2;
}
location /api {
proxy_set_header Host $host;
proxy_set_header X-Real-Ip $remote_addr;
proxy_set_header X-Forward-For $proxy_add_x_forward_for;
proxy_pass http://172.1.0.3;
}
}
复制代码
启动作为反向代理的容器
docker run -d -p 8080:80
--network native-dev-net --ip 172.1.0.1
-v %workspace%/proxy/dist/conf/nginx.conf:/etc/nginx/nginx.conf
-v %workspace%/proxy/dist/conf/conf.d:/etc/nginx/conf.d
-v %workspace%/proxy/dist/static:/usr/share/nginx/html
-v %workspace%/proxy/log:/var/log/nginx
nginx:latest
复制代码
转发静态服务器
转发动态服务器
评论