Docker Compose를 이용하여 워드프레스 설치하기

Ubuntu Server

Docker Compose를 이용하여 워드프레스 설치하기

우성군 4 149 0


1. 들어가며


Docker를 이용하면 호스트(서버)에 직접 설치하는 것이 아닌 가상환경 같이 설치할 수 있습니다.


따라서 기존에 웹서버나 DB서비스가 있어도 독립적으로 실행할 수 있습니다.


이번 가이드는 디지털오션에 있는 글을 최신 버전에 호환되는 것을 확인 후 한글로 작성한 것입니다.


https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose


자세한 내용은 원문에 작성되어 있으며, 이 글에서는 되도록이면 핵심만 알려드리겠습니다.



2. 준비사항


(1) 도메인 및 DNS 레코드 작업 완료하기


도메인이 있어야겠죠?


도메인이 없다면 freenom에서 무료 홈페이지 주소를 받을 수 있습니다.


https://blog.wsgvet.com/free-homepage-address-freenom


DNS 레코드는 서버IP 주소와 도메인을 연결하는 작업입니다.


https://blog.wsgvet.com/cloudflare-sign-in-and-change-nameserver


위 링크를 참조하세요. 무료 도메인의 경우 와일드카드 SSL 인증서가 필요하다면 Luadns 추천합니다.


일반적인 경우에는 클라우드플레어가 제일 편합니다. 링크에 모두 설명되어 있습니다.


(2) 서버 또는 가상서버호스팅


직접 돌릴 수 있는 서버도 있어야겠죠?


우분투 최신버전인 20.04 LTS로 진행할 것입니다.


구글 클라우드나 오라클 클라우드에서 무료로 제공해줍니다.


설정하기 편한 곳은 구글 클라우드입니다.


오라클 클라우드는 국내에 서버가 있지만 보안 쪽이 워낙 복잡하여 처음에는 구글 클라우드를 추천드립니다.


https://blog.wsgvet.com/sign-in-google-cloud-platform-and-connect-domain-and-hello-world


위와 같이 셋팅하면 됩니다. 


무료 도메인의 경우 와일드카드 인증서가 필요하다면 클라우드플레어보다는 Luadns가 좋습니다.


와일드카드 인증서가 필요없다면 클라우드플레어도 좋습니다.


그리고 방화벽 셋팅이 되어 있으며, SSH를 위한 22번 포트, Nginx를 위한 80, 443 포트는 열려있어야겠죠? 


추가적으로 phpmyadmin을 위하여 8081 포트도 개방해주세요. phpmyadmin이 필요없다면 열지 않아도 됩니다.



3. 도커 설치


이제 도메인, DNS 레코드, 서버가 있다면 도커를 설치하면 됩니다.


https://www.wsgvet.com/bbs/board.php?bo_table=ubuntu&wr_id=96


위 링크의 1번과 2번을 참고하세요.



4. 시작하기


이제 시작합니다.


먼저 설치관련 파일들이 있을 곳을 정해야 합니다.


-----------------------------------------------


디지털오션에서는 보안을 위해 root유저 보다는 sudo 권한을 가진 일반 유저를 추천합니다.


https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-18-04


sudo 권한을 가진 sammy 유저를 생성하는 방법은 root로 로그인 후



adduser sammy


위 명령어로 sammy라는 유저를 생성합니다. 비번은 원하는대로 넣고, 나머지 정보는 그냥 엔터만 치면 됩니다.



usermod -aG sudo sammy


그리고 위 명령어로 sammy 계정을 sudo 그룹에 포함시켜 줍니다.


이제 sammy 계정에 로그인 후 sudo 명령어를 앞에 붙이면 root 계정에서 명령하는 것과 같은 효과를 가지게 됩니다.


-----------------------------------------------


sammy 유저로 SSH에 접속합니다.


이제 /home/sammy에서 시작하도록 하겠습니다.



cd /home/sammy



mkdir wordpress && cd wordpress


