우분투 서버
설치 분류

Docker Compose를 이용하여 그누보드 설치하기

컨텐츠 정보

  • 28,680 조회
  • 17 댓글
  • 1 추천
  • 목록

본문

3232235777_LjZWok9E_251c8dfec405a016819b802389a8085caaa5bca9.png



0. 참고사항


이 글은 Docker compose로 그누보드 편하게 설치하기를 풀어서 쓴 글입니다.


스크립트로 편하게 설치하시려면


Docker compose로 그누보드 편하게 설치하기 를 참조하세요!


1. 들어가며 


이 글은 기존에 적었던 Docker Compose를 이용하여 워드프레스 설치하기(링크)와 90% 이상 동일합니다.


그럼에도 불구하고 이 글을 적는 이유는 그누보드에 최적화된 도커 시스템을 만들 수 있기 때문입니다.


공식이미지이므로 업데이트도 잘 될 것입니다.


물론 제가 이미지를 직접 만들 수 있지만, 완전 초보분들도 처음부터 만들다보면 자신만의 이미지를 만들 수 있을 것입니다.


이제 시작합니다.



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


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


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


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


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



2. 준비사항


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


도메인이 있어야겠죠?


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


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. 시작하기


도커를 설치하기 전에 현재 유저에게 docker를 실행할 수 있는 권한을 줄 것입니다.


그렇지 않으면 docker 명령어를 내릴 때 항상 sudo 명령어를 넣어야 되기 때문에 매우 귀찮습니다. 



먼저 docker 그룹을 만듭니다.



sudo groupadd docker


그리고 현재 유저를 docker 그룹에 추가합니다.



sudo usermod -aG docker $USER


SSH를 다시 접속하거나, 로그아웃 후 다시 로그인하면 적용이 됩니다.


밑의 설명 중에 sudo docker 또는 sudo docker-compose 명령어에서 sudo는 무시하셔도 됩니다.


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


꼭 sammy 유저를 사용할 필요가 없습니다. 그냥 예시로 든 것이며, 자신의 환경에 맞게 쓰시면 됩니다.


대신 아래의 명령어들 중에 sammy 대신 다른 것으로 바꾸면 됩니다.


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



cd /home/sammy



mkdir gnuboard && cd gnuboard


위 명령어로 그누보드 폴더를 생성하고 이동합니다.


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



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



mkdir php


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



mkdir nginx-conf


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



mkdir certbot-etc


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



mkdir dbdata


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



mkdir gnuboard && chmod 777 gnuboard


위 명령어로 그누보드 설치파일이 들어갈 폴더를 만듭니다.



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



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;


        server_tokens off;
        client_max_body_size 100M;


        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 gnuboard: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;
        }
        #### 그누보드5 nginx rules BEGIN #####
        if (!-e $request_filename){
        rewrite ^/content/([0-9a-zA-Z_]+)$ /bbs/content.php?co_id=$1&rewrite=1 break;
        rewrite ^/content/([^/]+)/$ /bbs/content.php?co_seo_title=$1&rewrite=1 break;
        rewrite ^/rss/([0-9a-zA-Z_]+)$ /bbs/rss.php?bo_table=$1 break;
        rewrite ^/([0-9a-zA-Z_]+)$ /bbs/board.php?bo_table=$1&rewrite=1 break;
        rewrite ^/([0-9a-zA-Z_]+)/write$ /bbs/write.php?bo_table=$1&rewrite=1 break;
        rewrite ^/([0-9a-zA-Z_]+)/([^/]+)/$ /bbs/board.php?bo_table=$1&wr_seo_title=$2&rewrite=1 break;
        rewrite ^/([0-9a-zA-Z_]+)/([0-9]+)$ /bbs/board.php?bo_table=$1&wr_id=$2&rewrite=1 break;
        }
        #### 그누보드5 nginx rules END #####
}


위 내용에서 수정할 곳은 



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_gnuboard_database_user
MYSQL_PASSWORD=your_gnuboard_database_password


위와 같이 ROOT 비번, 그누보드 DB의 유저, 그누보드 DB의 비번을 설정합니다.


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



8. 워드프레스의 Dockerfile을 수정하기


https://hub.docker.com/_/wordpress


워드프레스 공식 도커 이미지 중에서 php-fpm-alpine를 이용할 것입니다.


