ทดลองใช้งาน Docker พื้นฐาน #4

จากครั้งที่แล้ว เราสามารถทำเว็ปไซต์ง่ายๆขึ้นมาได้แล้ว แต่ถ้าหากเราต้องการมีมากกว่าเพียง 1 เว็ปไซต์ละ (ในเครื่องๆเดียว และแยก domain name หรือ sub domain name) นอกจากนี้ยังมีการเพิ่มในส่วนของความปลอดภัยขึ้นมาด้วย นั่นคือการใช้ HTTPS หรือ SSL ช่วยด้วยนั่นเอง
เริ่มกันเลย !~
สร้าง Folder nginx_proxy_dock และภายใต้นั้นให้แก้ไขดังนี้
nginx_proxy_dock/docker-compose.yml
version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy:alpine
container_name: nginx-proxy
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- certs:/etc/nginx/certs:ro
- dhparam:/etc/nginx/dhparam
- /var/run/docker.sock:/tmp/docker.sock:ro
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: nginx-proxy-lets
volumes_from:
- nginx-proxy
volumes:
- certs:/etc/nginx/certs:rw
- /var/run/docker.sock:/var/run/docker.sock:ro
depends_on:
- nginx-proxy
volumes:
vhost:
html:
certs:
dhparam:
networks:
default:
external:
name:
webproxy
จาก config จะเห็นว่ามี 2 service ซึ่งมีการทำงานดังนี้
nginx-proxy ทำงานเป็น Reverse Proxy เพื่อส่งต่อ Request ไปยัง service ภายในต่างๆ
letsencrypt เป็นตัวคอยออกใบ Certificate ให้เว็ปมีความปลอดภัยมากขึ้น (HTTPS)
หลังจากนั้นสั่งให้ docker-compose ทำงานรอไว้เลย
docker-compose up -d
ต่อไปจะเป็นในส่วนของเว็ปไซต์ ต่อจากคราวที่แล้ว หรือจะ clone ไปตามนี้ก็ได้
git clone http://gitlab.cpsudevops.com/nuttachot/www_dock.git website1
แก้ไข website1/docker-compose.yml
version: '3'
services:
php:
container_name: lemp_php
build: php/
restart: unless-stopped
volumes:
- ./html/:/var/www/html
expose:
- "9000"
depends_on:
- db
nginx:
container_name: lemp_nginx
image: nginx:stable-alpine
restart: unless-stopped
networks:
- webproxy
- default
environment:
VIRTUAL_HOST: www.lab10.cpsudevops.com
LETSENCRYPT_HOST: www.lab10.cpsudevops.com
volumes:
- ./html/:/var/www/html
- ./nginx/conf/nginx.conf:/etc/nginx/conf/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
expose:
- "80"
db:
container_name: lemp_mariadb
image: mariadb:latest
restart: unless-stopped
volumes:
- ./mariadb/initdb/:/docker-entrypoint-initdb.d
- ./mariadb/data/:/var/lib/mysql/
environment:
- MYSQL_ROOT_PASSWORD=devops101
- MYSQL_DATABASE=devops_db
- MYSQL_USER=devops
- MYSQL_PASSWORD=devops101
networks:
default:
external:
name:
web_network
webproxy:
external:
name: webproxy
ในที่นี้มีการ config domain name ทุก sub domain ที่กล่าวถึงไว้ทั้งหมด ไปที่ที่เดียวแล้ว เพราะฉะนั้นอย่าลืมไป config ใน DNSด้วย
และแก้ไขไฟล์ website1/html/index.php เพื่อให้แสดงว่าเราเข้าถึงมาจาก domain name ไหน
<?php
$servername = "db";
$username = "devops";
$password = "devops101";
$dbhandle = mysqli_connect($servername,$username,$password);
$selected = mysqli_select_db($dbhandle, "titanic");
echo "Connected database server<br>";
echo "Selected database<br>";
echo $_SERVER['HTTP_HOST'];
?>
จากนั้นให้ทำการ start service ข้างต้น
docker-compose up -d
จากนั้นให้ลองเข้า lab10.cpdudevops.com จะพบ

