docker-compose 사용하기 – 2부. mariadb 추가설정 및 wordpress, nginx 설정

지난 번에 작성하던 docker-compose.yml 파일을 가져왔다.

version: '2.1'
services:
  mariadb:
    container_name: mydb
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_PW}
    volumes:
      - /Users/aaaa/con_volumes/mariadb/data:/var/lib/mysql
      - /Users/aaaa/con_volumes/mariadb/conf.d:/etc/mysql/conf.d

1부를 보셨던 분이라면 중요한 정보인 DB의 root 비밀번호를 MYSQL_PW라는 환경변수로 추출했던 것을 기억할 것이다.

환경변수로 추출할 부분이 더 있다. 바로 volumes에서 호스트의 경로 설정 부분이다. 컨테이너는 동일한 환경으로 구축해야 하지만, 로컬의 호스트는 사용자마다 다를 수 있다. 각자가 원하는 환경에서 도커를 구동하기 원할 것이다. 그래서 다음과 같이 환경 변수들을 추출하고, 설정파일 .env와 docker-compose.yml을 각각 다음과 같이 변경하였다.

MYSQL_PW=mypassword
MYSQL_DATA_PATH=/Users/aaaa/con_volumes/mariadb/data
MYSQL_CONFIG_PATH=/Users/aaaa/con_volumes/mariadb/conf.d
version: '2.1'
services:
  mariadb:
    container_name: mydb
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_PW}
    volumes:
      - ${MYSQL_DATA_PATH}:/var/lib/mysql
      - ${MYSQL_CONFIG_PATH}:/etc/mysql/conf.d

이제 어느 개발자의 머신에서든 서버에서든 각자의 입맛에 맞는 설정이 가능하다.

WordPress를 컨테이너로 띄울 것이다. 필자는 wordpress를 php 7.1으로 구동하는 fpm으로 띄울 것이며 도커 이미지 경량화를 위해 alpine 리눅스 이미지를 사용할 것이다. 관련 사항을 docker-compose.yml에 추가하려 한다. mariadb의 환경변수를 추출했던 것처럼 .env에 환경 변수는 별도로 설정한다.

# MYSQL
MYSQL_PW=mypassword
MYSQL_DATA_PATH=/Users/aaaa/con_volumes/mariadb/data
MYSQL_CONFIG_PATH=/Users/aaaa/con_volumes/mariadb/conf.d

# WORDPRESS
WP_DB_USER=root
WP_DB_PASSWORD=mypassword
WP_DB_NAME=my_wp_db
WP_DATA_PATH=/Users/aaaa/con_volumes/wordpress
version: '2.1'
services:
  mariadb:
    container_name: mydb
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_PW}
    volumes:
      - ${MYSQL_DATA_PATH}:/var/lib/mysql
      - ${MYSQL_CONFIG_PATH}:/etc/mysql/conf.d
  wordpress:
    container_name: wordpress
    image: wordpress:4.8.3-php7.1-fpm-alpine
    restart: always
    environment:
      - WORDPRESS_DB_HOST=mydb
      - WORDPRESS_DB_USER=${WP_DB_USER}
      - WORDPRESS_DB_PASSWORD=${WP_DB_PASSWORD}
      - WORDPRESS_DB_NAME=${WP_DB_NAME}
      - WORDPRESS_TABLE_PREFIX=wp_
    volumes:
      - ${WP_DATA_PATH}:/var/www/html

본 포스팅에서는 편의상 WP_DB_USER를 root로 설정해 주었다. 실제 상황에서는 maria db에 적절한 권한을 가진 사용자를 만들고 적어주면 되겠다.

이제 워드프레스 설정은 끝났다. 워드프레스 설정에 사용한 도커 이미지는 php-fpm으로 돌아가므로 nginx에서 proxy pass로 접근하게 할 것이다. nginx 컨테이너 설정도 추가로 해 준다.

