docker安装nginx并使用自定义配置文件

2,679 阅读6分钟

一、拉取Nginx镜像

如果对nginx镜像版本有要求,可以先搜索Docker Hub 中的镜像列表

docker search nginx

image.png

可以看到列表里面的nginx镜像有很多,这里可以自定义选择拉取的镜像。

这里我直接拉取nginx官方的镜像了。使用命令

docker pull nginx

image.png

拉取速度跟网速有关,稍等片刻,不报错即可,正常也不会报错。

1、列出已下载的镜像

拉取之后,查看当前机器上镜像文件:

docker images

image.png

2、列出运行中的容器

使用 docker ps 命令即可列出运行中的容器

docker ps

image.png 使用 docker ps -a 命令即可列出所有(包括已停止的)的容器

docker ps -a

image.png 如果在我们启动容器时提示端口占用了或者启动的历史记录占用了我们的端口,运行镜像都是会报错的,这时,可以使用

docker stop  CONTAINER ID 

停止运行,然后使用删除命令,删除启动痕迹,再次运行就好了。

docker rm  CONTAINER ID 

重启该容器:

docker restart  CONTAINER ID 

二、启动容器,部署nginx并修改配置文件

因为这里我想要自定义nginx的配置文件,所以就先提前手动新建了后面启动映射的文件夹/usr/soft/nginx, /usr/soft/nginx/conf.d和文件/usr/soft/nginx/nginx.conf,

  • /usr/soft/nginx nginx镜像的总的文件夹
  • /usr/soft/nginx/conf.d nginx的子配置文件
  • /usr/soft/nginx/nginx.conf 该文件是nginx的总的配置文件,下面启动中指定该文件为只读。

image.png

nginx.conf 文件内容:

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;
    
    # set client body size to 50M #
    client_max_body_size 50m;
    
    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"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

注意上面的配置文件中的:client_max_body_size 50m;,如果没有这个,在前端上传文件或者base64的图片时,就会出现:Nginx服务出现413 Request Entity Too Large的问题

image.png

default.conf 文件内容:

server {
    listen       80;
    server_name  localhost;
    charset utf-8;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        try_files $uri $uri/ /index.html; #防止页面刷新404问题
    }

    location /api {
        proxy_pass http://192.168.1.1:9999/api;
        # access_log "logs/test.log";
        proxy_set_header    X-Real-IP        $remote_addr;
        proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
        proxy_set_header    HTTP_X_FORWARDED_FOR $remote_addr;
        proxy_set_header    X-Forwarded-Proto $scheme;
        proxy_redirect      default;
    }
}

这里简单说明下default.conf 文件,这里监听的是80端口,包含了两个转发规则,一个是根路径"/",一个是"/api",也就是说,当访问服务器的80端口时,走的是这个路由配置,如果前缀是"/api"是走的是下面的代理 proxy_pass

其中charset utf-8;,这个是必须要加的,否则浏览器打开页面时,如果html的title为中文,则有可能会出现乱码的情况。或者nginx映射的静态资源文件夹下面的文件名包含中文,也是会乱码的。

image.png

由于上面我们映射了容器的目录到本地,所以我们还需要新建一个欢迎页,因为nginx默认的欢迎页,没有自动映射出来,就很郁闷。

在nginx的文件夹下,新建index.html,一个最简单的html文件,内容如下:

<!DOCTYPE html>
<html>
<head>
    <title>网页标题</title>
</head>
<body>
    <h1>Hello Nginx.......</h1>
</body>

</html>

准备完成,下面就可以启动nginx了。

启动nginx镜像的命令:

