OCI 에서 제공되는 무료 서버를 이용하여 nginx(x86) – was(arm64) – DB(arm64) 으로 잘 사용하고 있었다. (물론 앞으로도 잘 사용할 예정…)
기존엔 snapd(certbot) 도 arm64에서 정상 동작지 않았고 http3를 구현한 nginx도 베타 였으나 현재는 mainline-quic 으로 되었기 때문에
native-arm64 환경으로 이행을 통해 메모리가 적어서 상대적으로 속도가 느렸던 x86서버를 버리기 위해서 아래와 같은 목표를 구현하는 것을 목표로 잡았다.
- Docker – Was(http,php-fpm) 의 OS를 amazonlinux2 -> rockylinux9 으로 변경 및 php-8.3 사용
- Docker – rockylinux9 – nginx-quic(http3) 구축
- Docker x86_64(amd64), arm64(aarch64) 을 지원
-
Docker 설치
베이스 OS는 rockylinux 9 (aarch64)이며, 서버에 docker 를 설치하고 활성화 한다. (Install Docker Desktop on RHEL)
1 2 3 |
~]# dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo ~]# dnf -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin ~]# systemctl enable --now docker.service |
Was 컨테이너 안에서 웹서비스가 apache:apache 권한 으로 동작 되기 때문에 아래와 같이 베이스 os에 같은 유져를 생성 한다.
(바깥에서 단순 UID 48으로 지정해 운영 해도 된다.)
1 2 3 4 |
~]# groupadd -g 48 apache ~]# useradd -s /sbin/nologin -u 48 -g apache -d /usr/share/httpd -c Apache apache ~]# mkdir -p /var/www/html ~]# chown -R apache:apache /var/www/html |
-
배포된 Docker 이미지를 이용한 apache, php 사용
https://hub.docker.com/r/san0123/rocky9-http-php
웹서버 또는 개발자 PC (windows)에서 공통으로 사용할 수 있도록 생성한 Docker 이미지 이다.
도커는 pull 을 별도로 하지 않더라도 정확한 주소를 사용할 경우 자동으로 pull 하는 기능이 있으므로 바로 run 을 실행 한다.
nginx 가 80,443 을 사용할 예정이기 때문에 9000번 포트를 이용해 run 한다.
1 2 3 4 5 6 |
~]# docker run -d --name main_site \ -p 9000:80 \ --restart unless-stopped \ --add-host host.docker.internal:host-gateway \ -v /var/www/html:/var/www/html \ san0123/rocky9-http-php:8.3 |
웹소스를 호스트os의 /var/www/html에 넣으면 호출을 할수 있다.
파일을 복사해 넣거나 압축을 해제한 후에는 chown -R apache:apache 파일명or폴더
을 잊지 말자…
배포된 rocky8-httpd-php, rocky9-httpd-php 에서 CI4(code igniter 4) 사용법
1 2 3 4 |
~]# docker exec main_site composer create-project codeigniter4/appstarter html ~]# sudo docker exec main_site chown -R apache: html ~]# docker exec main_site sed -i "s+DocumentRoot \"/var/www/html+DocumentRoot \"/var/www/html/public+g" /etc/httpd/conf/httpd.conf ~]# docker restart main_site |
일반적인 CMS테스트를 위할 경우 여기 까지만 진행 하고 웹서버를 서비스 하고자 할때 아래 부분까지 진행 한다.
-
배포된 Docker 이미지를 이용한 Nginx 사용
https://hub.docker.com/r/san0123/rocky9-nginx
웹서버에서 http3 를 구현하기 위해서 apache 앞에 nginx를 사용하고 Let’s encrypt(certbot) 을 사용하기 위한 Docker 이미지 이다.
Nginx 도커를 이용한 http2를 위해 80/tcp, 443/tcp 그리고 http3를 위해 443/udp 을 파이어월에서 허용 한다.
1 2 3 4 |
~]# firewall-cmd --add-service=http --permanent ~]# firewall-cmd --add-service=https --permanent ~]# firewall-cmd --add-port=443/udp --permanent ~]# firewall-cmd --reload |
웹용 도커는 베이스OS에서 virtualhost 설정 파일 을 저장해서 버전 업데이트시 설정 파일을 새로 설정 하지 않기 위해 mount 하기 때문에 먼저 생성을 한뒤 docker run 을 해야 한다.
1 2 |
~]# mkdir -p /var/www/conf ~]# touch /var/www/conf/virtual.conf |
Nginx용 도커를 실행 한다. 컨테이너를 재 생성 할때마다 인증서나 가상호스트 파일을 수정하지 않도록 두개의 마운트 포인트를 추가해서 실행한다.
1 2 3 4 5 6 |
~]# docker run -d --name nginx_docker \ -p 80:80 -p 443:443 -p 443:443/udp \ --restart unless-stopped \ -v /etc/letsencrypt:/etc/letsencrypt \ -v /var/www/conf/virtual.conf:/etc/nginx/conf.d/virtual.conf \ san0123/rocky9-nginx |
도메인을 서버에 연결 한 뒤에 Let‘s encrypt 를 생성하는 명령어는 다음과 같다. (email, domain 은 자신에 맞게 수정해서 사용한다.)
1 2 3 4 |
~]# docker exec nginx_docker /usr/local/bin/certbot certonly \ --server https://acme-v02.api.letsencrypt.org/directory --rsa-key-size 4096 --agree-tos \ --email 이메일@주소.com --webroot -w /var/www/html \ -d www.도메인.com -d 도메인.com -d grafana.도메인.com |
베이스OS 에서 /var/www/conf/virtual.conf 를 자신의 url에 맞게 수정하고 발급된 인증서가 동작할 수 있도록 수정을 한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
### http server server { listen 80; server_name www.도메인.com 도메인.com grafana.도메인.com; include security_params; include security_method_params; location ^~ /.well-known/acme-challenge/ { root /var/www/html/; } location / { rewrite ^ https://$host$request_uri? permanent; } } ### http2 set for example.com -> www.example.com ### server { listen 443 ssl; server_name 도메인.com; include http2_params; ssl_certificate /etc/letsencrypt/live/www.도메인.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.도메인.com/privkey.pem; add_header Strict-Transport-Security 'max-age=31536000; preload'; location / { return 301 https://www.$server_name$request_uri; } } ### http3 only one site ### server { listen 443 ssl; listen 443 quic reuseport; server_name www.도메인.com; include security_params; include security_method_params; include http2_params; include http3_params; ssl_certificate /etc/letsencrypt/live/www.도메인.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.도메인.com/privkey.pem; add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload'; location / { include proxy_params; proxy_pass http://host.docker.internal:9000; } } ### http2 other site ### server { listen 443 ssl; server_name grafana.도메인.com; include security_params; include http2_params; ssl_certificate /etc/letsencrypt/live/www.도메인.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/www.도메인.com/privkey.pem; add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload'; if ( $request_method !~ ^(GET|POST|PUT|DELETE|HEAD|OPTIONS)$ ) { return 405; } allow 123.123.123.123/32; deny all; location /api/live/ { proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://host.docker.internal:3000; } location / { include proxy_params; proxy_pass http://host.docker.internal:3000; } } |
nginx를 재시작 하기 위해서 컨테이너를 재시작 한다.
1 |
~]# docker restart nginx_docker |
http3가 잘 활성화 되어있는지 확인 한다. ( https://http3check.net/)
인증서가 약 2-3개월 마다 갱신해야 하기 때문에 cronatb에 아래와 같이 등록해서 주기적인(주1회) 인증서 업데이트 및 적용을 위한 재시작을 한다. (매주 월요일 오전 8시)
1 |
00 08 * * 1 /bin/docker exec nginx_docker /usr/local/bin/certbot renew && /bin/docker restart nginx_docker |
데이터베이스 사용법 까지 필요 하면 아래 포스트를 확인 하자 ‘ㅅ’a