# MYSQL
MYSQL_PW=mypassword
MYSQL_DATA_PATH=/Users/aaaa/con_volumes/mariadb/data
MYSQL_CONFIG_PATH=/Users/aaaa/con_volumes/mariadb/conf.d

# WORDPRESS
WP_DB_USER=root
WP_DB_PASSWORD=mypassword
WP_DB_NAME=my_wp_db
WP_WWW_PATH=/Users/aaaa/con_volumes/wordpress
version: '2.1'
services:
  mariadb:
    container_name: mydb
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_PW}
    volumes:
      - ${MYSQL_DATA_PATH}:/var/lib/mysql
      - ${MYSQL_CONFIG_PATH}:/etc/mysql/conf.d
  wordpress:
    container_name: mywp
    image: wordpress:4.8.3-php7.1-fpm-alpine
    restart: always
    environment:
      - WORDPRESS_DB_HOST=mydb
      - WORDPRESS_DB_USER=${WP_DB_USER}
      - WORDPRESS_DB_PASSWORD=${WP_DB_PASSWORD}
      - WORDPRESS_DB_NAME=${WP_DB_NAME}
      - WORDPRESS_TABLE_PREFIX=wp_
    volumes:
      - ${WP_WWW_PATH}:/var/www/html
  nginx:
    container_name: mynginx
    image: nginx:1.12.2-alpine
    restart: always
    ports:
      - 80:80
    volumes:
      - ${WP_WWW_PATH}:/var/www/html

일단 위와 같은 설정이면 컨테이너 3개가 모두 정상적으로 뜬다. http://localhost에 접속하면 welcome to nginx! 화면을 볼 수 있다.

이제 nginx에 워드프레스 php-fpm에 대한 proxy_pass를 설정해주면 된다.

그리고 컨테이너 간의 통신을 위해서는 networks 옵션을 사용하면 된다. 사실 지금까지 네트워크 옵션을 주지 않았지만, 자동으로 aaaa_default 라는 네트워크가 생성되어 해당 네트워크를 통해 통신하고 있었던 것이다. 필자는 my-net이라는 네트워크 이름을 지정해서 사용해 보도록 하겠다. 먼저 docker network create my-net 명령으로 네트워크를 생성한 후, 아래와 같이 .env와 compose 파일을 각각 설정한다.

# MYSQL
MYSQL_PW=mypassword
MYSQL_DATA_PATH=/Users/aaaa/con_volumes/mariadb/data
MYSQL_CONFIG_PATH=/Users/aaaa/con_volumes/mariadb/conf.d

# WORDPRESS
WP_DB_USER=root
WP_DB_PASSWORD=mypassword
WP_DB_NAME=my_wp_db
WP_WWW_PATH=/Users/aaaa/con_volumes/wordpress

# NGINX
NGINX_VHOSTS=/Users/aaaa/con_volumes/nginx/vhosts.conf

# NETWORK
MY_NETWORK=my-net
version: '2.1'

services:
  mariadb:
    container_name: mydb
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_PW}
    volumes:
      - ${MYSQL_DATA_PATH}:/var/lib/mysql
      - ${MYSQL_CONFIG_PATH}:/etc/mysql/conf.d
    networks:
      - mynet

  wordpress:
    container_name: mywp
    image: wordpress:4.8.3-php7.1-fpm-alpine
    restart: always
    environment:
      - WORDPRESS_DB_HOST=mydb
      - WORDPRESS_DB_USER=${WP_DB_USER}
      - WORDPRESS_DB_PASSWORD=${WP_DB_PASSWORD}
      - WORDPRESS_DB_NAME=${WP_DB_NAME}
      - WORDPRESS_TABLE_PREFIX=wp_
    volumes:
      - ${WP_WWW_PATH}:/var/www/html
    networks:
      - mynet

  nginx:
    container_name: mynginx
    image: nginx:1.12.2-alpine
    restart: always
    ports:
      - 80:8080
    volumes:
      - ${NGINX_VHOSTS}:/etc/nginx/conf.d/vhosts.conf
      - ${WP_WWW_PATH}:/var/www/html
    networks:
      - mynet

