IntelliJ IDEA Preview 한글 깨짐

IntelliJ IDEA를 설치하면, 안드로이드 개발시 Layout xml의 Preview 창에 한글이 깨진다. 해결하기 위해서는 폰트를 재설정 해 주어야 한다.

필자는 금번에 Jetbrains의 Toolbox를 사용하여 IntelliJ IDEA를 설치하였다. 그래서 설치 경로는 다음과 같았다.

$HOME/.local/share/JetBrains/Toolbox/apps/IDEA-U/ch-0/172.4574.11/

폰트 설정 파일은 위의 경로 하위로 다음 경로에 있다.

plugins/android/lib/layoutlib/data/fonts/fonts.xml

노토 산스 CJK면 한글이 깨지지 않아야 할 것 같은데 깨지는 문제가 있다. 아래의 내용 중 NotoSansCJK-Regular.ttc를 나눔고딕으로 변경해 주면 된다.

<family lang="ko">
<font weight="400" style="normal" index="1">NotoSansCJK-Regular.ttc</font>
</family>

다음과 같이 변경하면 된다.

<family lang="ko">
<font weight="400" style="normal" index="1">NanumGothic.ttf</font>
</family>

IntelliJ IDEA 단축키 사용기

Jetbrains Night 서울에 참석한지 아직 일주일도 지나지 않았지만, 지난 한 주간 단축키 몇 개 더 쓰면서 들었던 생각과 금주에 학습하고 활용한 단축키를 몇 가지 소개하려 한다.

이전 포스팅에서도 언급했듯 한글97의 단축키는 대략 80% 이상을 외워서 사용했다. 물론 마우스 사용은 극도로 꺼렸는데, 그 이유는 문서 작업의 흐름이 끊기기 때문이었다. 단축키 5-6개로 작업 할 동안 마우스로는 한 두 가지 작업 밖에 못한다는 게 너무 답답해서, 늘 단축키를 습관처럼 사용했었다.

그러던 내가 IntelliJ IDEA를 사용하면서 활용하는 단축키가 30개도 안된다는 게 사실 이번 컨퍼런스에서 느낀 불편함이었다. 그래서 이번 행사에 참석한 후 intelliJ IDEA에서 최소한 일 평균 5번 이상 클릭이 반복된다 싶으면 단축키를 외워버리기로 마음을 먹었다.

이번 주에 사용하기 시작한 단축키가 몇 가지 있어서 소개하려 한다. 이미 아시는 분들도 많겠지만, 필자와 같이 그동안 단축키를 사용하지 않는 분들이 계실 수도 있으니 소개한다.

자주 사용하는 툴박스들의 단축키는 Linux에서는 Alt + 숫자키 그리고 맥에서는 Cmd + 숫자키이다. 특히 노트북을 사용할 때에는 화면이 비좁다. 때때로 툴박스를 접고 펴기 위해서 그동안은 마우스 클릭으로 토글해서 사용했는데, 단축키 한 번이면 마우스 움직이는 몇 초를 아낄 수 있다. ‘뭐 그깟 몇 초를 아낄려고 그렇게까지 하나’라고 생각할 수도 있는데, 그건 하루 이틀만 코딩하는 사람이라면 그렇게 말할 수 있을 것 같다. 뭐 똑똑하신 분들이야 시간이 좀 흘러도 작업하던 맥락을 잘 챙기시겠지만, 필자는 그리 똑똑한 편은 아니라 흐름이 끊기면 맥락을 다시 떠올리느라 고생한다. 뭐 그런 면에서 단축키는 분명 작업 중에 맥이 끊기지 않게 해 준다는 면에서 유용하다.

그리고 IDE 내의 터미널은 Alt + F12이다. 바로 해당 창을 열거나 닫을 때 해당 단축키들을 사용하니, 정말 편리하다.

기본으로 제공하지 않는 단축키들은 Settings(or Preferences)에서 직접 Keymap을 지정해 주면 된다. 안드로이드 개발 시에는 Android Monitor의 logcat을 활용할 때가 많은데, 기본으로는 단축키가 설정돼 있지 않아서 수동으로 설정해 주었다.