docker run --privileged=true \
  --restart=always \
  --name nginx \
  -d -p 80:80 \
  -v /usr/soft/nginx/html:/usr/share/nginx/html \
  -v /usr/soft/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v /usr/soft/nginx/conf.d:/etc/nginx/conf.d \
  nginx
  1. 第一个“-v”,是项目位置,把项目放到挂载到的目录下即可
  2. 第二个“-v”,是挂载的主配置文件"nginx.conf",注意"nginx.conf"文件内有一行 "include /etc/nginx/conf.d/*.conf;" ,这个include指向了子配置文件的路径,此处注意include后所跟的路径一定不能出错
  3. 第三个“-v”,把docker内子配置文件的路径也挂载了出来,注意要与 “2.” 中include指向路径一致
  4. nginx.conf是挂载了一个文件(docker是不推荐这样用的),conf.d挂载的是一个目录

这里映射目录之后,我们直接操作宿主机上的文件夹,即是修改了docker容器内的文件,如果修改之后未生效,我们可以重新启动容器就好了,这点还是很方便的。

启动成功,如果不报错,那么访问本机的80端口,应该可以看到我们自定义的欢迎页了。

image.png

今天遇到一个坑,感觉是在是 有点坑了,明明已经知道自定义的配置文件对应的是镜像中的nginx的了,但是这个知识点并没有走到自己心里去。

今天部署另一台服务器,打算将项目部署在8080端口的,那还不好整么,直接将上面的docker运行命令,第一个80端口改为8080,然后default.conf配置文件,监听的端口,改为8080,然后重启docker容器,一气呵成,稳稳当当,结果打开浏览器访问,死活就是访问不通,这给我气的,以为防火墙问题,但是防火墙在关闭状态。

结果过了个周末,又倒腾这个,想着8080端口不行,那我换台服务器还用80端口跑,看你行不行

结果发现80端口正常,好了,换8080!!!!

这次直接修改了启动命令,将name改了下,映射的服务器端口改成8080,直接在浏览器里面访问,结果竟然正常了,这时才恍然大悟,换端口就换端口,根本没必要修改default.conf配置文件监听的端口啊。。。。。。。。。。。毕竟那玩意对应的镜像内部的nginx。。。。。。。。。。

傻了傻了。。。。。

三、异常问题

1. 启动nginx报错:Error response from daemon: driver failed programming external connectivity on endpoint nginx

image.png 重启docker

image.png

2. 容器名称被占用:Error response from daemon: Conflict. The container name "/nginx" is already in use by container

image.png 由于之前启动失败了一次,这个名字被上一个失败的容器给占用了,解决方法有两种: 一种是修改启动命令里面--name 后面的值,定义新的名字。 二、删除之前启动失败的镜像容器 查看之前容器ID,并删除:

docker ps -a

image.png 删除之后,再次启动:

image.png 返回一个ID串,说明启动成功了,否则会有异常信息提示。

3. 启动nginx成功后,访问欢迎页,提示403 Forbidden

image.png

这个问题就很诡异了,搜了一下发现网上有人说是启动容器挂载的目录没有权限,可是启动命令里面命名添加了"--privileged=true"的。

最后查到是需要添加selinux规则,将要挂载的目录添加到白名单:

chcon -Rt svirt_sandbox_file_t + 挂载的目录

这里我直接将整个宿主机上的nginx文件夹添加到白名单了:

image.png

这时重启容器,仍然是403的问题,需要我们将这次启动的容器给删掉,然后重新运行启动容器命令。

image.png

还有一种原因就是当前文件的权限问题,如果文件夹的权限有问题,nginx也是会出现403的问题的。 正常文件夹权限应该是"drwxr-xr-x. 6"

4.如何自定义修改根目录映射的欢迎页位置?

上面我们直接在nginx文件夹下新建了index.html文件,但是实际项目我们打包之后,可能上层还有一个项目的名称作为文件夹呢,或者vue项目,打包之后是dist文件下面才是index.html文件。

修改default.conf 文件中,根目录index映射的规则。

image.png

这里"safety-project"即为我这里的项目名,项目名下面的index为项目的首页。

参考文章:CentOS7中Docker文件挂载的权限 www.cnblogs.com/hailun1987/…