networks:
  mynet:
    external:
      name: ${MY_NETWORK}

이제 해당 컨테이너들은 my-net이라는 docker network를 공동으로 사용하게 된다. 같은 네트워크를 사용하는 컨테이너끼리는 대상 호스트명을 컨테이너 이름으로 사용할 수 있게 된다. 그리고 기본 엔직엑스 경로가 아닌 워드프레스를 내보낼 것이므로 내부 컨테이너 포트를 8080으로 변경해 주었다. 이제 엔직엑스 설정 파일 vhosts.conf를 살펴보겠다.

server {
    listen 8080;
    server_name localhost;

    root /var/www/html;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?q=$uri&$args;
    }

    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass mywp:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
    }
}

컨테이너 내부의 서버 포트는 8080으로 설정해 주었다. 그리고 fastcgi_pass는 docker-compose에서 컨테이너 이름으로 설정해 주었던 mywp를 호스트 이름으로 사용하고 있는 것을 볼 수 있다.

모든 설정이 다 되었다면, docker-compose로 컨테이너를 띄운다. 이제 웹 브라우저를 실행하고 localhost에 접속해 보면, 워드프레스 설정 화면을 만나볼 수 있다.

간단히 도커 이미지를 사용해서 워드프레스를 띄우는 작업을 함께 해 보았다. 참, 도커 이미지의 버전을 지정하지 않으면 최신 버전이 설치될 수 있으므로 동일한 환경 설정을 위해서 필자는 도커 이미지의 버전을 모두 지정해 보았다. 그리고 docker-compose에는 build 옵션을 사용하여 Dockerfile을 빌드할 수도 있다. 필자는 docker-compose를 적용한 후 자질구레한 중복 쉘 스크립트들을 제거할 수 있었고, 서버 재시작 시에도 안심하고 서버를 띄울 수 있게 되었다. 컨테이너를 효율적으로 관리할 수 있는 도구들이 또 있다고 한다. 좀 더 학습해 보아야겠다.

혹시 아직도 docker run으로 컨테이너를 띄우고 계신 분이 있다면, docker-compose 적용을 시도해 볼 것을 권한다. 이것으로 2부로 docker-compose 활용에 대한 포스팅을 마친다.

docker-compose 사용하기 – 1부. mariadb 설정

서비스는 하나인데 사용해야 하는 컨테이너가 여러 개인 경우 매번 docker build, docker run, docker stop, docker rm, docker restart 등의 명령어를 사용하는 것은 말도 못하게 번거롭다. 필자는 바로 쉘 스크립트로 해당 명령어들을 작성해서 보관하기 시작했는데, 컨테이너 개수가 늘어나면서 관리할 쉘 스크립트도 덩달아서 늘어나고, 스크립트 내에서 사용하는 환경 변수들에 대한 처리 문제도 덩달아 발생하였다. docker-compose를 사용하면 build부터 컨테이너를 띄우는 순서까지 모두 결정할 수 있으며 docker-compose up -d 라는 명령어 한 줄이면 docker-compose.yml에 설정된 모든 컨테이너를 한 번에 바로 띄울 수 있다.

docker-compose 설정 파일은 YAML을 사용하여 서비스, 네트워크, 볼륨 등을 설정할 수 있다. 간단한 시나리오를 상정하고 docker-compose 파일을 설정해 보려한다. 워드프레스로 웹 사이트를 운영할 것이고, 데이터 베이스는 mariadb를 사용하고, 웹 서버는 nginx를 사용할 것이다. 본 포스팅에서는 우선 mariadb에 대한 docker-compose 파일 설정을 먼저 해 볼 것이다.

