Docker Compose SSL: ติดตั้ง SSL certificate บน nginx container [ล่าสุด 2023]

  • Updated Jan 16, 2023

วิธีการติดตั้ง SSL Certificate บน Nginx โดยใช้ Docker container และสอนการใช้งาน commandline docker compose เบื้องต้น


Requirements

  1. Docker Engine (Linux, Windows, AWS, Azure)
  2. Docker Compose
  3. Docker Images (Nginx)
  4. SSL Certificates file (.crt or .pem)
  5. Private Key file (.key)

Docker compose folder layout สำหรับการติดตั้ง ssl certificate

.nginx-docker/
|____docker-compose.yaml
|____nginx/
| |____ssl/
| | |____coppers.io.key
| | |____coppers.io.pem
| |____conf.d/
|   |____vhost-coppers_io.conf
|____public/
  |____index.php

ขั้นตอนการติดตั้ง ssl certificate บน NGINX container ด้วย Docker compose

1. ทำการติดตั้ง Docker Engine บนเครื่องทดสอบ

เรียบร้อยแล้วทำการตรวจสอบความพร้อมใช้งานของ docker engine โดย run command

$ docker --version
Docker version 18.09.0, build 4d60db4

2. ทำการติดตั้ง docker-compose command line tool เพิ่มเติม

เพิ่มเติมเพื่อใช้สำหรับจัดการและส่ัง run docker container ได้อย่างมีประสิทธิภาพและสะดวกยิ่งกว่าการใช้งาน command ผ่าน docker engine โดยตรง ตรวจสอบการติดตั้งโดย run command

$ docker-compose --version
docker-compose version 1.23.2, build 1110ad01

3. ให้ทำการสร้าง directory ต่างๆตาม Project directory layout

ภายในเครื่อง Host ทดสอบที่ได้ทำการติดตั้ง docker-engine ไว้ซึ่งประกอบด้วย

  1. docker-compose.yaml (เก็บ config ต่าง container)
  2. nginx/ssl/ (เก็บไฟล์ ssl certificates และ private key)
  3. nginx/conf.d/ (เก็บไฟล์ nginx configuration)
  4. public/ (เก็บไฟล์ข้อมูลต่างๆ ของเว็บไซต์เช่นไฟล์ .php)

4. ทำการกำหนดค่า nginx container ที่ต้องการใช้งาน ในไฟล์ docker-compose.yml

ทำการแก้ไขไฟล์ docker-compose.yml ดังตัวอย่าง

version: "2"
services:
  # Nginx webserver
  nginx:
    image: nginx:latest
    restart: always
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
    ports:
      - "80:80"
      - "443:443"
    volumes_from:
      - php

  # PHP-FPM for compile .php file
  php:
    image: php:7.4-fpm-alpine
    restart: always
    volumes:
      - ./public:/var/www/html

คำอธิบาย

  • กำหนด nginx container ในไฟล์ docker-compose.yml โดยใช้ image version ล่าสุดและทำการ map volumes ./nginx จากเครื่อง host ที่ run docker-engine เข้าไปใน nginx container เพื่อสามารถอ่านไฟล์ configuration, ssl certificate และ private key จากภายใน container ได้
  • ในที่นี้เราได้ทำการเพิ่ม php-fpm container ในไฟล์ docker-compose.yml เพิ่มเติมขึ้นมาเพื่อให้เหมือนกับการใช้งานจริงมากยิ่งขึ้น โดยให้ทำการ map volumes ./public เข้าไปใน container ของ php-fpm ให้อยู่ภายใต้ /var/www/html/ เพื่อให้ php-fpm สามารถประมวลผลไฟล์ .php เว็บไซต์ของเราได้

5. เริ่มติดตั้ง ssl certificate โดยวิธีการใช้ docker compose

นำไฟล์ ssl certificate (.pem or .crt) ที่ได้รับจาก SSL Providers/Reseller และ private key (.key) ไปวางไว้ที่โฟล์เดอร์ ./nginx/ssl/

6. ต้ังค่า virtual host บน NGINX container

สร้างไฟล์ nginx configuration (virtual host) ตัวอย่างเช่น vhost-<<domain>>.conf และวางไว้ในโฟล์เดอร์ ./nginx/conf.d/

  • โดยกำหนด server_name เป็นชื่อโดเมนของเว็บไซต์ที่ต้องการ และกำหนด ssl_certificate และ ssl_certificate_key ให้ชี้ไปที่ไฟล์ certificate และ private key ภายใต้ /etc/nginx/ssl/ ซึ่งจะเป็น path ภายใน container ที่ได้ทำการ map volumes ไว้จาก docker host ตามขั้นตอนที่ 4

    ...
    server_name coppers.io www.coppers.io;
    
    ssl_certificate /etc/nginx/ssl/www_coppers_io.pem;
    ssl_certificate_key /etc/nginx/ssl/www_coppers_io.key;
    ...
    
  • ทำการ redirect จาก http ไปที่ https ดังนี้โดยกำหนด server_name และ return 301 https://<<domain>>$request_uri;

    ...
    server {
      listen 80;
      listen [::]:80;
      server_name coppers.io www.coppers.io;
      return 301 https://www.coppers.io$request_uri;
    }
    
  • « Nginx Full Configuration »

    server {
        listen 443 ssl http2 default_server;
        listen [::]:443 ssl http2 default_server;
        server_name coppers.io www.coppers.io;
    
        ssl_certificate /etc/nginx/ssl/www_coppers_io.pem;
        ssl_certificate_key /etc/nginx/ssl/www_coppers_io.key;
    
        root /var/www/html;
        index index.php index.html;
    
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
        location ~ \.php {
            fastcgi_index index.php;
            fastcgi_pass php:9000;
    
            include fastcgi_params;
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        }
    }
    server {
        listen 80;
        listen [::]:80;
        server_name coppers.io www.coppers.io;
        return 301 https://www.coppers.io$request_uri;
    }
    

7. ทำการ start nginx และ php container ดัวย command docker-compose ดังต่อไปนี้

$ docker-compose up -d
Creating network "nginx-docker_default" with the default driver
Creating nginx-docker_php_1 ... done
Creating nginx-docker_nginx_1 ... done

หมายเหตุ: เครื่อง docker-engine ที่ยังไม่เคยทำการ download images มาก่อนให้รอ docker-engine ทำการ pull image จาก Docker Hub สักครู่

8. ตรวจสอบสถานะ container ที่ได้สร้างไว้ดังนี้

$ docker-compose ps
        Name                      Command              State                      Ports
----------------------------------------------------------------------------------------------------------
nginx-docker_nginx_1   nginx -g daemon off;            Up      0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
nginx-docker_php_1     docker-php-entrypoint php-fpm   Up      9000/tcp

ให้สังเกตุตรงคอลัมน์ State จะต้องแสดงเป็น Up ทุก container หากไม่แสดงให้ตรวจสอบ log ของ container โดย command$ docker-compose logs <<container_name>>

9. ทดสอบเข้าเว็บไซต์ที่ได้ทำการสร้างผ่าน Web Browser

ตรวจสอบการติดตั้ง SSL Certificate โดยการกดสัญลักษ์รูปกุญบน Address bar ของ Web Browser!

Nginx SSL Certificate - Verify

  1. Install Docker CE for CentOS | Docker Documentation
  2. Install Docker CE for Ubuntu | Docker Documentation
  3. Install Docker for Windows | Docker Documentation
  4. Install Docker Compose | Docker Documentation