wordpress를 사용하기 위해 서버를 구성하며 진행했던 내용 누군가에게 도움이 되었으면 좋겠다는 바램을 담아 기록으로 남겨봅니다.
Oracle Free Trial 서버를 만든 지 한참이 지났지만 넉넉하지 못한 서버 사양으로 활용도를 찾지 못하고 있던 와중에 wordpress로 블로그를 구축해서 사용하는 사례를 알게 되었고, 직접 구현해 보면서 고민하고 알게 된 내용입니다.
현재 이 wordpress가 돌고 있는 서버는 Oracle Free Trial에서 평생 무료 정책으로 계정당 2개를 제공해주는 vm 중 1개로 Ubuntu Linux 22.04 LTS 버전이 설치되어 있습니다.
AMD EPYC 7551 32-Core Processor CPU 2Core와 1GB의 메모리, 100GB의 디스크로 구성된 서버라 간단한 웹서버나 DB서버 등으로 활용이 가능한데, wordpress 정도를 구성하는데는 충분한 사양인 것 같습니다.
wordpress를 구성하기 위해서는 크게 2가지 모듈이 필요합니다.
- wordpress (php가 설치된 웹서버 필요 ex.apache, nginx)
- database (일반적으로 MySQL, mariaDB)
각각 서버에 직접 설치 및 구성도 가능하지만 Docker를 활용하면 아주 간단하게 구성이 가능한데, 1가지 문제가 있습니다.
wordpress 컨테이너가 동작하는 웹서버는 nginx혹은 apache로 구현 된 경우가 많은데 기본적으로 SSL(https)를 지원하지 않기 때문에 요즘 많이 사용하는 chrome같은 브라우저에서 빨간 창을 보여주며 접근을 막는 상황이 발생하게 되죠.
이 문제를 해결하려면 서버 IP에 해당하는 도메인 생성 및 도메인에 맞는 SSL인증서를 발급받아 웹서버에 등록해야 하는데요
이런 일련의 과정을 1개의 docker-compose.yaml 파일로 정의 해서 바로 사용이 가능한 방법이 있어 그 방법을 사용하여 구성하였습니다.
서버 환경설정(docker환경 구성, 방화벽, 도메인 등록)은 이번 포스팅에서는 언급하지 않고 docker-compose.yaml 파일을 소개하는데 집중하고 관련 내용은 추후 하나하나 포스팅을 올려보도록 할께요.
docker-compose.yaml
version: "3.8"
services:
# NginxProxy 가상 호스트를 관리하는 컨테이너
nginx-proxy:
image: jwilder/nginx-proxy:latest
container_name: nginx-proxy
privileged: true
ports:
- "80:80"
- "443:443"
environment:
- DEFAULT_HOST=example.com # 사용 domain
volumes:
- proxy:/etc/nginx/vhost.d
- proxy:/usr/share/nginx/html
- ./nginx-proxy/conf.d/custom_proxy_settings.conf:/etc/nginx/conf.d/custom_proxy_settings.conf # nginx 설정 파일 mount
- ./nginx-proxy/logs:/var/log/nginx # Docker 컨테이너 내부의 apache 설정파일 mount
- /var/run/docker.sock:/tmp/docker.sock:ro
- ./certs:/etc/nginx/certs:ro
restart: always
networks:
- app-net
- default
labels:
com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: ""
# SSL 인증서를 관리하는 컨테이너 (Let's Encrypt)
letsencrypt:
image: jrcs/letsencrypt-nginx-proxy-companion
container_name: lets-encrypt
restart: always
depends_on:
- nginx-proxy
volumes:
- proxy:/etc/nginx/vhost.d
- proxy:/usr/share/nginx/html
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./certs:/etc/nginx/certs:rw
environment:
- NGINX_PROXY_CONTAINER=nginx-proxy
networks:
- app-net
- default
# WordPress 컨테이너
wordpress:
build:
context: ./Php
dockerfile: Dockerfile
container_name: wordpress
depends_on:
- wordpressdb
restart: always
expose:
- 80
- 443
environment:
WORDPRESS_DB_HOST: wordpressdb
WORDPRESS_DB_USER: wp_user
WORDPRESS_DB_PASSWORD: password # 데이터베이스의 비밀번호
WORDPRESS_DB_NAME: wordpress
VIRTUAL_HOST: example.com # 사용 domain
VIRTUAL_PORT: 80
LETSENCRYPT_HOST: example.com # 사용 domain
LETSENCRYPT_EMAIL: info@example.com # e-mail 주소
volumes:
- ./wordpress/html:/var/www/html # wordpress 소스코드 폴더 mount
- ./wordpress/log:/var/log/apache2 # Docker 컨테이너 내부의 apache 설정파일 mount
- ./Php/php.ini:/usr/local/etc/php/php.ini # PHP 설정파일 mouunt
networks:
- app-net
- default
# wordpress가 사용할 데이터베이스 컨테이너
wordpressdb:
image: mariadb
restart: always
volumes:
- ./wp_mariadb/db_data:/docker-entrypoint-initdb.d
- ./wp_mariadb/data:/var/lib/mysql
- ./wp_mariadb/logs:/var/log/mysql
- ./wp_mariadb/conf.d/my.cnf:/etc/mysql/conf.d/my.cnf
expose:
- 3306
ports:
- 3306:3306
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wp_user
MYSQL_PASSWORD: password # 데이터베이스 비밀번호
MYSQL_ROOT_PASSWORD: root_password # 데이터베이스의 root 비밀번호
TZ: Asia/Seoul
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
networks:
- app-net
- default
# phpMyAdmin 컨테이너
phpmyadmin:
image: phpmyadmin/phpmyadmin
depends_on:
- wordpressdb
restart: always
expose:
- 88
ports:
- 88:80
volumes:
- ./wp_phpmyadmin/sessions:/sessions
environment:
PMA_ARBITRARY: 1
PMA_HOST: wordpressdb
PMA_USER: root
PMA_PASSWORD: root_password # 데이터베이스의 root 비밀번호
networks:
- app-net
- default
# 컨테이너들이 사용할 공유 네트워크
networks:
app-net:
driver: bridge
# mount volumes
volumes:
db_data:
proxy:
간단히 설명하면 nginx-proxy는 가상호스트를 관리합니다.
‘example.com’에 접속하면 nginx-proxy가 wordpress 컨테이너로 연결 해 줍니다.
‘letsencrypt’는 SSL 인증서를 관리하고 wordpress 컨테이너가 ‘https’로 연결 해 줍니다.
wordpress는 wordpress 자체 컨테이너 입니다.
phpmyadmin은 phpMyAdmin이라는 도구가 동작하는 컨테이너로 서버의 88번 포트를 통해 접속됩니다.
정리하면 잘 알고 계시는 wordpress와 mariadb 구조에 nginx-proxy와 letsencrypt컨테이너를 더해서 SSL인증서가 등록된 nginx-proxy를 통해 wordpress에 접속하는 구조 정도라고 할 수 있겠네요.
여기에 추가로 docker-compose.yaml 파일내부에 정의 된 Dockerfile과 custom_proxy_setting.conf , php.ini 파일이 필요합니다.
Dockerfile
FROM wordpress:6.5.3-php8.1-apache
# Run apt command
RUN apt-get update \
&& apt-get install -y \
g++ \
libicu-dev \
libpq-dev \
libzip-dev \
unzip \
zip \
zlib1g-dev \
libonig-dev \
vim
# CP php.ini
RUN cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini
CMD ["apache2-foreground"]
custom_proxy_setting.conf
client_max_body_size 10g; proxy_request_buffering off; proxy_buffers 8 32K; proxy_buffer_size 32k; proxy_busy_buffers_size 64k;
파일의 업로드사이즈를 변경하여 세션이 너무 커지는 것을 막기 위한 설정으로 필요에 따라 적용하시면 되는 부분입니다.
php.ini
php.ini 파일은 원본 php.ini파일에서 업로드 파일 사이즈가 변경되어 있습니다.
디렉토리 구성
docker-compose.yml nginx-proxy/ conf.d/ custom_proxy_settings.conf Php/ Dockerfile php.ini
docker-compose.yaml 파일이 위치한 workdpress를 설치할 경로에 위와 같은 구조로 파일을 배포해 주시면 됩니다.
서버에 해당 파일을 업로드 한 후 ‘docker compose up -d’ 명령으로 docker를 실행한 후 https://example.com으로 접속하면 wordpress 초기 설정 화면이 보이실 겁니다.
관련하여 컨테이너 내부에서 에러가 발생하는 경우 ‘wordpress/log’와 ‘nginx-proxy/logs’에 각각의 로그가 기록되어 있으니 확인 및 조치가 가능합니다.
여기까지 SSL을 지원하는 wordpress docker-compose.yaml에 대한 포스팅을 마치겠습니다.
서버설치 및 구성의 불편함이 없는 docker를 많이 활용하는 추세인데 https통신을 위해 SSL인증서 등록을 하는데 애를 먹는 분들이 많이 있을 것 같습니다. (저도 그랬고, 인터넷 검색을 통해 관련 내용을 찾아 일부 오류가 있는 부분을 수정하여 올려 드리는 부분입니다.) ‘nginx-proxy’와 ‘letsencrypt’ 컨테이너를 추가하여 SSL등록을 가능하게 하는 좋은 방법인 것 같아 기록을 남겨 봅니다.