그에 앞서 버전 이야기를 먼저 하려고 한다. docker-compose는 docker 엔진 버전에 따라 docker-compose 파일 버전을 맞추어 설정해야 한다. 만일 도커 엔진 버전이 낮으면 해당 엔진 버전에 상응하는 docker-compose 파일 버전 이상을 사용할 수 없다. 따라서 docker-compose를 사용하려면 현재 자신이 사용하는 도커 엔진의 버전을 확인하고 적용할 수 있는 docker-compose 파일 버전을 확인한 후 사용해야 한다.

도커 버전은 다음의 명령어로 확인할 수 있다.

docker —version

일례로 필자가 사용중인 도커 엔진은 1.12 버전이다. 이 경우 docker-compose 파일 버전은 2.1까지 사용할 수 있다. 자신이 사용하는 도커 버전을 확인한 후, 아래 주소에서 자신이 사용할 수 있는 docker-compose 파일 버전을 확인한 후 활용하면 된다.

https://docs.docker.com/compose/compose-file

물론 버전에 따라 사용할 수 있는 문법의 지원 정도에 차이가 있는 것은 당연하며, 도커 엔진 버전에 상응하는 docker-compose 파일 버전보다 높은 버전으로 설정하면 오류가 발생한다.

docker-compose.yml 파일에 다음과 같이 적어주면 docker-compose 파일의 버전 설정이 끝난다.

version: '2.1'

그러면 이어서 mariadb 컨테이너 설정을 해보자. services는 띄울 컨테이너 서비스들을 모아서 설정하는 곳이다. 자신이 띄울 서비스의 이름을 적어준다. 필자는 mariadb라고 적어주었다.

version: '2.1'
services:
  mariadb:
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=mypassword
    volumes:
      - /Users/aaaa/con_volumes/mariadb/data:/var/lib/mysql
      - /Users/aaaa/con_volumes/mariadb/conf.d:/etc/mysql/conf.d

위의 설정은 mariadb:10.2.10이라는 image를 사용할 것을 의미한다. 재시작 옵션을 always로 하겠다는 것은 컨테이너 종료 상태와 상관없이 항상 재시작하겠다는 것이다. 이 옵션을 설정해 두면, PC을 껐다 켠 후에 컨테이너가 자동으로 뜨는 것을 확인할 수 있을 것이다.

그 다음은 enviroment 옵션인데, MYSQL_ROOT_PASSWORD를 mypassword로 설정해 주었다.

그리고 volumes 옵션을 통해서 Host 경로를 Container 경로로 마운팅하게 해 놓았는데, 도커 컨테이너를 삭제하면 당연히 컨테이너의 내용은 모두 사라진다. DB을 보존하기 위해서는 호스트 경로로 저장되도록 설정해야 한다. 콜론(:)을 중심으로 왼쪽은 호스트 경로, 오른쪽은 컨테이너 경로이다. /var/lib/mysql 경로는 DB가 저장되는 경로이고, /etc/mysql/conf.d는 mysql 환경설정을 별도로 오버라이딩 하기 위한 경로이다.

도커를 띄우기 전에 /Users/aaaa/con_volumes 디렉토리를 생성해 줘야 한다. mariadb 이후의 경로는 도커가 알아서 생성해 준다.

mkdir con_volumes

여기에서 잠깐! MYSQL_ROOT_PASSWORD는 환경변수이다. git과 같은 버전관리 도구를 사용하면서 docker-compose.yml 파일을 커밋하고 푸시하면, DB의 root 패스워드가 공개된다. 이러면 안된다. 그래서 환경변수로 설정을 해 주어야 한다.

docker-compose는 기본으로 .env 파일을 환경변수 파일로 인식한다. 필요한 변수를 .env에 설정해 주고, .gitignore에 추가한다. 새로 생성한 .env 파일과 변경한 docker-compose 파일은 다음과 같다.

MYSQL_PW=mypassword
version: '2.1'
services:
  mariadb:
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_PW}
    volumes:
      - /Users/aaaa/con_volumes/mariadb/data:/var/lib/mysql
      - /Users/aaaa/con_volumes/mariadb/conf.d:/etc/mysql/conf.d