위 명령어로 워드프레스 폴더를 생성하고 워드프레스 폴더로 이동합니다.


실제 파일들은 /home/sammy/wordpress 이하로 들어갈 것입니다.



그리고 필요한 폴더를 미리 만듭니다.



mkdir php


위 명령어로 php 설정파일이 들어갈 php 폴더를 만듭니다.



mkdir nginx-conf


위 명령어로 nginx 설정파일이 들어갈 nginx-conf 폴더를 만듭니다.



mkdir certbot-etc


위 명령어로 Letsecrypt SSL 인증서가 들어갈 폴더를 생성합니다.



mkdir dbdata


위 명령어로 MariaDB의 DB가 들어갈 폴더를 만듭니다.



mkdir wordpress && chmod 777 wordrpess


위 명령어로 워드프레스 설치파일이 들어갈 폴더를 만들고 권한을 777로 줍니다. W3 Total Cache 같은 플러그인의 경우 워드프레스의 root 폴더 쓰기 권한이 필요합니다. 그에 대비한 작업이라고 보시면 됩니다.



해당 폴더를 미리 만들어서 연결해두면 굳이 멀리가지 않아도 편하게 접근할 수 있는 장점이 있고, 데이터가 유지되는 장점이 있습니다.



5. Nginx 설정파일 만들기



nano nginx-conf/nginx.conf


위 명령어로 nginx 설정파일을 만듭니다. 우선은 certbot으로 SSL 인증서 획득을 위한 설정만 넣을 것입니다.



server {
        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;

        index index.php index.html index.htm;

        root /var/www/html;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }

        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}


위 내용에서 수정할 곳은 



server_name example.com www.example.com;


입니다. 자신의 도메인으로 바꿉니다.


바꿨으면, 컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.



6. php.ini 설정파일 만들기


php.ini의 기본 설정은 워드프레스와 어울리지 않는 것이 많습니다.


그래서 해당 부분만 넣으면 잘 작동됩니다.



nano php/php.ini


위 명령어로 php 설정파일을 만듭니다. 



short_open_tag = On
memory_limit = 256M
cgi.fix_pathinfo = 0
upload_max_filesize = 100M
post_max_size = 101M
max_execution_time = 360
date.timezone = Asia/Seoul
expose_php = off


upload_max_filesize와 post_max_size는 업로드 용량을 결정하는 것입니다.


더 많은 업로드 용량이 필요하다면 높여도 됩니다. 다만 post_max_size가 upload_max_filesize보다는 커야 합니다.


expose_php = off 는 php 버전을 숨기는 것입니다. 보안에 효과적입니다.


컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.



7. 환경변수 설정하기



nano .env


위 명령어로 환경변수로 쓸 파일을 만듭니다.


도커에서는 Mysql이나 MariaDB에 직접 접속하지 않고 환경변수만 지정해도 알아서 DB를 만들어줍니다.


정말 편합니다.



MYSQL_ROOT_PASSWORD=your_root_password
MYSQL_USER=your_wordpress_database_user
MYSQL_PASSWORD=your_wordpress_database_password


위와 같이 ROOT 비번, 워드프레스 DB의 유저, 워드프레스 DB의 비번을 설정합니다.


바꿨으면, 컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.



8. Docker Compose 파일 설정하기



nano docker-compose.yml


위와 같이 도커 컴포즈 파일 생성합니다.



version: '3'

services:

  db:
    image: mariadb:latest
    container_name: db
    restart: unless-stopped
    env_file: .env
    environment:
      - MYSQL_DATABASE=wordpress
    volumes: 
      - ./dbdata:/var/lib/mysql
    networks:
      - app-network

  wordpress:
    depends_on: 
      - db
    image: wordpress:fpm-alpine
    container_name: wordpress
    restart: unless-stopped
    env_file: .env
    environment:
      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress
    volumes:
      - ./wordpress:/var/www/html
      - ./php/php.ini:/usr/local/etc/php/php.ini
    networks:
      - app-network

  webserver:
    depends_on:
      - wordpress
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./wordpress:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - ./certbot-etc:/etc/letsencrypt
    networks:
      - app-network

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot-etc:/etc/letsencrypt
      - ./wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@example.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    container_name: phpmyadmin
    ports:
      - "8081:80"
    environment:
      - PMA_HOST=db
    restart: always
    depends_on:
      - db
    networks:
      - app-network

