Here is a record of the docker deployed nginx, access to the host port reported 502 problems, and solutions.

I. Firewall

  1. First make sure that the host firewall is on. If the firewall is off, the container should have direct access to the host’s IP+ port.

For example, in our test environment (Centos 7), the firewall is turned off. Run the firewall-cmd –state or systemctl status firewalld command to check the firewall status. If Active:actice(running) is displayed, the firewall is enabled.

Firewall closed state:In order to facilitate the general test environment, the firewall is directly closed, so that in our usual development and testing, it will indeed be more convenient, but sometimes it is because of the firewall, resulting in our program after production, puzzling problems.

Obviously the test environment is normal, how production is not good…

If the firewall is on, then we need to open certain ports.

firewall-cmd --zone=public --add-port=80/tcp --permanent
Copy the code
--zone # scope --add-port=80/ TCP # Add port. Format: port/protocol --permanentCopy the code
Run the systemctl restart firewalld.service command to restart the firewallCopy the code

View open ports:

netstat -ntlp
Copy the code

firewall-cmd --list-ports
Copy the code

View the port usage: lsof -i: indicates the port number

lsof -i:8000
Copy the code

Here’s the problem with Nginx.

2. Use virtual IP to communicate with container kernel host

Since I am using the Docker installation nginx, and custom configuration file.

Therefore, you can directly change the configuration file when forwarding routes and configuring domain names.

The first step is to configure the domain name. It is very simple to configure the domain name. Just follow the method provided by the domain name provider to get the secret key and key file out, and then put it in the path that nginx can access, and configure the path into the conf file.

Here affixed with the current configuration, for reference only, copy may not work.

The first is to define the configuration file that listens on port 80: default.conf

    upstream cavdWeb {
        server 172.17. 01.:9999;
    }


server {
    listen       80;
    server_name  cavd.org.cn;
    charset utf-8;

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



    location / {
        root   /usr/share/nginx/html;
        index  safety-project/index.html index.htm;
    }

    location /web{
        proxy_pass http://cavdWeb/web;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect default; } #location /download/ { # alias /opt/upload/; # autoindex on; #}}Copy the code

Upstream cavdWeb is used to dynamically proxy ports or IP addresses with fixed prefixes.

172.17.0.1 is not the IP address of the host. This has been messing with me for a long time.

This IP is the COMMUNICATION IP between the docker and the host, which is a virtual IP. The query method is to directly look at the Docker0 in ifconfig

If the firewall is disabled, write the IP address and port of the host directly. If the firewall is powered on, nginx fails to start directly. The failed logs can be viewed using docker logs –since 5m container ID, where 5m indicates the logs in the last 5 minutes.

Next, listen for 443’s configuration file: https.conf


    #upstream cavdWeb {
    #    #server 192.168. 5288.:9999;
    #    server 172.17. 01.:9999;
    #}

    server { 
	listen       443 ssl; 
	server_name  www.baidu.com; 
	#ssl                  on; 
	ssl_certificate      /etc/nginx/cert/server.pem; 
	ssl_certificate_key  /etc/nginx/cert/server.key; 
	ssl_session_timeout  5m; 
	ssl_protocols  TLSv1 TLSv11. TLSv12.; ssl_ciphers HIGH:! RC4:! MD5:! aNULL:! eNULL:! NULL:! DH:! EDH:! EXP:+MEDIUM; ssl_prefer_server_ciphers on; location / { root /usr/share/nginx/html; index safety-project/index.html index.htm; } location /web{ proxy_pass http://cavdWeb/web;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect default; }}Copy the code

Among them:

        ssl_certificate      /etc/nginx/cert/server.pem; 
	ssl_certificate_key  /etc/nginx/cert/server.key; 
Copy the code

Indicates the path and file name of the HTTPS certificate. The path here needs to be accessible to Nginx.

[warn] the "ssl" directive is deprecated, use the "listen ... ssl" directive instead
Copy the code

If you see the above message in the nginx log, it is because nginx from 1.18, the SSL command is not recommended, use listen… SSL. So you can see that the SSL on line is commented out, and you start with listen 443 SSL

If docker is installed directly, set the absolute path. If docker is installed directly, set the absolute path under the mounted directory to ensure that nginx can access it.

Upstream cavdWeb can only be defined once under nginx or it will fail to start.

At first I innocently defined the address in upstream cavdWeb as the host IP or 127.0.0.1. After startup, the access remains 502 Bad Gayteway, or as you can see from the log: host not found in upstream “xxxxxxx”

In the search for a long time online answer is, first of all to see whether the service port is normal, if the service is closed, it is indeed will appear 502 error. When I saw this, I did not think that the service is not open with the service open access, is not the same thing, the result was a long time……

Finally, paste my nginx configuration file: 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;
    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;
}

Copy the code

All configuration files at the end of the conf file in /etc/nginx/conf.d are imported automatically.

Start docker image command:

docker run --privileged=true \
  --restart=always \
  --name nginx \
  -d -p 80:80 \
  -d -p 443:443 \
  -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 \
  -v /usr/soft/nginx/cert:/etc/nginx/cert \
  -v /opt/upload:/opt/upload \
  192.168104.51.:5000/huaun/nginx:test 
Copy the code

The image used here was found online and tagged with its own mirror repository.

Here we map ports 80 and 443, and then use -v to mount the directories we need.