문자열 선택을 손쉽게 할 수 있는 단축키가 Mac에서는 Alt + up 또는 down 키를 사용해서 문자열 선택 범위를 넓히고 좁힐 수 있다. Ubuntu를 사용하면서 이 단축키를 찾았다. Ctrl + w 와 Ctrl + Shift + w로 각각 선택영역을 넓히고 줄일 수 있다.

마지막으로 단축키는 아니지만 가끔 문자열을 선택하고 따옴표나 쌍따옴표나 괄호로 묶어야 할 때가 있다. 문자열 시작점에 따옴표 하나 찍고 끝에 가서 따옴표 하나 더 찍기도 귀찮고 따옴표도 찍고 괄호도 쳐야하면 정말 귀찮기 짝이 없다. 그럴 땐 Settings(또는 Preferences)에서 Editor > General > Smart keys에서 Surround selection on typing quote or brace를 체크하고 적용한다. 그런 다음, 문자열 선택 후 따옴표나 괄호를 쳐보면 해당 문자열에 손쉽게 따옴표나 괄호 처리를 할 수 있다.

그동안 마우스로 클릭하면서 이걸 단축키로 할 수 없을까 싶었던 것들은 대체로 단축키가 있었다. 빠르게 단축키를 외우는 방법은 많이 사용해서 손에 익숙하게 하는 것보다 더 빠른 길은 딱히 없는 것 같다.

언젠가 기회가 되면 단축키 사용에 대해 정리를 한 번 해보고 싶다. 일단은 Jetbrains에서 제공하는 keymap 링크를 여기에 공유하며 글을 맺는다.

https://resources.jetbrains.com/storage/products/intellij-idea/docs/IntelliJIDEA_ReferenceCard.pdf

AWS EC2로 웹 서버 띄우기 전에 해야 할 일

필자는 AWS의 EC2 인스턴스를 제대로 활용해 볼 기회가 없었던, 그래서 AWS 초짜이다. EC2 인스턴스를 새로 생성해서 서비스해야 할 일이 생겨서 웹서버를 구축하다가 AWS 서비스의 구조를 잘 몰라서 잠시 고생을 했다. 웹서버를 띄웠는데 인스턴스와 IP는 어떻게 연결해 주어야 할 지, 도메인 세팅을 다 해 주었는데도 왜 접속이 되지 않았는지 고민하게 되었다.

결론은 AWS를 몰라서 생긴 이슈였다. 필자가 경험한 것을 바탕으로 AWS EC2 사용과정에서 꼭 필요한 과정들을 간단히 정리해 보았다. 혹여나 필자와 같은 처지에 있는 분들께 도움이 되길 바라는 마음으로 과정을 공유하고자 한다.

1. EC2 인스턴스를 생성한다.

2. ElasticIP를 추가한 후 생성한 인스턴스를 연결해 준다.

AWS의 인스턴스를 멈추고 다시 시작하면 새로운 내부 IP가 부여된다. 고정된 IP로 서비스하려면 엘라스틱 IP 서비스를 사용해야 한다.

3. 네임서버에 서비스하고자 하는 도메인에 대한 주소를 엘라스틱IP에서 할당받은 IP로 설정해 준다.

카페24나 도레지 등에서 네임서버를 설정할 수 있으면 굳이 라우트 53은 사용하지 않아도 된다.

4. 보안 그룹 페이지에 가서 서비스하고자 하는 포트를 열어준다.

기본적으로 EC2는 ssh 사용을 위해 22번 포트만 열어준다. 따라서 추가로 서비스를 제공하려면 해당하는 포트를 inbound에서 열어줘야 서비스가 가능하다.

JetBrains Night 서울에 다녀오고서..

어제 기다리고 기다리던 JetBrains의 행사에 다녀왔다. 행사의 주제는 IDE 팁, 생산성 향상을 위한 협업 툴 소개, 코틀린 소개, 레진코믹스에서 활용하고 있는 코틀린 현업 적용기, 그리고 질의응답 시간이었다.