이제 docker-compose.yml 파일을 안전하게 커밋해도 된다. 각자의 환경변수로 필요한 설정을 해서 사용하면 될테니 말이다.

이제 docker-compose 명령어로 컨테이너를 띄워보자.

docker-compose up -d

위와 같이 입력하면 기본적으로 .env 파일에서 환경변수를 읽어들이고, docker-compose.yml 파일을 찾아서 컨테이너를 띄우게 된다. 만약 docker-compose.yml 파일을 사용하지 않고 파일이름을 특정하고 싶다면 자신이 원하는 파일이름으로 저장한 후,  docker-compose -f FILENAME.yml up -d이라고 해 주면 된다.

docker-compose의 up 명령어는 컨테이너를 새로 생성하고 띄우라는 것이고, -d는 background 모드로 실행하겠다는 것이다. 이제 컨테이너가 작동하는지 확인해 보자.

docker-compose ps

aaaa_mariadb_1 라는 이름의 컨테이너가 떠 있는 것을 확인할 수 있다. 동일한 서비스이름을 사용할 수 있기 때문에 접두어와 접미어가 붙어있다. 접두어와 접미어를 붙이지 않고 그냥 mydb라고 간단히 명명하고 싶다면 다음과 같이 파일을 수정하면 된다.

version: '2.1'
services:
  mariadb:
    container_name: mydb
    image: mariadb:10.2.10
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_PW}
    volumes:
      - /Users/aaaa/con_volumes/mariadb/data:/var/lib/mysql
      - /Users/aaaa/con_volumes/mariadb/conf.d:/etc/mysql/conf.d

일단 docker-compose 사용하기의 첫 포스팅은 여기까지이다. 글이 너무 길어지는 것 같아서 다음 포스팅에 wordpress와 nginx 설정을 차례로 하려한다.

Dockerfile –build-arg option

도커 컨테이너를 띄울 때 volume을 설정해서 persistence를 잡아 줄 때, 컨테이너에 마운팅되는 방식이 머신별로 차이가 있는 것을 발견하였다.

필자는 php:7.1.10-fpm-alpine 이미지를 이용하여 컨테이너를 띄웠다.

볼륨을 마운트하면, 마운팅 된 디렉토리의 UID와 GID가 계속 1000으로 나오는 것이었다.

컨테이너에서 php-fpm을 띄우는 사용자는 www-data로 세팅해 놓았고, www-data 사용자의 UID와 GID는 둘 다 기본으로 82로 잡혀 있었다.

www-data 사용자로는 마운팅된 디렉토리에 쓰기 permission이 주어지지 않았으니 기록을 못하는 것이 당연하다.

그래서 찾아낸 것이 Dockerfile을 빌드할 때 주는 옵션이 있다는 것을 알게 되었다. 바로 “–build-arg 변수명=변수값”이다. 컨테이너 내의 사용자인 www-data의 UID를 Host에서 현재 docker를 사용하는 사용자의 UID로 바꾸면 된다.

docker build \
  --build-arg HOST_UID=$(id -u) \
  --build-arg HOST_GID=$(id -g)

위와 같이 UID와 GID를 설정하고 Dockerfile에는 아래와 같은 내용을 추가하였다.

ARG HOST_UID
ARG HOST_GID

RUN usermod -u ${HOST_UID} www-data
RUN groupmod -u ${HOST_GID} www-data

도커 이미지를 생성한 후 컨테이너의 www-data 사용자의 UID가 바뀐 것을 확인하였다.

이렇게 하면, 개발자마다 로그인하여 사용하는 PC의 UID가 다르더라도 각자의 환경에 맞게 적용이 가능하다.

필자는 개발용 머신으로 우분투 17.10을 사용 중인데, 별 문제 없이 잘 되었다. 하지만, MacOS에서는 Group 이름이 staff이며 GID는 20이라서 다음과 같이 충돌이 발생한다.

