우선 글을 시작하기 전에 개발 환경 자동화에 정말 도움을 많이 받은 글을 써주신 도커 컴포즈를 활용하여 완벽한 개발 환경 구성하기 를 작성해 주신 raccoony님과 개발환경을 한 방에! 쉘 스크립트의 힘(우형 기술블로그)를 작성해주신 라태웅님께 감사드립니다.

계기

신입 개발자라면 누구나 개발환경이란 것을 세팅하게 될 거라고 생각합니다. 이전의 회사의 경우 클라이언트에 따라 개발환경을 바꿔줘야 하는 경우가 있었는데, 이게 한번 꼬이면 귀중한 퇴근 시간을 미루는 주요 원인이 되곤 했죠... 그러던 중 우아한 형제들의 기술 블로그에서 개발환경 자동화를 읽었고, 지금 회사의 면접을 볼 때, 개발환경 자동화가 안 되어있다면 하고 싶다고 말을 꺼내는 바람에 개발환경 자동화를 진행하게 되었습니다. (다들 입조심합시다..)

사용 도구

현재 개발팀은 모두 Mac을 사용하기 때문에 Mac에서 사용할 목적으로 Shell script로 작성되었습니다.

  • Homebrew : Mac 용 패키지 관리 도구
    • git : 소스 버전 관리 도구
    • mas : Mac App Store 앱 관리 도구
  • Docker : 컨테이너 기반 가상화 도구
  • Slack : 업무 협업 도구

목표

  1. 현재 업무에 기본적으로 사용하는 협업 도구와 개발 도구를 자동으로 설치.
  2. slack으로 업무 관련 권한을 요청하는 메시지 전송.
  3. 권한을 받은 뒤, 자동으로 개발환경 세팅
  4. 새로 온 개발자분의 존경의 눈빛

협업&개발 도구 설치 및 메시지 전송

Homebrew 설치 (Hombrew Site)

Mac OS에서 앱을 설치하고, 관리하기 위하여 homebrew를 설치합니다.

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

앱 설치

hombrew로 설치할 앱의 정보는 아래의 명령어나 여기에서 찾을 수 있습니다.

brew search [APP_NAME]

Slack을 제외한 앱들은 앱스토어에 없어서 brew cask로 다운받았습니다.

brew : cli 기반의 앱
brew cask : UI 기반의 앱

mas로 설치할 경우 해당 앱의 id가 필요합니다.

mas search [APP_NAME]

명령어로 id를 찾거나, 앱스토어 링크에 id~부분을 찾으시면 됩니다.

저는 Brewfile이 존재하는지 확인 후, 있으면 Brewfile을 이용해서 앱을 설치하고, 없으면 필수로 필요한 앱들을 설치하도록 스크립트를 작성했습니다.

if [ -e ./Brewfile ];then
    brew bundle
    else
        brew install --force mas git
        brew cask install --force zeplin sourcetree docker google-chrome
        mas install 803453959 #slack
fi

Slack으로 담당자에게 메시지 전송 (Slack Incomming WebHook)

링크를 따라 Incomming WebHook을 생성하고, curl을 이용해서 메시지 전송합니다.

curl -X POST --data-urlencode "payload={'channel':'${channel} or ${target_user}', 'text':'개발팀에 싱싱한 개발자 [${NAME}]님이 새로 들어오셨어요!!\n관련 권한 부여 부탁드립니다!'}" "${slack_webhook_url}"

Slack 문서를 보면 payload에 많은 것들이 있지만, 일단 channel, text 정도로 충분합니다!

추가로 필요한 앱 설치

추가로 많이 사용하는 앱들을 선택적으로 설치할 수 있도록 합니다.

  • 카카오톡

    mas install 869223134 //KakaoTalk
  • IDE

    # 설치 할 앱 고르는 함수
    function answerCase() {
      echo --- Item list ---
      for PARAM in $*
      do
          echo $PARAM
      done
    
      while true;
      do
        printf "if you don't need to install item .exit\n"
        printf "Choice [enter item's name] : "
        read CASE_ANSWER
        for PARAM in $*
            do
                if [ $PARAM == "$CASE_ANSWER" -o "$CASE_ANSWER" == ".exit" ];then
                    return 1
                fi
            done
        echo invalid value.. try again!
      done
    }
    # 앱을 고른 뒤, 설치
    if [ $? == 1 ];then
          answerCase "visual-studio-code" "ntellij-idea" "sublime-text" "webstorm"
          if [ $CASE_ANSWER != '.exit' ];then
              echo 'Nice Choice!!  '$CASE_ANSWER
              brew cask install $CASE_ANSWER
          fi 
    fi

Docker를 이용한 개발 서버 띄우기

docker-compose로 DB 설정이나 여러 이미지를 묶을 수 있으나 현재는 CRA로 만들어진 개인 프로젝트를 클론하여 CRA의 개발 서버를 구동하도록 하겠습니다.

프로젝트 클론

git clone https://github.com/Hong-Ki/todo-list.git

Dockerfile 작성

Docker에서 공식으로 제공하는 Nodejs 이미지를 이용하여 프로젝트 이미지를 생성하겠습니다.

FROM node

WORKDIR /
RUN npm install -g yarn && npm install -g create-react-app

ADD ./todo-list/package.json    /
RUN yarn install
  • FROM : 어떤 이미지로부터 이미지를 생성할 것인지 지정합니다.
  • RUN : 실행할 명령어를 지정합니다. (Docker는 리눅스 기반이기 때문에 Shell script로 작성합니다.)
  • WORKDIR : 이미지 내부에서 명령을 실행할 디렉터리를 지정합니다.
  • ADD : 로컬에서 이미지 내부로 주입할 파일을 지정합니다. 두 개의 인자를 가지며 순서대로 로컬 경로, 이미지 경로입니다.

docker-compose.yml 작성

docker-compose.yml을 작성합니다.

이 부분부터는 Docker의 버전이 1.13.1 이상이어야 하고, docker-compose의 버전은 1.6.0 이상이어야 합니다.

version: '3'

services:
    node:
      image: node
    todo-list:
      build:
        context: .
        dockerfile: ./Dockerfile
      ports:
        - "3000:3000"
      command:
        - yarn
        - start
      volumes:
        - ./todo-list/src:/src
        - ./todo-list/public:/public
  • version : 파일의 규격 버전입니다. [파일 규격 버전 공식문서]
  • services : 실행하려는 서비스들을 정의합니다.
  • image : 서비스에 사용할 이미지를 정의합니다.
  • build : docker를 빌드 할 때 사용할 옵션입니다.
  • context : build를 실행할 디렉터리 경로입니다.
  • dockerfile : build에 사용할 Dockerfile경로 입니다.
  • command : docker 실행 시 사용할 명령어를 정의합니다.
  • volumes : 로컬의 디렉터리를 컨테이너의 해당 디렉터리에 주입합니다. (로컬의 코드 변경 시, 컨테이너에 반영돼야 할 폴더들을 작성해 줍니다.)

실행!

docker-compose up --build

후기

Docker를 알고만 있다가 실제로 처음 사용하다 보니 제대로 이해되지 않는 부분이 많다고 생각합니다. 실제로 사용할 다음 들어올 개발자분을 위해 더욱 다듬어야겠죠.. 적고 보니 다음에 내가 읽어도 이해가 안될 수도 있겠다 싶은 부분들은 공부하면서 다듬고 보충하겠습니다.

읽어주셔서 감사합니다! 설명 중에 제가 잘 못 알고 있는 부분이 있다면, 부디 알려주시길 바랍니다.