volumes:
  certbot-etc:
  wordpress:
  dbdata:
  nginx-conf:

networks:
  app-network:
    driver: bridge



설정파일이 정말 많죠? 상세 내용은 디지털오션 원문을 참조하세요.


https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-docker-compose#step-3-%E2%80%94-defining-services-with-docker-compose


우선 db는 MariaDB 최신버전을 사용합니다. mariadb:latest




MYSQL_DATABASE=wordpress


위 내용은 워드프레스의 DB 이름을 지정하는 것입니다. 그냥 놔두면 됩니다.



wordpress 이미지는 php-fpm과 연결된 최신 이미지인 wordpress:fpm-alpine 을 씁니다.


php-fpm과 워드프레스 이미지가 합쳐지고, 용량도 최적화된 것입니다.




      - WORDPRESS_DB_HOST=db:3306
      - WORDPRESS_DB_USER=$MYSQL_USER
      - WORDPRESS_DB_PASSWORD=$MYSQL_PASSWORD
      - WORDPRESS_DB_NAME=wordpress


위 내용은 워드프레스가 MariaDB와 3306포트로 소통하고, 워드프레스 DB의 유저, 워드프레스 DB의 비번은 환경변수 값을 읽는다는 뜻입니다. DB 이름은 wordpress 입니다.



./php/php.ini:/usr/local/etc/php/php.ini


그리고 윗 부분이 php 설정 파일을 덮어쓰는 부분입니다.


웹서버는 nginx:alpine 이며 최신버전에 용량이 최적화되어 있습니다.


Certbot은 Letsencrypt를 이용하는 서비스입니다.



command: certonly --webroot --webroot-path=/var/www/html --email sammy@example.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com


위 내용에서 sammy@example.com과 example.com 은 자신의 것으로 바꾸세요!  --staging은 테스트한다는 뜻입니다. 테스트에서 통과하면 본격적으로 만들 것입니다.


phpmyadmin은 db와 연결되어 MariaDB에 접속할 수 있습니다. 필요없다면 지워도 됩니다.


컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.


9. 실행하기



sudo docker-compose up -d


위 명령어로 열심히 작성한 도커 컴포즈 파일을 기반으로 실행합니다.


열심히 받고 실행할 것입니다.