groupmod: GID '20' already exists

테스트 해 본 결과 Mac에서는 GID를 변경하지 않아도, Host의 파일의 권한이 Host의 UID와 GID로 유지된다. 하지만 Host가 리눅스인 경우 GID를 변경하지 않으면 컨테이너의 www-data 그룹의 기본 id인 82로 세팅되는 것을 확인하였다.

따라서 Mac에서는 빌드 시에 다음과 같이 GID 세팅을 빼 주면 된다.

docker build \
  --build-arg HOST_UID=$(id -u)

Dockerfile에서는 GID 변경 부분을 제외한다.

ARG HOST_UID

RUN usermod -u ${HOST_UID} www-data

작성하고 보니, 이 부분들도 쉘 스크립트를 작성하면 중복을 제거하고 하나의 파일로 구동이 가능할 것 같다. 이 부분은 독자의 몫으로 남겨놓겠다.

docker –link option is deprecated

도커가 컨테이너를 띄울 때 내부 아이피를 사용하는데, 그 아이피가 고정되어 있지 않기 때문에, 컨테이너 간에 접근할 때 아이피를 사용하면 그 때 당시에는 되겠지만, 추후에 컨테이너를 다시 띄우면 IP 주소가 새로 할당되기 때문에 컨테이너 이름을 호스트 이름으로 사용해야 한다.

과거에는 –link 옵션을 사용해서 컨테이너를 서로 연결해 주었다. 이제는 docker network가 그 기능을 대신하고 있고, –link 옵션은 deprecated 상태이다. 언젠가 완전히 사라질 것이다.

네트워크를 설정하는 방법은 우선 도커 네트워크를 생성한다. 그 후에 컨테이너를 띄울 때 해당 네트워크를 사용하도록 설정해 주면 된다. 해당 네트워크를 사용하는 컨테이너에서 접근하고자 하는 대상 컨테이너 이름을 호스트 이름으로 사용할 수 있게 된다.

우선 도커 네트워크를 생성할 이름과 함께 아래와 같이 입력한다.

docker network create NETWORK-NAME

ls 명령어를 사용하여 도커 네트워크가 추가된 것을 확인한다.

docker network ls

이제는 특정 컨테이너를 실행할 때 사용할 네트워크를 지정해 준다. mysql과 php-fpm을 사용한다고 가정하고 아래와 같이 –network 옵션을 설정해 준다.

docker run ..... --name mysql --network NETWORK-NAME mysql:5.x.x
docker run ..... --name php --network NETWORK-NAME php:5.6-fpm

이제 호스트이름을 그냥 사용하면 된다. 위의 경우와 같이 컨테이너를 띄웠다면, 각 컨테이너의 이름인 mysql, php로 상호간에 접근할 수 있게 되었다.

그리고 이렇게 하면 해당 컨테이너의 해당 포트로 바로 접근 가능하므로 굳이 port를 publish 하면서 사용하지 않아도 된다.

만일 NGINX 컨테이너를 하나 더 띄워서 nginx.conf 에서 fastcgi를 설정하는 경우라면 php-fpm은 보통 9000번 포트를 사용하니 아래와 같이 설정해 주면 된다. 해당 서버 설정 구간에 다음과 같이 호스트명으로 잡아주면 된다.

fastcgi_pass php:9000;

 

참고자료: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/

https://docs.docker.com/engine/userguide/networking/

Gitlab with docker and setup ssl using letsencrypt on macOS

Docker image를 생성하고 실행한다.

컨테이너의 443, 80, 22 포트는 각각 Mac의 8443, 8080, 8022로 매핑해준다. 동일한 포트로 사용하기 원하면 443:443과 같이 써주면 된다.

