preface

In this article, we have implemented a Docker container that uses a domain name to access different web projects.

Take it a step further and use HTTPS to access multiple projects to improve security.

In addition, it should be mentioned again that our current framework structure is multiple different nginx containers under Docker to manage projects, not the same as the traditional server directly configure Nginx to manage multiple projects, but a layer of Docker loading.

While it may be easier and more convenient to deploy nginx directly on the server in most cases, learn more about port forwarding, redirection, host networking, and more in order to learn about diversified, virtualized Docker + Nginx.

Of course, you can also use docker+ single nginx container method, just need to combine the configuration file is OK, actually a little easier. But if we want to isolate to manage different services and web sites, go deeper and understand the internals. At present is still docker+ multiple nginx service to achieve the way.

Nginx typically deploys multiple projects in three ways:

1. Use secondary domain names to configure different items

2. Use different ports to configure different projects

3. Use different URL paths to configure different projects

For details, see Deploying Multiple front-end projects with Nginx

[TOC]

harvest

By the end of this article you will have learned:

  • Docker under the application of free automatic renewal of the certificate
  • Secondary domain name access to different items
  • Nginx configuration HTTPS

expect

Keep999.cn is a level 1 domain name, through which to access my friend’s project, and through HTTPS protocol, HTTP request forward to HTTPS request

A.keep999.cn is a secondary domain name, through which I access my project and use HTTPS protocol. HTTP requests are forwarded to HTTPS requests

To the chase

Docker uses arme.sh to apply for free certificates

Arme. sh is free to apply for certificates and we will use it to apply for certificates.

The main thing arme.sh does is apply for certificates, and periodically check and apply for certificates through a cronJob script

However, the special situation is that we need to run the script of application and renewal in Docker.

If you use the arme.sh method Run acme.sh in docker

There are two ways to apply for a certificate:

1, the HTTP

2. DNS authentication

HTTP requires port 80 to be free, and my port 80 is already occupied (nginx service), so I can only use DNS

I am Aliyun, if you are another cloud, you can see the usage here: How to Use DNS API

1. Apply for Aliyun AccessKey

Ali cloud server DNS authentication, is to apply for an accessKey and accesSecret

2, Docker run arme.sh

Docker run --rm -itd \ -v "$(PWD)/out":/acme.sh \ -e Ali_Key= accessKey \ -e Ali_Secret= accessSecret \ --net=host \ --name=acme.sh \ neilpang/acme.sh daemonCopy the code

Note that by changing the -e environment variable to your own, the generated certificate will be in your PWD (current directory) out directory

After that, you can use the arme.sh command to apply for the certificate

3. Apply for a certificate

Create your own directory to manage certificates

mkdir /mydockerdata/arme
Copy the code

Go to the directory for managing certificates

cd /mydockerdata/arme
Copy the code

To apply for the certificate

docker exec acme.sh --issue --dns dns_ali -d *.keep999.cn -d keep999.cn
Copy the code

Note: I am applying certificate for my domain name and its secondary domain name

root@keep999:/mydockerdata# cd arme/ root@keep999:/mydockerdata/arme# ls out root@keep999:/mydockerdata/arme# cd out/ root@keep999:/mydockerdata/arme/out# ls account.conf ca http.header *.keep999.cn root@keep999:/mydockerdata/arme/out# cd  \*.keep999.cn/ root@keep999:/mydockerdata/arme/out/*.keep999.cn# ls backup ca.cer fullchain.cer *.keep999.cn.cer *.keep999.cn.conf *.keep999.cn.csr *.keep999.cn.csr.conf *.keep999.cn.key root@keep999:/mydockerdata/arme/out/*.keep999.cn#Copy the code

Your accessKey and accessSecret are in account.conf

Well, the certificate is in *.keep999.cn

Cer and ***. Keep999.cn. Key **

Docker + nginx to manage

Let me first introduce the specific architecture

1. Configure my project nginx