ซึ่งไม่ต้องตกใจ เพราะที่เราทำการตั้งค่าไว้นั่นคือ www.lab10.cpdudevops.com ซึ่งหากเข้าตาม url ด้านบนแล้วก็จะพบกับแบบนี้

ซึ่ง www นั้นคือ sub domain name นั่นเอง หากหลายคนยังไม่ทราบ ต่อไปลองเปิดเพิ่มอีกเว็ปไซต์โดยเริ่มดังนี้ (repeat ขั้นตอนคล้ายๆของเดิม)
git clone http://gitlab.cpsudevops.com/nuttachot/www_dock.git website2
เพียงแต่แก้ไขไฟล์ docker-compose.yml ดังนี้ เพื่อหลีกเลี่ยงชื่อ container ซ้ำกันและเปลี่ยนชื่อ subdomain name
website2/docker-compose.yml
version: '3'
services:
php:
container_name: lemp_php2
build: php/
restart: unless-stopped
volumes:
- ./html/:/var/www/html
expose:
- "9000"
depends_on:
- db
nginx:
container_name: lemp_nginx2
image: nginx:stable-alpine
restart: unless-stopped
networks:
- webproxy
- default
environment:
VIRTUAL_HOST: service.lab10.cpsudevops.com
LETSENCRYPT_HOST: service.lab10.cpsudevops.com
volumes:
- ./html/:/var/www/html
- ./nginx/conf/nginx.conf:/etc/nginx/conf/nginx.conf:ro
- ./nginx/conf.d:/etc/nginx/conf.d:ro
expose:
- "80"
db:
container_name: lemp_mariadb2
image: mariadb:latest
restart: unless-stopped
volumes:
- ./mariadb/initdb/:/docker-entrypoint-initdb.d
- ./mariadb/data/:/var/lib/mysql/
environment:
- MYSQL_ROOT_PASSWORD=devops101
- MYSQL_DATABASE=devops_db
- MYSQL_USER=devops
- MYSQL_PASSWORD=devops101
pma:
container_name: lemp-phpmyadmin2
image: phpmyadmin/phpmyadmin
restart: always
networks:
- webproxy
- default
environment:
VIRTUAL_HOST: mydb2.lab10.cpsudevops.com
LETSENCRYPT_HOST: mydb2.lab10.cpsudevops.com
expose:
- "80"
networks:
default:
external:
name:
web_network2
webproxy:
external:
name: webproxy
และใช้คำสั่ง เพื่อสร้าง network ขึ้นมาอีกตัว เพราะถือว่าเป็นคนละ service กัน
docker network create web_network2
และหากสังเกตละก็ จะเห็นว่าได้มีการเพิ่ม phpMyAdmin(pma) เข้ามาด้วย เพื่อง่ายต่อการจัดการกับ database

แน่นอนว่าตัว Portainer ก็เป็น Web base ซึ่งก็สามารถทำได้เช่นกันโดยแก้ไขไฟล์เก่าหรือเพิ่มไฟล์ดังนี้
port_dock/docker-compose.yml
version: '3'
services:
portainer:
container_name: ${CONTAINER_NAME}
restart: unless-stopped
image: portainer/portainer
volumes:
- portainer_data:/data
- vhost:/etc/nginx/vhost.d
- html:/usr/share/nginx/html
- certs:/etc/nginx/certs:ro
- dhparam:/etc/nginx/dhparam
- /var/run/docker.sock:/var/run/docker.sock
environment:
VIRTUAL_HOST: ${DOMAINS}
LETSENCRYPT_HOST: ${DOMAINS}
expose:
- "9000"
volumes:
portainer_data:
vhost:
html:
certs:
dhparam:
networks:
default:
external:
name: ${NETWORK}
.env
CONTAINER_NAME=portainer
PORTAINER_DATA_PATH=/portainer/data
DOMAINS=port.lab10.cpsudevops.com
NETWORK=webproxy
และสั่งรันมันด้วย
docker-compose up -d

จากการได้ใช้งาน พบปัญหาที่ตัว Let’s Encrypt นั้นมี Rate limit ในการทำ HTTPS เพราะ Domain name มีการแบ่งใช้งานกับคนในชั้นเรียน อ่านรายละเอียดเพิ่มเติมได้ที่ https://letsencrypt.org/docs/rate-limits/