일단 동시통역 덕분에 도움이 되기도 했지만, 개발 분야에서 사용되는 표현들을 해석하기보다는 그대로 말해주었다면 좀 더 매끄러웠을텐데 싶었던 부분도 일부 있었다. 하지만 나의 부족한 영어 실력은 통역의 도움을 안 받을 수 없었다. 어찌됐든 통역해 주신 분들께 이 자리를 빌어 감사의 인사를 전한다. 엄청난 집중력이 필요한 일인데, 그걸 해 내시다니 대단한 분들이라는 생각이다.

그 와중에 그냥 통역기 안 쓰고 행사에 참여하는 분들을 보며, 역시 가장 원활히 의사소통을 하려면 영어를 잘 하는 게 제일 좋겠구나 싶었다.

사설은 각설하고, 첫 세션은 IDE에 대한 팁을 알려주는 시간이었다. 추후 질의응답에서도 더 빨리 팁을 습득할 수 있는 방법이 없냐고 청중 속에서 질문이 있었는데, 역시 빠른 길은 없다. 그저 자주 사용해서 손에 익숙하게 만드는 방법 뿐인 거다. Hadi는 그냥 마우스 뽑고 키보드로만 IDE를 쓰라고 답해주어 청중에게 웃음을 주었다. 필자는 실제로 한글97을 사용할 때 마우스 사용 비율이 10%도 채 안 되었다. IDE도 그 정도로 꼭 쓰겠노라고 다짐했다.

별도의 유인물이 없어서, 일부 메모하기는 했지만, 너무 빠르게 진행이 되어서 도무지 뭘 봤는지 기억이 잘 나지 않는다. 역시 단축키는 그냥 외우고 직접 써보고 몸으로 편하구나를 느껴야 단축키를 쓴다. 예전에 생각했던 1일 1단축키 학습이라도 해야겠다.

생산성을 위한 협업 툴을 소개하는 시간에는 이슈 트래킹, 지속적 통합 등을 IDE와 연동해서 사용할 수 있음을 보여주었다. 대단하다 싶기는 한데, 사실 이미 다른 협업 툴을 쓰고 있다면 크게 필요가 있을까 싶었다. 필자는 회사에서 이슈 트래킹에는 gitlab을 CI에는 jenkins를 사용하고, 코드 리뷰에는 bitbucket을 활용하고 있다. 아직 협업 툴은 좀 더 지켜봐야 할 것 같다. 코드 리뷰 등에서 IDE의 코드 내용과 연동이 되면 좀 매력적일 것 같기는 하다.

그리고 가장 궁금했던 건 Kotlin 세션이었다. 재미있었던 것은 참가자들 중에 코틀린을 현업에 적용하고 있는 사람들은 많지 않았는데, 적용하고 싶어하는 사람들은 많았다는 것이다. 분명 Kotlin이 시장의 관심을 끄는 데에는 성공한 것이다. 물론 관심을 그렇게 끌기에 충분히 매력적이기 때문이리라 생각한다. 1.1 버전에 corputine과 typealias 등이 추가되었다고 한다. 자세한 건 역시 학습해야 할 것이다. 질의응답시간에 알게된 사실은 Jetbrains의 IDE도 코틀린으로 개발하고 있다는 것이었다. 자신들이 개발한 언어로 그들의 제품을 생산해 낸다는 것은 매력적이었다.

마지막으로 레진코믹스에서 Kotlin을 적용하고 있는 현업에서의 스토리를 만나보았다. 아무래도 우리말 세션이라 그런지 가장 이해하기 편했다. 가독성과 생산성이 가장 매력적인 지점으로 느껴졌다.

모든 시간을 통해서 공통적으로 느낀 건 기본기에 충실해야 한다는 거다. 겉멋만 들어가지고는 크게 도움이 되지 않는다는 것을 다시금 깨닫고 돌아왔다. 함수형 프로그래밍의 방법론들과 철학에 대해서도 다시금 고찰해 보기에 유익한 시간이었다.

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 설정을 차례로 하려한다.

SSL configuration generator & security test links