~/wordpress$ sudo docker-compose up -d
Creating network "wordpress_app-network" with driver "bridge"
Creating network "wordpress_default" with the default driver
Creating volume "wordpress_certbot-etc" with default driver
Creating volume "wordpress_wordpress" with default driver
Creating volume "wordpress_dbdata" with default driver
Creating volume "wordpress_nginx-conf" with default driver
Pulling db (mariadb:latest)...
latest: Pulling from library/mariadb
3ff22d22a855: Pull complete
e7cb79d19722: Pull complete
323d0d660b6a: Pull complete
b7f616834fd0: Pull complete
78ed0160f03e: Pull complete
a122e9306ac4: Pull complete
673e89352b19: Pull complete
caf1e694359b: Pull complete
04f5e4f6ead3: Pull complete
a41772aadb3d: Pull complete
c3811aa2fa0a: Pull complete
655ad574d3c7: Pull complete
90ae536d75f0: Pull complete
Digest: sha256:812d3a450addcfe416420c72311798f3f3109a11d9677716dc631c429221880c
Status: Downloaded newer image for mariadb:latest
Pulling wordpress (wordpress:fpm-alpine)...
fpm-alpine: Pulling from library/wordpress
df20fa9351a1: Pull complete
b358d6dbbdff: Pull complete
0232d962484c: Pull complete
0c1d3ac04d2a: Pull complete
21e2be1d2e71: Pull complete
a715280c3b40: Pull complete
4fa736fe3036: Pull complete
4808dd45a24b: Pull complete
591d728477bc: Pull complete
5c38ac758dc8: Pull complete
ce77155199d1: Pull complete
2ec1126a33c3: Pull complete
234dd85e94a0: Pull complete
73d419daee63: Pull complete
e9a9a0f65898: Pull complete
858f1a96ba1d: Pull complete
Digest: sha256:4d4028f297116d70cc5eab7607945cdde4afb7a629816a8d8a68adf5cba855bf
Status: Downloaded newer image for wordpress:fpm-alpine
Pulling webserver (nginx:alpine)...
alpine: Pulling from library/nginx
cbdbe7a5bc2a: Pull complete
85434292d1cb: Pull complete
75fcb1e58684: Pull complete
2a8fe5451faf: Pull complete
42ceeab04dd4: Pull complete
Digest: sha256:ee8c35a6944eb3cc415cd4cbeddef13927895d4ffa50b976886e3abe48b3f35a
Status: Downloaded newer image for nginx:alpine
Pulling certbot (certbot/certbot:)...
latest: Pulling from certbot/certbot
df20fa9351a1: Already exists
36b3adc4ff6f: Pull complete
a3758150fe75: Pull complete
164dc99cbd9c: Pull complete
64cc991ba717: Pull complete
756f5bac7453: Pull complete
b988c158c9ab: Pull complete
a353cddc7def: Pull complete
8a0aee67a63b: Pull complete
f717fd0b107b: Pull complete
56d5370adbee: Pull complete
Digest: sha256:e2a940dbbc1aac8e6c22e43736eb9053bec17259f58af3ae6ec8e27a8b0b2cc7
Status: Downloaded newer image for certbot/certbot:latest
Pulling phpmyadmin (phpmyadmin/phpmyadmin:)...
latest: Pulling from phpmyadmin/phpmyadmin
6ec8c9369e08: Pull complete
081a822af595: Pull complete
bb5bea655fca: Pull complete
1e5d9e6a44c7: Pull complete
51c80d726a75: Pull complete
41f3ef5189e5: Pull complete
c1a9c1efdc83: Pull complete
348c6ac67813: Pull complete
d16c4c4b2a5f: Pull complete
035ee560bfbc: Pull complete
4c16f7d16e86: Pull complete
560feb679e04: Pull complete
0bc8defe61af: Pull complete
b80e31e8a7c4: Pull complete
f94927b2554c: Pull complete
416dcf230b63: Pull complete
a9d24c9f2a61: Pull complete
4cae08d2f851: Pull complete
Digest: sha256:69eaf4a23598e9986b62bbfde9e8e3ae773f0da53406723e6f027582e0310274
Status: Downloaded newer image for phpmyadmin/phpmyadmin:latest
Creating db ... done
Creating phpmyadmin ... done
Creating wordpress  ... done
Creating webserver  ... done
Creating certbot    ... done


위와 같이 모두 done이 뜨면 성공입니다.



sudo docker-compose ps


위 명령어로 현재 상태를 볼 수 있습니다.




   Name                 Command               State                     Ports
-----------------------------------------------------------------------------------------------
certbot      certbot certonly --webroot ...   Exit 1
db           docker-entrypoint.sh mysqld      Up       3306/tcp
phpmyadmin   /docker-entrypoint.sh apac ...   Up       0.0.0.0:8081->80/tcp
webserver    /docker-entrypoint.sh ngin ...   Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress    docker-entrypoint.sh php-fpm     Up       9000/tcp


위와 같이 certbot은 자기 할일하고 끝났고, MariaDB는 3306포트, phpmyadmin은 80포트, webserver는 80, 443 포트, php-fpm은 9000 포트에 연결되어 있고, 실제 노출된 포트는 Nginx의 80, 443포트와 Phpmyadmin의 8081포트입니다.