https://github.com/docker-library/wordpress/blob/master/latest/php7.4/fpm-alpine/Dockerfile 


원본은 위 링크에 있습니다.


워드프레스의 php Dockerfile을 이용하는 이유는 기본 php에는 없는 opcache를 설정할 수 있고, gd 및 imagick 라이브러리까지 추가할 수 있기 때문입니다.



위 명령어로 도커파일을 다운 받습니다. 공식이미지라 관리가 잘 되고 있습니다.



nano Dockerfile


위 명령어를 넣으면 엄청 많은 내용이 나오는데요.


대략 73번째 줄부터 90번째 줄까지의 내용



ENV WORDPRESS_VERSION 5.4.2
ENV WORDPRESS_SHA1 e5631f812232fbd45d3431783d3db2e0d5670d2d


RUN set -ex; \
	curl -o wordpress.tar.gz -fSL "https://wordpress.org/wordpress-${WORDPRESS_VERSION}.tar.gz"; \
	echo "$WORDPRESS_SHA1 *wordpress.tar.gz" | sha1sum -c -; \
# upstream tarballs include ./wordpress/ so this gives us /usr/src/wordpress
	tar -xzf wordpress.tar.gz -C /usr/src/; \
	rm wordpress.tar.gz; \
	chown -R www-data:www-data /usr/src/wordpress; \