docker run -p 8080:443 --name mynginx -v /mydockerdata/nginx/log/:/var/log/nginx \ -v /mydockerdata/nginx/etc/nginx/nginx.conf:/etc/nginx/nginx.conf \ -v /mydockerdata/nginx/dist/:/usr/share/nginx/html \ -v  /mydockerdata/arme/out/*.keep999.cn/:/etc/nginx/cert \ -d nginxCopy the code

Note: – v/mydockerdata/arme/out / *. Keep999. Cn /, / etc/nginx/cert \ directory is mapping certificate to nginx certificate directory inside the container

Add the configuration file to the server

server {
        listen 443 ssl;
        server_name a.keep999.cn;
        root  /usr/share/nginx/html;           # Project path
        index index.html index.htm;
        ssl_certificate   cert/fullchain.cer;
        ssl_certificate_key  cert/*.keep999.cn.key;
        location / {
            try_files $uri $uri/ /index.html; }}Copy the code
ssl_certificate   cert/fullchain.cer;
ssl_certificate_key  cert/*.keep999.cn.key;
Copy the code

Cert/fullchain-cer is a file in the certificate directory in the relative nginx.conf path

For details on how to generate nginx and mapping configuration files, see Docker Nginx deployment secondary domain name port access multiple Web projects

2. Configure his project nginx

docker run -p 8081:443 --name web_nginx -v /mydockerdata/web_nginx/log/:/var/log/nginx \
-v /mydockerdata/web_nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /var/www/html:/usr/share/nginx/html  \
-v /mydockerdata/arme/out/*.keep999.cn/:/etc/nginx/cert \
-d nginx
Copy the code

Add the configuration file to the server

server {
    listen 443 ssl;
    server_name keep999.cn;
    root  /usr/share/nginx/html;           # Project path
    index index.html index.htm;
    ssl_certificate   cert/fullchain.cer;
    ssl_certificate_key  cert/*.keep999.cn.key;
    location / {
        try_files $uri $uri/ /index.html; }}Copy the code

3. Configure proxy nginx

docker run -p 80:80  -p 443:443 --name proxy_nginx \
-v /mydockerdata/proxy_nginx/log/:/var/log/nginx \
-v /mydockerdata/proxy_nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /mydockerdata/arme/out/*.keep999.cn/:/etc/nginx/cert \
-d nginx
Copy the code

Add configuration files to multiple servers

server {
    listen 80;
    server_name  a.keep999.cn;    # listen to the URL
    rewrite ^(.*)$ https://${server_name}The $1 permanent;
}

server {
     listen 443 ssl;
     server_name  a.keep999.cn;    # listen to the URL
    ssl_certificate   cert/fullchain.cer;
    ssl_certificate_key  cert/*.keep999.cn.key;
    location / {
         proxy_redirect off;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_pass https://a.keep999.cn:8080;
    }

}

server {
    listen 80;
    server_name  keep999.cn;    # listen to the URL
    rewrite ^(.*)$ https://${server_name}The $1 permanent;

}
server {
    listen       443 ssl ;
    server_name  keep999.cn;    # listen to the URL
    ssl_certificate   cert/fullchain.cer;
    ssl_certificate_key  cert/*.keep999.cn.key;
    location / {
           proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass https://keep999.cn:8081; }}Copy the code

Done!

Here is the final plan to write directly to come out, but actually in the process of exploration, has tried various ways, there are many kinds of way will work, because the parcel, the relation between the docker this container port mapping out, many ports will be occupied, such as 80, 443 port, a container, occupy the other containers will not be able to use.

Therefore, the only way to achieve this is to use multiple domain names and different ports to forward.

Docker + single nginx to manage

In fact, we can also use a single Nginx in Docker to manage multiple projects, so that the configuration will be simpler, the implementation is also simpler, but the management of different services, not so flexible. Here, based on the way of secondary domain name to achieve.

docker run -p 80:80  -p 443:443 --name all_nginx \
-v /mydockerdata/all_nginx/log/:/var/log/nginx \
-v /mydockerdata/all_nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /mydockerdata/nginx/dist/:/usr/share/nginx/html1  \
-v /var/www/html:/usr/share/nginx/html2  \
-v /mydockerdata/arme/out/*.keep999.cn/:/etc/nginx/cert \
-d nginx
Copy the code

But mapping to pay attention to the, mydockerdata/nginx/dist / : / usr/share/nginx/html1 mapped to html1 my project,

: / var/WWW/HTML/usr/share/nginx/html2 mapped to html2 another project

Complete configuration file:

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;
    
    server {
        listen 80;
        server_name  a.keep999.cn;    # listen to the URL
        rewrite ^(.*)$ https://${server_name}The $1 permanent;
    }
    
    
    server {
        listen 80;
        server_name  keep999.cn;    # listen to the URL
        rewrite ^(.*)$ https://${server_name}The $1 permanent;
    }
    
    
    server {
            listen 443 ssl;
            server_name a.keep999.cn;
            root  /usr/share/nginx/html1;           # Project path
            index index.html index.htm;
            ssl_certificate   cert/fullchain.cer;
            ssl_certificate_key  cert/*.keep999.cn.key;
            location / {
                try_files $uri $uri/ /index.html;
            }
    }
    
    server {
        listen 443 ssl;
        server_name keep999.cn;
        root  /usr/share/nginx/html2;           # Project path
        index index.html index.htm;
        ssl_certificate   cert/fullchain.cer;
        ssl_certificate_key  cert/*.keep999.cn.key;
        location / {
            try_files $uri $uri/ /index.html;
        }
    }

    include /etc/nginx/conf.d/*.conf;
}
Copy the code

conclusion

I have finished the process of website development -> Docker, Nginx deployment -> HTTP -> HTTPS. I have clearly understood the relationship between Docker and host ports, mapping paths, internal isolation of containers and other joint applications of Docker and other micro services.

I believe you have also harvested a lot, life, learning more than, continue to refueling 💪

About the author

The author is a programmer who loves learning, open source, sharing, spreading positive energy, likes playing basketball, and has a lot of hair. –

Warmly welcome everyone to pay attention to, like, comment exchange!

Jane: www.jianshu.com/u/d234d1569…

github:github.com/fly7632785

CSDN:blog.csdn.net/fly7632785

The Denver nuggets: juejin. Cn/user / 993614…