mobaijun 发表于 2021-12-28 17:53

Docker启动Nginx配置动静分离

## 前言

最近接了个小需求,将服务和前端资源实现分离,很早之前就使用过 `nginx` 做动静分离,不同的是,这一次使用的是在 `docker` 环境下,配置方面没有多大区别,主要是启动 `nginx` 和 `nginx` 的挂载目录需要注意下,下面就开始吧!



## 动静分离

动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和 静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用 `Nginx` 处理静态页面,`Tomcat` 处理动态页面。动静分离从目前实现角度来讲大致分为两种:

- 第一种:是纯粹把静态文件独立成单独的域名,放在独立的服务器上,也是目前主流推崇的方案;
- 第二种:方法就是动态跟静态文件混合在一起发布,通过`nginx`来分开。

以上内容搬的以前 `nginx` 的文章,感兴趣的小伙伴可以去看下这篇笔记[动静分离简介](https://www.mobaijun.com/posts/1706463495.html#toc-heading-29)

![动静分离](https://cdn.jsdelivr.net/gh/mobaijun/blog_css_js/image/blog_images/20200613213818.png)

> 通过 `location`指定不同的后缀名实现不同的请求转发。通过 `expires`参数设置,可以使浏 览器缓存过期时间,减少与服务器之前的请求和流量。具体 `Expires`定义:是给一个资源 设定一个过期时间,也就是说无需去服务端验证,直接通过浏览器自身确认是否过期即可, 所以不会产生额外的流量。此种方法非常适合不经常变动的资源。(如果经常更新的文件, 不建议使用 Expires 来缓存),我这里设置`3d`,表示在这 3 天之内访问这个`URL`,发送一 个请求,比对服务器该文件最后更新时间没有变化,则不会从服务器抓取,返回状态码`304`, 如果有修改,则直接从服务器重新下载,返回状态码 `200`。



## 准备环境

* 保证系统有 `Docker` 环境,有无网络均可。
* 有网络的情况下使用`docker pull`拉取镜像,无网络的情况下使用`docker load < `导入镜像

~~~bash
# 搜索镜像
$ docker search nginx
# 拉取镜像
$ docker pull nginx|latest
# 创建工作目录
$ mkdir -p /nginx/{conf,conf.d,logs,data}
# 在data目录下添加html文件夹和image文件夹
$ docker run -dit nginx
# conf 里放 nginx.conf 配置文件, 这个文件的内容要从镜像里的复制出来,前面是容器的路径 后面是宿主机的路径
$ docker cp 容器id:/etc/nginx/conf.d/default.conf /nginx/conf.d/default.conf
$ docker cp 容器id:/etc/nginx/nginx.conf /nginx/conf/nginx.conf
# 删除容器
$ docker rm $(docker stop 容器id)
# 查看nginx启动日志
$ tail -f /nginx/logs/error.log
~~~

* 启动 nginx

~~~bash
$ docker run -dit --restart=always --name=nginx -p 8005:80 -v /nginx/data/image:/data/image -v /nginx/data/html:/usr/share/nginx/html -v /nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /nginx/logs:/var/log/nginx -v /nginx/conf.d:/etc/nginx/conf.d nginx:latest
#######################################################
* --restart=always: 异常关闭后重新尝试启动
* -v /nginx/data/image:/data/image:挂载宿主机的image文件
* -v /nginx/data/html:/usr/share/nginx/html: 挂载宿主机的html文件
* -v /nginx/conf/nginx.conf:/etc/nginx/nginx.conf: nginx配置文件
* -v /nginx/logs:/var/log/nginx: 日志文件
* -v /nginx/conf.d:/etc/nginx/conf.d: 默认配置文件
~~~

* 配置动静分离,修改`/nginx/conf.d/default.conf`配置文件

~~~nginx
server {
    # 监听端口
    listen       80;
    listen[::]:80;
    # 对应域名,单个网站域名网站也可写localhost
    server_nameip;
    #access_log/var/log/nginx/host.access.logmain;
    # 可以配置多个location
    # 配置html访问路径 https://ip:port/index.html
    location / {
      root   /usr/share/nginx/html;
      indexindex.html index.htm;
    }
   # 配置图片访问路径 https://ip:port/*.jpg
    location ~ .*\.(gif|jpg|pdf|jpeg|png)$ {
      expires    8h;
      root   /data/image/;
    }
    # 拦截后台请求,正则匹配 api 路径
    location ~* ^/(code|auth|admin|gen|dcmp|transport) {
       # 配置代理地址
       proxy_pass http://ip:port;
       #proxy_set_header Host $http_host;
       proxy_connect_timeout 15s;
       proxy_send_timeout 15s;
       proxy_read_timeout 15s;
       proxy_set_header X-Forwarded-Proto http;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
    #error_page404            /404.html;
    # redirect server error pages to the static page /50x.html
    error_page   500 502 503 504/50x.html;
    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}
    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root         html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_indexindex.php;
    #    fastcgi_paramSCRIPT_FILENAME/scripts$fastcgi_script_name;
    #    include      fastcgi_params;
    #}
    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    denyall;
    #}
}
~~~

!(https://s2.loli.net/2021/12/23/vzo9igPfqdhjbUY.png)

> PS: 中间有一段踩坑经历:在备份 `default.conf` 的时候名字前缀不要为 `default-*.conf`,最好也不要放在同级目录下,不然会导致配置覆盖,无法生效,不注意就排查很久无法找到原因,同时修改配置后建议重启容器。`docker restart [容器ID]`;

bigcan 发表于 2021-12-28 21:21

问题是,nginx运行在自己的命名空间里,它只认识“自己”,你的tomcat或PHP也必须运行在docker同一个网络空间里,否则是找不到它们的

我也尝试过用容器化的nginx,但总有奇怪奇怪的问题,最后还是放弃了,改为宿主机运行nginx,把其它服务容化。

kof21411 发表于 2021-12-28 21:57

bigcan 发表于 2021-12-28 21:21
问题是,nginx运行在自己的命名空间里,它只认识“自己”,你的tomcat或PHP也必须运行在docker同一个网络空 ...

可以多个docker容器运行在一个虚拟网段中的

mobaijun 发表于 2021-12-29 09:42

bigcan 发表于 2021-12-28 21:21
问题是,nginx运行在自己的命名空间里,它只认识“自己”,你的tomcat或PHP也必须运行在docker同一个网络空 ...

是的,使用单一的nginx容器确实会有很多小问题,我这里最后是需要整合docker-compose的,所以最终会进行容器编排,就没有这个问题

mobaijun 发表于 2021-12-29 09:49

kof21411 发表于 2021-12-28 21:57
可以多个docker容器运行在一个虚拟网段中的

这个方法也不错,可以尝试下

yyb1813 发表于 2021-12-29 10:14

soyadokio 发表于 2021-12-29 18:13

哈哈 这题有点窜台...
页: [1]
查看完整版本: Docker启动Nginx配置动静分离