使用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 为容器指定了一个独一无二的名字。
再为其创建一个hello world文件。
cd /usr/share/
echo "hello world" > index.html
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.debian.org 不是很稳定,如果连不上,反复多试几次。
按照顺序更新apt工具
apt update
apt-get update
更新成功之后再执行一众常用命令的安装指令
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
这样一些常用的命令就安装好了,可以在容器内使用。如果还有命令没有覆盖到,也对应安装起来即可。
映射本地文件
容器启动了,常用命令也安装好了,理论可以直接进入容器对文件进行操作。但很明显搭建本地环境,不可能所有的文件都进到容器里修改,这样就成玩具了。我们需要完善的方案。
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