sudo docker-compose logs 서비스Name


위와 같이 서비스Name 대신에 certbot이나 db의 log를 확인할 수 있습니다.


이제 Certbot이 자기 할일을 하고 SSL 인증서 만드는 테스트에 통과했는지 체크합니다.



sudo docker-compose exec webserver ls -la /etc/letsencrypt/live


위 명령어로 webserver 컨테이너의 인증서 폴더를 볼 수 있습니다.



total 16
drwx------    3 root     root          4096 Aug  2 07:41 .
drwxrwxr-x    9 1001     1002          4096 Aug  2 07:41 ..
-rw-r--r--    1 root     root           740 Aug  2 07:41 README
drwxr-xr-x    2 root     root          4096 Aug  2 07:41 example.com



위와 같이 example.com 이라는 도메인의 인증서가 잘 생성된 것을 확인할 수 있습니다.


인증서 테스트가 통과했으므로 이제 진짜 인증서를 받아야겠죠?



10. SSL 인증서 받기



nano docker-compose.yml


위 명령어로 도커 컴포즈 파일을 엽니다.



  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - certbot-var:/var/lib/letsencrypt
      - wordpress:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email sammy@example.com --agree-tos --no-eff-email --force-renewal -d example.com -d www.example.com


certbot 부분에서 command를 수정합니다. 기존 내용에서 --staging을 --force-renewal로 바꾸면 됩니다. 


sammy@example.com 와 example.com 부분은 아까 자신의 환경에 맞게 바꾸었죠?


수정한 뒤, 컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.



sudo docker-compose up --force-recreate --no-deps certbot


위 명령어로 의존성없이 certbot 컨테이너만 다시 생성합니다.



Recreating certbot ... done
Attaching to certbot
certbot      | Saving debug log to /var/log/letsencrypt/letsencrypt.log
certbot      | Plugins selected: Authenticator webroot, Installer None
certbot      | Renewing an existing certificate
certbot      | Performing the following challenges:
certbot      | http-01 challenge for example.com
certbot      | http-01 challenge for www.example.com
certbot      | Using the webroot path /var/www/html for all unmatched domains.
certbot      | Waiting for verification...
certbot      | Cleaning up challenges
certbot      | IMPORTANT NOTES:
certbot      |  - Congratulations! Your certificate and chain have been saved at:
certbot      |    /etc/letsencrypt/live/example.com/fullchain.pem
certbot      |    Your key file has been saved at:
certbot      |    /etc/letsencrypt/live/example.com/privkey.pem
certbot      |    Your cert will expire on 2020-10-31. To obtain a new or tweaked
certbot      |    version of this certificate in the future, simply run certbot
certbot      |    again. To non-interactively renew *all* of your certificates, run
certbot      |    "certbot renew"
certbot      |  - Your account credentials have been saved in your Certbot
certbot      |    configuration directory at /etc/letsencrypt. You should make a
certbot      |    secure backup of this folder now. This configuration directory will
certbot      |    also contain certificates and private keys obtained by Certbot so
certbot      |    making regular backups of this folder is ideal.
certbot      |  - If you like Certbot, please consider supporting our work by:
certbot      | 
certbot      |    Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
certbot      |    Donating to EFF:                    https://eff.org/donate-le
certbot      | 
certbot exited with code 0


위와 같이 정상적으로 인증서 발급이 된 것을 볼 수 있습니다.



11. Nginx 설정 수정하기


이제 Nginx에서 SSL 인증서를 사용할 수 있게 수정해야 합니다.



sudo docker-compose stop webserver


위 명령어로 웹서버를 정지합니다.



curl -sSLo nginx-conf/options-ssl-nginx.conf https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf


위 명령어로 Nginx의 SSL 설정을 다운 받습니다.



rm nginx-conf/nginx.conf


위 명령어로 기존에 있던 설정을 지웁니다.



nano nginx-conf/nginx.conf


다시 생성합니다.