sudo docker run --detach \
 --hostname gitlab.example.com \
 --publish 8443:443 --publish 8080:80 --publish 8022:22 \
 --name gitlab \
 --restart always \
 --volume /Users/[username]/apps/gitlab/config:/etc/gitlab \
 --volume /Users/[username]/apps/gitlab/logs:/var/log/gitlab \
 --volume /Users/[username]/apps/gitlab/data:/var/opt/gitlab \
 gitlab/gitlab-ce:latest

Letsencrypt 인증서 생성을 위해 certbot을 설치한다.

brew install certbot

certbot을 사용하여 인증서를 만들려고 시도하였다.

sudo certbot certonly --manual -d mydomain.org

하지만 augeas 와 관련된 오류를 만났다. 퍼미션 관련 설정을 해 주었다.

sudo chown [username] /usr/local/lib/pkgconfig

다시 certbot을 실행하여 인증서 생성을 시도하였다.

sudo certbot certonly --manual -d mydomain.org

접속할 수 있는 IP인지 물어본다. y로 대답한다.

Are you OK with your IP being logged?
----------------
(Y)es/(N)o:

생성할 파일의 내용과 경로를 알려준다. 준비가 되면 엔터를 치라고 한다.

Create a file containing just this data: 293487987fd9s87s98fa798s7df7sadf987saf79dsa97afsd897dsaf987 And make it available on your web server at this URL: http://mydomain.org/.well-known/acme-challenge/fas89adfs87dasf9asdf78

-----------------------------
Press Enter to Continue

해당 경로에 파일을 만들어주어야 하기 때문에 gitlab.rb를 편집한다.

vi /Users/[username]/apps/gitlab/config/gitlab.rb

다음 줄을 추가해 준다.

nginx['custom_gitlab_server_config'] = "location ^~ /.well-known { alias /etc/gitlab/www; }"

해당 내용을 적용해 준다.

docker exec -it gitlab /bin/bash gitlab-ctl reconfigure

그리고 아래의 경로에 해당 파일을 위에서 알려준 내용으로 만들어 주었다.

vi /Users/[username]/apps/gitlab/config/www/acme-challenge/[instructed filename]

파일내용:
293487987fd9s87s98fa798s7df7sadf987saf79dsa97afsd897dsaf987

다시 certbot을 실행한 shell로 돌아가서 Enter를 누른다.

이제 /etc/letsencrypt/live/[mydomain.org]에 인증서 파일들이 생겼다. ssl 디렉토리를 생성하고 인증서를 복사한다.

cd /Users/[username]/apps/gitlab/config
mkdir ssl
cd ssl
sudo cp /etc/letsencrypt/live/[mydomain.org]/fullchain.pem ./
sudo cp /etc/letsencrypt/live/[mydomain.org]/privkey.pem ./

다시 gitrab.rb를 편집하러 간다.

vi /Users/[username]/apps/gitlab/config/gitlab.rb

다음 3개의 줄을 편집해 준다.

external_url 'https://[mydomain.org]'
nginx['ssl_certificate'] = "/etc/gitlab/ssl/fullchain.pem"
nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/privkey.pem"

첫째 줄은 외부 접속 경로를 설정해 주는 것이다. 필자는 외부에서도 접속할 수 있게 하려고 하였기 때문에 개인적으로 사용하는 도메인 이름을 적어 주었다.

둘째, 셋째 줄은 인증서 파일에 대한 경로를 설정해 주는 것이다.

이제 준비가 되었다. 적용해 준다.

docker exec -it gitlab /bin/bash gitlab-ctl reconfigure

웹 브라우저를 띄우고 접속해 본다.

필자는 공유기 – MacOS – docker container(Ubuntu 16.04) 의 구조였고, 포트는 8443:8443:443이었으므로

https://[mydomain.org]:8443

으로 접속하였다. 자물쇠가 나오는 것을 확인하면 SSL이 제대로 설정된 것이다.

두서 없이 썼지만, 기억은 잘 잊혀지므로  기록하였다.

다음엔 letsencrypt 인증서 만료 기간이 3개월이니, 자동으로 갱신되도록 만들어 보아야겠다.