Requirement: only one cloud host, but multiple sites with different domain names, and even secondary domain names. Access only by domain name (or secondary domain name). You also need to enable HTTPS (automatic certificate renewal after expiration). Site content is static file (currently tentative), docker deployment. The original HTTPD image is used, but the site files are mounted for easy updating. Management and publishing, use GitLab or Github to manage website source files, build static files through CI, and automatically update to the cloud host.

directory

Create the directory/home/latelee/docker/composefile/websites, consists of vhost. D, acme, certs directory, create website file mount directory, such as html1, html2, html_latelee.org, and so on.

Cloud hosting

The mapping between subdomain names and IP addresses must be added on the domain name background console. Otherwise, the domain name cannot be accessed. Ports 80 and 443 must be enabled on the cloud host.

The deployment of

Docker-compose is deployed for ease of administration.

The reverse proxy

proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    restart: always
    ports:
      - 80:80
      - 443:443
    labels:
      com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
    volumes:
      - ./certs:/etc/nginx/certs:ro
      - ./acme:/acmecerts
      - ./vhost.d:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - /var/run/docker.sock:/tmp/docker.sock:ro
    networks:
Copy the code

Use the image name jwilder/nginx-proxy, visit the official website for documentation. Which need to be mapped ports 80 and 443, tag com. Making. The JRCS. Letsencrypt_nginx_proxy_companion. Nginx_proxy is a must, Otherwise, letsencrypt-nginx-proxy-companion cannot connect to the proxy container. For ease of administration, most mount directories are in the current directory. Note that certs is read-only.

HTTPS authentication

letsencrypt-companion:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: letsencrypt
    restart: always
    volumes:
      - ./certs:/etc/nginx/certs
      - ./vhost.d:/etc/nginx/vhost.d
      - ./html:/usr/share/nginx/html
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - nginxp-net
    depends_on:
      - proxy
Copy the code

To use the image JRCS /letsencrypt-nginx-proxy-companion, visit the official website for details. The mount directory is also required, where the automatically created certificate is located in the CERts directory. (Question: The validity period of the certificate is three months, will it be renewed automatically?) Note: there are instructions on the official website to mount acme.sh file, currently not in use. Note 2: When the container is running, it will sleep automatically for one hour and then check the validity of the certificate. As long as the container does not exit, the certificate is automatically updated. Whether this is the case, follow-up supplement.

Web service container

The first two items are the basic content, set generally do not change, the need to provide web site services also use container deployment.

  http1:
    image: httpd
    container_name: httpd1
    volumes:
      - ./html1:/usr/local/apache2/htdocs/
    environment:
      - VIRTUAL_HOST=latelee.org,www.latelee.org
      - LETSENCRYPT_HOST=latelee.org,www.latelee.org
      - [email protected]
      - ENABLE_ACME=true
    networks:
      - nginxp-net
Copy the code

Mount the current directory HTML1 is the apache service root directory, which contains static website files. Note that since HTTPD only exposes port 80, there is no need to specify the value of VIRTUAL_PORT here; the reverse proxy container automatically specifies this port. VIRTUAL_HOST and LETSENCRYPT_HOST specify host domain names. Multiple host names can be specified, separated by commas (,). For ease of understanding, a domain name without a prefix and with WWW is usually specified. LETSENCRYPT_EMAIL Specifies an email address for receiving emails sent by LETsENCRYPT.

This is a template that can be added as needed. Such as:

  http2:
    image: httpd
    container_name: httpd2
    volumes:
      - ./html1:/usr/local/apache2/htdocs/
    environment:
      - VIRTUAL_HOST=i.latelee.org
      - LETSENCRYPT_HOST=i.latelee.org
      - [email protected]
      - ENABLE_ACME=true
    networks:
      - nginxp-net
Copy the code

Start the

Run the following command to start:

docker-compose up -d
Copy the code

You can start or stop individual services, for example:

docker-compose up -d http2
docker-compose stop http2
docker-compose start http2
Copy the code

Using the record

2021.1.4 When the certificate expires, letsENCRYPT fails to run. The cause cannot be found from the error information. Update the image and restart the system to automatically update the certificate. Container initialization log:

Info: Running letsencrypt-nginx-proxy-companion version v2.0.2-19-g5d890e7 Warning: '/etc/acme.sh' does not appear to be a mounted volume. Info: Custom Diffie-Hellman group found, generation skipped. Reloading nginx proxy (c75452210276c1003b86356fa10266d6939cac2f331bd89a12f0abed16a1221f)... 2021/01/05 16:18:06 Contents of /etc/nginx/conf.d/default.conf did not change. Skipping notification '' 2021/01/05 16:18:06 [notice] 59#59: signal process started Warning: /app/letsencrypt_service_data not found, skipping data from containers. Reloading nginx proxy (c75452210276c1003b86356fa10266d6939cac2f331bd89a12f0abed16a1221f)... 2021/01/05 16:18:08 Generated '/etc/nginx/conf.d/default.conf' from 13 containers 2021/01/05 16:18:08 [notice] 81#81: signal process started Sleep for 3600s 2021/01/05 16:18:09 Generated '/app/letsencrypt_service_data' from 13 containers 2021/01/05 16:18:09 Running '/app/signal_le_service' 2021/01/05 16:18:09 Watching docker events 2021/01/05 16:18:09 Contents of /app/letsencrypt_service_data did not change. Skipping notification '/app/signal_le_service' ... Creating/renewal i.latelee.org certificates... (i.latelee.org) [Tue Jan 5 16:20:23 UTC 2021] Using CA: https://acme-v02.api.letsencrypt.org/directory [Tue Jan 5 16:20:23 UTC 2021] Creating domain key [Tue Jan 5 16:20:24 UTC  2021] The domain key is here: /etc/acme.sh/[email protected]/i.latelee.org/i.latelee.org.key [Tue Jan 5 16:20:24 UTC 2021] Single domain='i.latelee.org' [Tue Jan 5 16:20:24 UTC 2021] Getting domain auth token for each domain [Tue Jan 5 16:20:30 UTC 2021] Getting webroot for domain='i.latelee.org' [Tue Jan 5 16:20:30 UTC 2021] Verifying: i.latelee.org [Tue Jan 5 16:20:35 UTC 2021] Pending [Tue Jan 5 16:20:38 UTC 2021] Pending [Tue Jan 5 16:20:41 UTC 2021] Pending [Tue Jan 5 16:20:45 UTC 2021] Success [Tue Jan 5 16:20:45 UTC 2021] Verify finished, start to sign. [Tue Jan 5 16:20:45 UTC 2021] Lets finalize the order. [Tue Jan 5 16:20:45 UTC 2021] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/108459963/7141145386' [Tue Jan 5 16:20:47 UTC 2021]  Downloading cert. [Tue Jan 5 16:20:47 UTC 2021] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/03f5858c596c2ee39ba44bb4cda7e5a26c1e' [Tue Jan 5 16:20:55 UTC 2021] Cert success. -----BEGIN CERTIFICATE----- MIIGasdflaksdjfiaskdfjG*Y#@RF&lSDFDFDSFDSF dfdf3w#KFHDGFLDFUEIHGDLGDSgfSLDKHFDSLHGLDS ... -----END CERTIFICATE----- [Tue Jan 5 16:20:55 UTC 2021] Your cert is in /etc/acme.sh/[email protected]/i.latelee.org/i.latelee.org.cer [Tue Jan 5 16:20:55 UTC 2021] Your cert key is in /etc/acme.sh/[email protected]/i.latelee.org/i.latelee.org.key [Tue Jan 5 16:20:55 UTC 2021] The intermediate CA cert is in  /etc/acme.sh/[email protected]/i.latelee.org/ca.cer [Tue Jan 5 16:20:55 UTC 2021] And the full chain certs is there: /etc/acme.sh/[email protected]/i.latelee.org/fullchain.cer [Tue Jan 5 16:20:55 UTC 2021] Installing cert to:/etc/nginx/certs/i.latelee.org/cert.pem [Tue Jan 5 16:20:55 UTC 2021] Installing CA to:/etc/nginx/certs/i.latelee.org/chain.pem [Tue Jan 5 16:20:55 UTC 2021] Installing key to:/etc/nginx/certs/i.latelee.org/key.pem [Tue Jan 5 16:20:55 UTC 2021] Installing full chain to:/etc/nginx/certs/i.latelee.org/fullchain.pemCopy the code

Check some updated logs as follows:

# docker logs -f --tail 100 letsencrypt
Creating/renewal www.latelee.org certificates... (www.latelee.org)
[Tue Jan  5 23:25:33 UTC 2021] Domains not changed.
[Tue Jan  5 23:25:33 UTC 2021] Skip, Next renewal time is: Sat Mar  6 16:23:29 UTC 2021
[Tue Jan  5 23:25:33 UTC 2021] Add '--force' to force to renew.
Sleep for 3600s
Creating/renewal i.latelee.org certificates... (i.latelee.org)
[Wed Jan  6 00:25:37 UTC 2021] Domains not changed.
[Wed Jan  6 00:25:37 UTC 2021] Skip, Next renewal time is: Sat Mar  6 16:20:55 UTC 2021
[Wed Jan  6 00:25:37 UTC 2021] Add '--force' to force to renew.
Copy the code

As you can see, check every hour and continue sleeping if no update is needed. Mandatory updates are also possible (but not necessary).