# pre-create wp-content (and single-level children) for folks who want to bind-mount themes, etc so permissions are pre-created properly instead of root:root
	mkdir wp-content; \
	for dir in /usr/src/wordpress/wp-content/*/; do \
		dir="$(basename "${dir%/}")"; \
		mkdir "wp-content/$dir"; \
	done; \
	chown -R www-data:www-data wp-content; \
	chmod -R 777 wp-content


위 내용을 다 지웁니다. 워드프레스는 필요없기 때문입니다.


그리고 



# fix work iconv library with alpine
# Huge thanks to chodingsana!
RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community<a> --allow-untrusted gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php


위 내용을 넣습니다. 회원가입시 오류를 해결해줍니다.


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



이제 그누보드를 다운 받기 위한 docker-entrypoint.sh를 생성합니다.



nano docker-entrypoint.sh


위 명령어를 내린 후 



#!/bin/bash
set -euo pipefail
if [ ! -e data ]; then
curl -o gnuboard.tar.gz -fSL https://github.com/gnuboard/gnuboard5/tarball/master \
&& tar -xf gnuboard.tar.gz -C ./ --strip-components=1 \
&& rm gnuboard.tar.gz && mkdir data \
&& chown -R www-data:www-data ./ \
&& chmod -R 777 data
fi
exec "$@"


위 내용을 넣습니다. 위 내용은 /var/www/html 에 data라는 폴더가 없으면 그누보드 최신 버전을 다운받아서 덮어쓴 후 data폴더를 만듭니다.


따라서 서버를 이전할 땐 data 폴더를 미리 만들어거나, 그냥 이 이미지를 생성 후 기존 그누보드 내용으로 바꿔치기하는 것이 좋습니다.


새로 생성할땐 그냥 놔두면 알아서 설치됩니다 ^^


내용 추가 후 컨트롤 + O, 엔터, 컨트롤 + X로 빠져나옵니다.



chmod +x docker-entrypoint.sh


위 명령어로 실행가능한 상태로 바꿉니다.


이제 수정한 Dockerfile과 docker-entrypoint.sh를 이용하여 나만의 이미지를 생성할 것입니다.


9. 새로운 이미지 Build 하기



sudo docker build -t gnuboard-fpm-alpine:1.0.0 .


위 명령어로 Dockerfile과 docker-entrypoint.sh이 들어간 이미지가 생성됩니다.


gnuboard-fpm-alpine 라는 이름의 이미지가 생성되고, tag는 1.0.0 이 붙습니다.



Sending build context to Docker daemon  11.78kB
Step 1/9 : FROM php:7.4-fpm-alpine
 ---> f9f075c5a926
Step 2/9 : RUN apk add --no-cache               bash            sed             ghostscript             imagemagick
 ---> Using cache
 ---> 978d26b7458a
Step 3/9 : RUN set -ex;                 apk add --no-cache --virtual .build-deps                $PHPIZE_DEPS            freetype-dev            imagemagick-dev                 libjpeg-turbo-dev               libpng-dev                libzip-dev      ;               docker-php-ext-configure gd --with-freetype --with-jpeg;        docker-php-ext-install -j "$(nproc)"            bcmath          exif            gd       mysqli           zip     ;       pecl install imagick-3.4.4;     docker-php-ext-enable imagick;          runDeps="$(             scanelf --needed --nobanner --format '%n#p' --recursive /usr/local/lib/php/extensions                     | tr ',' '\n'                   | sort -u                       | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }'         )";     apk add --virtual .wordpress-phpexts-rundeps $runDeps;    apk del .build-deps
 ---> Using cache
 ---> 846ba1d02b29
Step 4/9 : RUN set -eux;        docker-php-ext-enable opcache;  {               echo 'opcache.memory_consumption=128';          echo 'opcache.interned_strings_buffer=8';               echo 'opcache.max_accelerated_files=4000';                echo 'opcache.revalidate_freq=2';               echo 'opcache.fast_shutdown=1';         } > /usr/local/etc/php/conf.d/opcache-recommended.ini
 ---> Using cache
 ---> 66d3356b5152
Step 5/9 : RUN {                echo 'error_reporting = E_ERROR | E_WARNING | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING | E_RECOVERABLE_ERROR';             echo 'display_errors = Off';              echo 'display_startup_errors = Off';            echo 'log_errors = On';                 echo 'error_log = /dev/stderr';                 echo 'log_errors_max_len = 1024';               echo 'ignore_repeated_errors = On';               echo 'ignore_repeated_source = Off';            echo 'html_errors = Off';       } > /usr/local/etc/php/conf.d/error-logging.ini
 ---> Using cache
 ---> 28f9404b40c8
Step 6/9 : VOLUME /var/www/html
 ---> Using cache
 ---> 70f1d96ee7d6
Step 7/9 : COPY docker-entrypoint.sh /usr/local/bin/
 ---> fcf7fa14ec24
Step 8/9 : ENTRYPOINT ["docker-entrypoint.sh"]
 ---> Running in a729bdc107cd
Removing intermediate container a729bdc107cd
 ---> f14080c41d29
Step 9/9 : CMD ["php-fpm"]
 ---> Running in 984ffd9caec4
Removing intermediate container 984ffd9caec4
 ---> 0853c264871b
Successfully built 0853c264871b
Successfully tagged gnuboard-fpm-alpine:1.0.0


마지막에 Successfully tagged gnuboard-fpm-alpine:1.0.0 이 뜨면 성공입니다.


이제 이 이미지로 실제 그누보드를 돌려봅시다.



10. 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=gnuboard
    volumes:
      - ./dbdata:/var/lib/mysql
    networks:
      - app-network


  gnuboard:
    depends_on:
      - db
    image: gnuboard-fpm-alpine:1.0.0
    container_name: gnuboard
    restart: unless-stopped
    env_file: .env
    volumes:
      - ./gnuboard:/var/www/html
      - ./php/php.ini:/usr/local/etc/php/php.ini
    networks:
      - app-network


  webserver:
    depends_on:
      - gnuboard
    image: nginx:alpine
    container_name: webserver
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./gnuboard:/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
      - ./gnuboard:/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:
  gnuboard:
  dbdata:
  nginx-conf:


networks:
  app-network:
    driver: bridge


설정파일이 정말 많죠? 


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




MYSQL_DATABASE=gnuboard


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


그누보드 이미지는 php-fpm과 연결된 직접 만든 이미지입니다.




./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 로 저장 후 빠져나옵니다.



상세 내용은 디지털오션 원문을 참조하세요.


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


11. docker-compose 실행하기



sudo docker-compose up -d


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


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



$ sudo docker-compose up -d
Creating network "gnuboard_app-network" with driver "bridge"
Creating network "gnuboard_default" with the default driver
Creating volume "gnuboard_certbot-etc" with default driver
Creating volume "gnuboard_gnuboard" with default driver
Creating volume "gnuboard_dbdata" with default driver
Creating volume "gnuboard_nginx-conf" with default driver
Creating db ... done
Creating gnuboard   ... done
Creating phpmyadmin ... done
Creating webserver  ... done
Creating certbot    ... done


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



sudo docker-compose ps


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




~/gnuboard$ sudo docker-compose ps
   Name                 Command               State                     Ports
-----------------------------------------------------------------------------------------------
certbot      certbot certonly --webroot ...   Exit 0
db           docker-entrypoint.sh mysqld      Up       3306/tcp
gnuboard     docker-entrypoint.sh php-fpm     Up       9000/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


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


SSL 인증서 없이 http로 테스트하려면 여기까지만 해도 도메인으로 바로 접속됩니다.



sudo docker-compose logs 서비스Name


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


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



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


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


물론 우리는 SSH에서 certbot 폴더를 만들었으므로


/home/sammy/gnuboard/certbot-etc/live


위 경로에 가면 다 있습니다 ^^;



~/gnuboard$ sudo docker-compose exec webserver ls -la /etc/letsencrypt/live
total 16
drwx------    3 root     root          4096 Aug  7 14:30 .
drwxrwxr-x    9 1001     1002          4096 Aug  7 14:30 ..
-rw-r--r--    1 root     root           740 Aug  7 14:30 README
drwxr-xr-x    2 root     root          4096 Aug  7 14:30 example.com


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


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



12. 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
      - gnuboard:/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 컨테이너만 다시 생성합니다.



~/gnuboard$ sudo docker-compose up --force-recreate --no-deps 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-11-05. 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


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



13. HTTPS 설정을 위한 Nginx 설정 수정하기


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



sudo docker-compose stop webserver


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



위 명령어로 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 gnuboard: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;
        }
        #### 그누보드5 nginx rules BEGIN #####
        if (!-e $request_filename){
        rewrite ^/content/([0-9a-zA-Z_]+)$ /bbs/content.php?co_id=$1&rewrite=1 break;
        rewrite ^/content/([^/]+)/$ /bbs/content.php?co_seo_title=$1&rewrite=1 break;
        rewrite ^/rss/([0-9a-zA-Z_]+)$ /bbs/rss.php?bo_table=$1 break;
        rewrite ^/([0-9a-zA-Z_]+)$ /bbs/board.php?bo_table=$1&rewrite=1 break;
        rewrite ^/([0-9a-zA-Z_]+)/write$ /bbs/write.php?bo_table=$1&rewrite=1 break;
        rewrite ^/([0-9a-zA-Z_]+)/([^/]+)/$ /bbs/board.php?bo_table=$1&wr_seo_title=$2&rewrite=1 break;
        rewrite ^/([0-9a-zA-Z_]+)/([0-9]+)$ /bbs/board.php?bo_table=$1&wr_id=$2&rewrite=1 break;
        }
        #### 그누보드5 nginx rules END #####
}


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


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


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



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


위 명령어로 webserver 컨테이너를 재생성합니다.



sudo docker-compose ps


위 명령어를 내리면



~/gnuboard$ sudo docker-compose ps
   Name                 Command               State                     Ports
-----------------------------------------------------------------------------------------------
certbot      certbot certonly --webroot ...   Exit 0
db           docker-entrypoint.sh mysqld      Up       3306/tcp
gnuboard     docker-entrypoint.sh php-fpm     Up       9000/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


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



14. 그누보드 접속하기


그누보드에 접속하기 전에 config.php를 수정하는 것이 좋습니다.


도메인 설정 및 이모지 적용을 위해서죠.


/home/sammy/gnuboard/gnuboard/config.php


위 파일이 그누보드의 설정파일입니다.


29~30번째 줄에



define('G5_DOMAIN', '');
define('G5_HTTPS_DOMAIN', '');


위 내용을



define('G5_DOMAIN', 'https://example.com');
define('G5_HTTPS_DOMAIN', 'https://example.com');


위와 같이 자신의 도메인을 넣습니다.


40번째 줄에



define('G5_DB_CHARSET', 'utf8');


위 내용을



define('G5_DB_CHARSET', 'utf8mb4');


위와 같이 바꾸면 이모지를 넣을 수 있습니다.




이제 그누보드 설정을 시작합니다.


https://example.com


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


3232235777_SEwJv3L8_f6e0be6add1ee44bce0dc273407ebcb09a08719d.png 


위와 같이 그누보드5를 먼저 설치해주십시오. 라는 말이 나옵니다! 그누보드5 설치하기를 눌러주세요.


3232235777_ya5I0fMG_6268bae4fe4725127bb40b94b85ba84c33355acf.png 


위와 같이 라이센스 내용이 나오고 동의합니다에 체크 후 다음을 누릅니다.


3232235777_HrUM5iE9_eb8a94e3387fb141f3f551ba21a7e3e0173e07dd.png 


위와 같이 MySQL정보와 최고관리자 정보입력이 나옵니다.


Host에는 db 만 넣으면 됩니다.


User와 Password는 7. 환경변수 설정하기에서 지정했던 그 유저와 비번을 넣으면 됩니다. ROOT 비번이 아닙니다.


DB에는 docker-compose.yml에 설정한 바로 그 값입니다. 수정하지 않았다면 gnuboard를 넣으면 됩니다.


TABLE명 접두사는 그대로 두시구요.



최고관리자 정보입력을 하면 됩니다.  회원ID 에는 admin을 제외한 자신이 원하는 아이디를 넣으세요.


그리고 나머지 정보를 입력하고 다음을 누르세요


3232235777_rOwC24dy_4dc7b4f71436ff791a2f51d6b641adc83241e3b7.png 


위와 같이 설치가 완료되면 성공입니다. 새로운 그누보드5로 이동을 누르세요.


3232235777_sAFg0y97_526bc2caa81afc8c370517fbc479044d1c2783fb.png 


위와 같이 그누보드가 뜨면 성공입니다.



15. SSL 인증서 갱신하기


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



nano ssl_renew.sh


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



#!/bin/bash


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


cd /home/sammy/gnuboard/
$COMPOSE run certbot renew  --no-random-sleep-on-renew --dry-run && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af



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


수정한 뒤, 컨트롤 + 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/gnuboard/ssl_renew.sh >> /var/log/cron.log 2>&1


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


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


1분 뒤에 명령을 내려보면



tail -f /var/log/cron.log


실시간으로 어떻게 작업이 되는지 확인할 수 있습니다.


하지만 1분 전에 내리면



~/gnuboard$ tail -f /var/log/cron.log
tail: cannot open '/var/log/cron.log' for reading: No such file or directory
tail: no files remaining


위와 같이 파일이 없다고 나옵니다. 당연합니다. 로그가 없으니 파일이 없을 수 밖에요.




tail -f /var/log/cron.log


1분 뒤에 위 명령어를 내려보면 



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


위와 같이 



** 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.)


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


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



sudo crontab -e


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



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


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


/home/sammy/gnuboard 경로는 자신의 환경에 맞게 수정하세요!


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





nano ssl_renew.sh


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



#!/bin/bash


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



cd /home/sammy/gnuboard/
$COMPOSE run certbot renew && $COMPOSE kill -s SIGHUP webserver
$DOCKER system prune -af



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


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





nano docker-compose.yml


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


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



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


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


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


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


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



16. SMTP 메일 설정하기


그누보드 SMTP 외부메일 설정하기


위 링크대로 하면 그누보드에서 인증용 메일을 편하게 보낼 수 있습니다.


실사용으로 충분히 쓰실 수 있을 것입니다.

관련자료

댓글 17 / 2 페이지

우성짱님의 댓글의 댓글

https://raw.githubusercontent.com/docker-library/wordpress/master/latest/php7.4/fpm-alpine/Dockerfile

경로가 여기로 바뀌었네요. 수정할게요. 감사합니다.

김민수님의 댓글

RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community<a> --allow-untrusted gnu-libiconv
ENV LD_PRELOAD /usr/lib/preloadable_libiconv.so php

<a> 이 부분이 오타인 듯 합니다.

김민수님의 댓글의 댓글

#!/bin/bash set -euo pipefail if [ ! -e data ]; then curl -o gnuboard.tar.gz -fSL https://github.com/gnuboard/gnuboard5/tarball/master \
&& tar -xf gnuboard.tar.gz -C ./ --strip-components=1 \
&& rm gnuboard.tar.gz && mkdir data \
&& chown -R www-data:www-data ./ \
&& chmod -R 777 data
fi
exec "$@"

이 부분도 오류가 납니다.
전체 34 / 1 페이지
RSS

최근글


새댓글


알림 0