server {
        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;

        location ~ /.well-known/acme-challenge {
                allow all;
                root /var/www/html;
        }

        location / {
                rewrite ^ https://$host$request_uri? permanent;
        }
}

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name example.com www.example.com;

        index index.php index.html index.htm;

        root /var/www/html;

        server_tokens off;
        client_max_body_size 100M;

        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
        include /etc/nginx/conf.d/options-ssl-nginx.conf;

        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-XSS-Protection "1; mode=block" always;
        add_header X-Content-Type-Options "nosniff" always;
        add_header Referrer-Policy "no-referrer-when-downgrade" always;
        add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;
        # add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
        # enable strict transport security only if you understand the implications

        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

        location ~ \.php$ {
                try_files $uri =404;
                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                fastcgi_pass wordpress:9000;
                fastcgi_index index.php;
                include fastcgi_params;
                fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
        }

        location ~ /\.ht {
                deny all;
        }

        location = /favicon.ico { 
                log_not_found off; access_log off; 
        }
        location = /robots.txt { 
                log_not_found off; access_log off; allow all; 
        }
        location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
                expires max;
                log_not_found off;
        }
}


위 내용에서 example.com 를 자신의 도메인을 모두 바꿉니다. 모두 7개니깐 꼭 확인하세요!


HTTP Strict Transport Security (HSTS) 부분은 # 으로 주석처리해뒀습니다. 한번 적용하면 해당 브라우저에서는 80포트로 접속이 안되기 때문에 정확하게 확인 후 주석을 제거해주세요.


수정한 뒤, 컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.



sudo docker-compose up -d --force-recreate --no-deps webserver


위 명령어로 webserver 컨테이너를 재생성합니다. W3 Total Cache 처럼 Nginx 재시작이 필요한 경우 위 명령어로 Nginx restart 같은 효과를 볼 수 있습니다.



sudo docker-compose ps


위 명령어를 내리면



   Name                 Command               State                     Ports
-----------------------------------------------------------------------------------------------
certbot      certbot certonly --webroot ...   Exit 0
db           docker-entrypoint.sh mysqld      Up       3306/tcp
phpmyadmin   /docker-entrypoint.sh apac ...   Up       0.0.0.0:8081->80/tcp
webserver    /docker-entrypoint.sh ngin ...   Up       0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
wordpress    docker-entrypoint.sh php-fpm     Up       9000/tcp



위와 같이 정상적으로 실행되고 있는 것을 볼 수 있습니다.



12. 워드프레스 접속하기


https://example.com


이제 위와 같이 자신의 도메인으로 접속하면



위와 같이 언어를 변경하는 화면이 나옵니다.


한국어를 선택하고 워드프레스 설정을 하면 됩니다. DB 정보는 이미 입력했기 때문에 아이디 비번 이메일 설정하는 화면이 나올 것입니다.


이제 원하는대로 쓰면 됩니다!



13. SSL 인증서 갱신하기


certbot으로 인증서를 생성했지만 유효기간이 3개월 밖에 되지않기 때문에 갱신 작업도 해줘야겠죠?



nano ssl_renew.sh


위 명령어로 SSL 인증서 갱신 BASH파일을 만듭니다.



#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew  --no-random-sleep-on-renew --dry-run && $COMPOSE kill -s SIGHUP webserver


위 내용에서 /home/sammy/wordpress/ 를 자신의 경로로 바꿔주세요.


수정한 뒤, 컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.



chmod +x ssl_renew.sh


위 명령어로 실행가능하게 만듭니다.



sudo crontab -e


위 명령어로 크론작업으로 들어갑니다.



no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.basic
  3. /usr/bin/vim.tiny
  4. /bin/ed

Choose 1-4 [1]:


혹시 위와 같이 나오면 1번 엔터를 누릅니다.


제일 밑에



* * * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1


위와 같이 넣습니다. 파일 경로는 자신에게 맞게 수정해야 합니다. 컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.


이제 매분 ssl 갱신을 시도할 것입니다.


1분 뒤에