Mozilla에서 Apache, Nginx 등의 SSL 설정 내용을 생성해 주는 페이지가 있다.

Mozilla SSL configuration generator
https://mozilla.github.io/server-side-tls/ssl-config-generator

SSL 설정이 얼마나 잘 되었는지, 해당 도메인으로 접속했을 때 얼마나 안전한지, 접속 호환성이 있는지 확인할 수 있는 페이지가 있다. 테스트 결과를 등급과 점수로 제시하고 있어서, 현재 운용중인 사이트의 보안 수준을 확인하기에 좋다.

SSL Security Test
https://www.ssllabs.com/ssltest

SSL 보안 테스트를 한 후, XP에 IE 8인 경우 서비스를 제공할 수 없는 상태라는 것을 확인하였다. 그리고 해당 운영체제와 브라우저를 지원하려면 nginx를 해당 알고리즘을 지원하도록 다시 컴파일해서 설정하면 된다고 한다.

참고자료: https://ablagoev.github.io/ssl/nginx/ie8/winxp/cipher/2016/12/23/ie8-winxp-nginx-ssl.html

이런 정보를 알게된 후 XP 운영체제에서의 IE 8의 호환성을 제공하는 것이 중요한지 의문이 들었다. 게다가 해당 환경에서 사용할 알고리즘은 이미 보안 취약성을 가져서, 안전하지 않다. 진정으로 사용자를 위하는 길이 XP의 IE 8 호환성을 유지하는 것일까? 아니면 조금 위험하더라도 사용자가 접속할 수 있도록 길을 터 주어야 하는 것일까. 다시 말해서, 모든 사용자가 차별받지 않고 서비스를 이용할 수 있어야 하는가. 아니면 일부 소외된다 하더라도 안전한 서비스를 제공할 것인가의 문제다.

서비스를 제공하는 입장에서 XP 운영체제에 IE 8을 사용해야만 하는 사용자에게 미안한 마음이 들거나, 서비스를 이용하지 못하게 되는 것에 대한 아쉬움이 있을 수 있다. 하지만, 그 미안함과 아쉬움 때문에 사용자를 위험에 빠뜨려서는 안 될 것이다. 따라서 안전한 서비스를 제공하고 사용자에게 이용할 수 있는 안전한 환경을 제시하는 게 더 나은 길이라 생각한다.


간밤에 글을 쓰고 다시 고민해 보았다. 그럼에도 불구하고 어쩔 수 없는 타협점이 필요할 것이라는 생각이 들었다. 취약점이 모두 제거된 최신 브라우저나 단말기 사용자만 지원하는 게 보안상 더 안전할 수는 있겠지만, 과도하게 사용자의 접근성을 제한할 수도 있겠다는 생각이 들었다. 그런 지점에서 본다면, 서비스의 보안 담당자는 적절한 타협점을 찾고 의사결정을 하는 과정이 필요할 것이다.

PHP 7.1 string -n

PHP 7.1부터 문자열에 -n을 사용해서 특정 문자를 다루거나 변경하는 게 가능하다.

$a = "100KB";
echo $a[-2].PHP_EOL;
$a[-2] = "M";
echo $a;

결과는 다음과 같다.

K
100MB

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

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

MacOS X 한영전환 -> Shift + Space

일단 아래의 파일을 찾는다.

~/Library/Preferences/com.apple.symbolichotkeys.plist

아래의 키에 해당하는 값을 찾는다.

Root > AppleSymbolicHotKeys > 61 > value > parameters > item 2

131,072라는 값으로 바꾸어 준 후, 재부팅하면 된다.

그냥 로그아웃하고 로그인 해 봤는데, 변경이 되지 않아서, 다시 설정하고 재부팅한 후 성공하였다. 사용하는 OS는 MacOS X High Sierra이다.

DOS를 운영체제로 쓸 때, 한글 1.x를 사용할 때부터 이미 shift + space로 한영 전환하는 것에 길들여져 있어서 지금도 그 버릇이 어딜 가지 않는구나 싶다.

출처: http://macnews.tistory.com/3736