tail -f /var/log/cron.log


위 명령어를 내려보세요. 실시간으로 어떻게 작업이 되는지 확인할 수 있습니다.



Starting webserver ...
Starting webserver ... done
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/example.com.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for example.com
http-01 challenge for www.example.com
Using the webroot path /var/www/html for all unmatched domains.
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/example.com/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/example.com/fullchain.pem (success)
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates above have not been saved.)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Killing webserver ...
Killing webserver ... done


위와 같이 



new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/example.com/fullchain.pem


위 내용이 뜨면 갱신 테스트가 성공했다는 뜻입니다.


컨트롤 + c 를 누르면 빠져나와집니다.



sudo crontab -e


위 명령어로 갱신 명령 주기를 수정합니다.



0 12 * * * /home/sammy/wordpress/ssl_renew.sh >> /var/log/cron.log 2>&1


위와 같이 매일 12시 0분에 갱신 명령을 내리도록 합니다.


/home/sammy/wordpress 경로는 꼭 수정하세요!


수정한 뒤, 컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.





nano ssl_renew.sh


위 명령어로 갱신 명령어도 수정합니다.



#!/bin/bash

COMPOSE="/usr/local/bin/docker-compose --no-ansi"

cd /home/sammy/wordpress/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver


위와 같이 --no-random-sleep-on-renew --dry-run 을 뺍니다. /home/sammy/wordpress/는 꼭 자신의 경로로 바꿔주세요.


컨트롤 + O, 엔터, 컨트롤 + X 로 저장 후 빠져나옵니다.





nano docker-compose.yml


다시 도커 설정파일로 들어갑니다.


도커 설정파일에는 도커를 완전 정지 후 다시 실행하면 --force-renewal 옵션에 의해 갱신기간이 오지 않아도 재갱신하는 셋팅이 되어있습니다. 그래서 수정합니다.



  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot-etc:/etc/letsencrypt
      - ./wordpress:/var/www/html
    command: renew


위와 같이 certbot 부분의 command를 단순히 renew로 변경합니다.


그러면 강제로 갱신하지 않고 갱신기간이 왔을때만 갱신하게 됩니다.


물론 crontab에서 매일 갱신 체크를 하게되니 걱정없지만요 ^^



이제 SSL 갱신까지 끝났습니다.


내용은 길었지만 실제로 셋팅하는데 30분도 걸리지 않습니다. 감사합니다.

, , , ,

4 Comments
해를쏘다 08.04 18:47  
우성군님, 혹시 네이티브로 설치할때와 도커로 설치할때 차이가 많이 날까요? 웹 반응성 측면에서요.
구글 무료클라우드에 설치 해보려고 하는데.. 네이티브로 할지 도커로 올릴지 고민되어서요^^
우성군 08.04 19:01  
[@해를쏘다] 도커의 성능이 네이티브의 95% 이상이라고 알고있어요.

일단 설치는 편하지만 이것저것 커스터마이징 하려면 따로 공부해야해요.

저도 이거 만들때 redis-server랑 연동하려고 했는데 php-redis 만 추가하려고 해도 따로 도커파일 만들어서 빌드해야하더라구요.

그러면 간편하게 만드는 의미가 없어져서 이정도만 했습니다.

서버를 처음 구동한다면 네이티브가 편할거예요.

특히나 로컬 컴퓨터가 아닌 클라우드라면 더 네이티브로 가야죠 ㅎ

클라우드 자체가 쿠버네티스 도커 역할을 하기 때문이죠 ㅎㅎ

좀 이상하다 생각하면 그냥 없애고 새로 만들 수 있으니깐요.
해를쏘다 08.04 20:26  
[@우성군] 말씀 들으니까 네이티브로 마음이 기우네요 ㅎㅎ 추천 감사합니다^^
우성군 08.04 20:52  
[@해를쏘다] 넵 ㅎㅎ 홈페이지 한번 띄우면 신기하고도 기분이 좋아지더라구요 ㅎㅎ