도커로 블로그 로컬 빌드하기 + 그런데 이제 로컬엔 WSL과 도커만 설치한
포스트
취소

도커로 블로그 로컬 빌드하기 + 그런데 이제 로컬엔 WSL과 도커만 설치한

table of contents

개요

왜 이런 짓을 하게 되었나

윈도우 11에 WSL과 도커만 설치해서 루비와 jekyll로 돌아가는 깃허브 블로그를 돌려보자.

왜 WSL과 도커만 쓰냐면요:

  1. 내 로컬에 Node.js나 Ruby는 설치하기 싫음: 블로그 돌리기 말고는 쓸 일이 없고, 나중에 삭제할 때 번거로움
  2. WSL에 올려도 되지만, 그건 로컬이랑 마운트하고 이것저것 설치해서 빌드하고 실행하는 과정이 포함될 뿐더러, 여차하면 삭제하고 싶다고 딸깍 삭제되는 게 아님. WSL은 윈도우 기본 기능 중 하나라 그런지 삭제한다고 깨끗하게 사라지지 않더라.
  3. 도커에 올려도 설치하고 빌드하는 건 똑같이 할텐데 왜 도커냐?
    1. 새로 배운 김에 이렇게라도 써야 나중에 기억함
    2. chirpy 공식 가이드가 도커 사용을 권장함
    3. 도커는 컨테이너 지우면 깔끔하잖아
  4. WSL은 싫다면서 왜 깔았냐? 도커 하려면 최소한 WSL은 필요해,, 이게 내 최대한의 타협임.

도커 말고 다른 건 없음?

대다수 사용자는 기본 OS로 윈도우를 씀. 적어도 내가 아는 범위에서는 윈도우 쓰더라.

근데 나는 개발을 해야 하잖아요. 윈도우는 일반 사용자에게 편한 OS지 개발하기 좋은 OS는 상당히 아니거든요. 하다보면 리눅스가 필요한 순간이 정말 많아요. 피하고 싶다고 피할 수 있는 OS가 아님.

그럼 윈도우가 디폴트인 사용자가 리눅스를 쓰는 방법이 뭐가 있느냐? 다양하긴 함.

  1. PC를 2대 장만한다
    • 사실 이거 하면 모든 문제가 해결되긴 하지만요. 컴퓨터가 공짜겠습니까? 돈이 없으면 할 수가 없어요. 그래서 나는 시도도 안+못해봤음.
  2. 네이티브 리눅스 듀얼부팅
    • 내가 이거 몇 년 해봤는데, 네이티브 리눅스를 쓸 수 있다는 게 제일 강력한 장점이긴 한데요. OS를 바꿀 때마다 전원을 껐다 켜야 하는 게 여간 불편한 게 아님.
    • 이게 되게 소소한 번거로움이긴 한데, 매번 전원 켤 때마다 GRUB 화면 나오는 거 기다렸다가 8초 안에 OS를 선택해야 윈도우를 쓸 수 있음. 시간 지나면 무조건 리눅스 켜지는 거임. 난 윈도우가 쓰고 싶은데! 전원 누르면 알아서 켜지면 좋겠는데!
    • 파티션부터 내가 관리해줘야 함. 윈도우는 얼마나 주고 리눅스는 얼마나 줄까? 용량 분배부터 시작해서 어느 OS가 앞쪽에 있느냐에 따라 나중에 용량을 변경하는 것도 될 수도 있고 안될 수도 있는거임. 리눅스 얼마 안 쓸 것 같아서 적게 줬다가 부족하면 더 떼주기? 그게 마음같지 않을 수 있다. 너무 많이 줘서 돌려받기? 안될 수도 있다. 만약 된다고 해도 두 OS에서 차례대로 파티션을 자르고 붙여줘야 한다. 번거롭다.
    • OS 재설치가 꽤나 마음졸이는 작업이 된다,,, 윈도우는 일반 사용자만큼 쓰니까 망가질 일이 거의 없죠. 근데 리눅스는 망가지는 것도 일상이거든. broken package가 apt 수준에서 고쳐지면 다행이지. 그것도 안되어서 정말 초기화밖엔 방법이 없다 하면 해야지 뭐 어떡해. 근데 이거 재설치할 때 파티션 구분 잘못하면 윈도우 날아가고 고장난 리눅스와 안 고장난 리눅스만 얻게 되는 거 아시죠?
    • 저거 말고도 말하자면 참 이것저것 있지만,, 어쨌든 한번은 경험삼아 해볼 수 있는 일이지만 또 하라면 난 비추천한다. 듀얼부팅 설치하는 방법 찾아보고 배울 시간에 도커 배워. 그게 낫더라.
  3. 가상머신(버추얼박스, VMware 등등)
    • 자 제일 큰 문제가 있어. 가상머신을 하나 만들기만 해도 용량은 가볍게 15기가 정도 먹고 시작하는데, 느리고 화면이 작아. 터미널 켰는데 화면 나오기까지 10초 걸려봐. 얼마나 마음이 급해집니까 네이티브는 누르면 그냥 나오는데.
    • 다음으로 문제가 있어. 화면이 작다는 부분. 이게 윈도우에서 버추얼박스로 가상머신 처음 만들면 화면 크기가 800 * 600으로 고정돼서 나오거든요. 게스트 확장 찾아서 넣어줘야 화면 크기 조절이 돼요. 다만 화면이 커질수록 사양을 먹으니까 그만한 자원이 받쳐줘야 한다는 점도 소소한 단점임.
    • 용량 참아줬고, 느린 거 참고, 화면 크기까지 잡았어. 그 다음으로 뭐가 있냐? 네트워크 연결이 안돼. 기본값이 윈도우 내부 가상 네트워크에 갇혀있어서 설정에서 따로 찾아서 열어줘야 해. USB도 안들어가. 똑같이 갇혀있거든. 적절한 설정 찾아서 직접 지정해서 연결해줘야 해. 그렇게 해도 안되는 PC를 많이 봤어,,
    • 고생고생해서 겨우 쓸만한 환경 만들어놨더니 다음엔 무슨 일이 생기냐? 기분탓인지 모르겠지만 broken package가 네이티브보다 훨씬 쉽게 생겨. 근데 문제 해결은 배로 어려워. 이제 어떻게 해? 가상머신을 삭제하고 처음으로 돌아가 다시 진행한다. 진짜 말도안되는데 이렇게 하게 됨.
    • 장점 딱 하나 있지. 아무거나 마음 편하게 시도해보고 아 이렇게 하면 리눅스가 터지는구나 배우기. 가상머신 지우면 깔끔하거든.
  4. WSL 쓰기
    • 이거 꽤 괜찮은 방법이긴 한데요, 여전히 남아있는 문제들이 있다. 일단 네트워크와 USB가 내부망에 갇혀있는 게 가상머신이랑 마찬가지임. 가상머신은 GUI로 그걸 열어줄 수 있지만 WSL은 터미널로 해결해야 함. 훨씬 낯설고 그러니까 어렵죠. 물론 요즘 쓰는 WSL 2는 그것도 편의성이 많이 개선되었다는 것 같긴 하더라.
    • GUI 보기가 힘들다. 기본적인 gedit부터 해서 내가 쓰던 ROS 같은 것들은 GUI를 봐야만 하는데, 이거 보려면 또 뭘 설치하고 설정하고 그래야 한대. WSL 2는 또 마찬가지로 편의성 개선을 했다고는 하는데 나는 WSL 1만 쓰고 접어서 잘 모름.
  5. 도커 쓰기
    • 위에 있는 방법들을 다 거쳐서 이제 여기까지 온 거임. 도커 자체가 생소하다는 진입장벽을 견디면 많은 것이 편해지더라.
    • 일단 로컬과 컨테이너가 확실하게 분리되니까 컨테이너 쪽에 아무거나 다 깔아봐도 돼.
    • 네트워크,,는 아직 손을 안대봤지만, 포트 매핑이 된다는 건 알지. 컨테이너 안에서 AWS EC2로 ssh 되는 것도 확인했어. 그거 되면 어지간한 건 될걸.
    • USB 안꽂아봤지만 로컬 스토리지 매핑이 되니까 하려면 할 수 있을거야. 이게 약간 불편하긴 하네. 처음 컨테이너 생성할 때만 매핑이 되고, 나중에 매핑 수정하는 거 안됨.
    • 컨테이너 망가지면? 지우고 다시 만들면 됨. 도커파일이나 컴포즈 파일에 초기 세팅 다 저장할 수 있잖아. 다시 만드는 거 어렵지 않음.
    • GUI는 아직 안해봤지만 기본적으로 도커 데스크탑에서 약간의 GUI를 제공하니까 일단 내 수준에서는 만족함.
    • 똑같이 가상머신을 만들어도 용량을 더 절약할 수 있음. 설정을 어떻게 넣느냐에 따라 다이어트가 되더라.

도커가 뭔데 그러세요

도커는 기본적으로 가상환경임. 아까 불평하던 가상머신과는 뭐가 다르냐 하면, 가상머신은 머신 하나하나가 자원을 새로 받아서 쓰지만 도커는 공유할 수 있는 건(커널) 공유함. 그러니까 자원이 적게 들지.

도커는 컨테이너라는 단위로 운영됨. 이 컨테이너 하나하나가 가상환경이라고 보면 됨. 파일도 들어가고, OS도 들어가고, 시스템 설정이나 라이브러리까지 다 들어감. 그리고 제일 편한 점, 이게 공유가 됨.

나의 도커에 대한 미진한 이해를 스스로 알기 때문에 간략하게 끝내자.

항목가상머신도커
격리 방식각 머신마다 커널 따로 쓰기커널은 같이 쓰고, 환경만 분리하기
크기최소 GB 단위MB 단위
실행 시간분 단위초 단위
동시 실행 가능한 양서너개면 이미 많음수십 개 돌려도 됨
(상용 서버컴 사양이면 수백 개도 돌림)
환경 재현성이미지로 찍어도 되긴 하지만 무겁고,
이미지를 안찍어내면 매번 손수 설정해야 함
도커파일에 써놓으면 되고, 필요하면 컴포즈도 쓰면 됨
이식성로컬 환경도 많이 탐.
맥은 가상머신 프로그램 설치 자체가 벽이더라.
도커만 깔리면 어떻게든 씀

도커 하려면 이건 알아야 함

단어만 좀 알고 가자.

  • 이미지: 컨테이너를 생성하는 기본 세팅. 읽기 전용 템플릿이고, 이 템플릿으로 컨테이너를 만들면 손수 이것저것 설정할 거 없이 딸깍하면 됨.
  • 컨테이너: 내가 실제로 돌리는 가상환경의 기본 단위. 이미지로 생성한 인스턴스임.
  • 도커 허브: 깃허브에 코드 올리는 것처럼 도커 허브에 이미지를 올림. 도커 공식이 배포한 것도 있고, 검증된 퍼블리셔가 올린 것도 있고, 일반 사용자가 올린 것도 있음. 알아서 잘 골라서 쓰기.

오늘의 목표가 뭐죠

  1. 내 윈도우 로컬에는 WSL과 도커만 설치한다.
  2. 블로그를 작성하는 레포지토리 파일은 내 로컬에 있고, 거기서 수정한다.
  3. Ruby 등의 환경 구성과 빌드는 도커가 한다.
  4. 내 로컬에서 켜보면 빌드된 블로그가 확인된다.
  5. 로컬 파일을 수정하면 빌드된 사이트에도 반영된다.
  6. 이 컨테이너는 나중에도 재활용한다.

일단 성공한 방법을 먼저 보여줄게

  1. 로컬 폴더를 마운트한 Ruby 컨테이너를 만든다. 이 스크립트는 레포지토리가 있는 위치에서 실행한다. ls 치면 _posts나 다른 config 파일들이 나오는 그 위치.

    1
    2
    3
    4
    5
    6
    
    docker run -it `
       --name chirpy-manual `
       --volume "${PWD}:/app" `
       -p 4000:4000 -p 35729:35729 `
       ruby:3.2 `
       bash
    
  2. 1을 실행하고 나면 실행하던 터미널이 컨테이너의 터미널로 바뀐다. 거기서 다음으로 실행.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    # 작업 경로 이동
    cd /app
    # git 설치
    apt-get update && apt-get install -y git
    
    # 모든 경로 허용하여 git 보안 해제
    # "fatal: detected dubious ownership in repository" 오류 때문에 포함됨
    git config --global --add safe.directory "*"
    
    # 의존성 라이브러리 설치: 이거 Ruby 이미지로 만든 거라 Ruby는 따로 설치 안해도 된다
    gem install bundler
    bundle install
    
  3. 2까지 실행하고 나면 그 다음은 블로그 테마 초기화 및 실행 순서인데, 윈도우와 컨테이너 OS 간의 차이로 약간의 문제가 있어서 개행 문자 관련 처리가 들어간다. 5번을 진행했는데 tools/init: line 4: $'\r': command not found과 같은 오류 메시지가 나오면 이걸 하면 된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # 개행 문자 변환 및 설정
    sed -i 's/\r$//' tools/init
    
    # 필요하다면 모든 파일에 대해 실행해도 됨
    sed -i 's/\r$//' tools/*
    
    # 윈도우 자체가 개행 문자를 똑바로 쓰도록 설정하면 나중에 이런 문제 또 생길 일이 없음
    # 이건 컨테이너 터미널이 아니라 윈도우 로컬 터미널에서 실행하기
    git config --global core.autocrlf input
    
  4. npm 설치하기. 있을 줄 알았는데 없더라.

    1
    2
    3
    4
    5
    6
    7
    
    # 설치하기
    apt-get update
    apt-get install -y nodejs npm
    
    # 설치 확인
    node -v
    npm -v
    
  5. 이제 진짜 블로그 테마 초기화하고 실행하기

    1
    2
    3
    4
    5
    6
    
    # init 파일 이름은 ls로 확인하고 있는 것으로 쓰기.
    # chirpy 테마는 "init.sh"가 아니라 "init"이라서 이렇게 쓴거임.
    bash tools/init
    
    # 서버 실행
    bundle exec jekyll serve --host 0.0.0.0 --watch --force_polling --livereload
    
  6. 로컬에서 확인하기: localhost:4000/{base_url}. 0.0.0.0:4000이 아님에 주의

  7. 나중에 컨테이너 다시 쓰기: docker start -ai chirpy-manual

Gemini에게 물어볼 때마다 받은 답변이지만 항상 실패했던 그 방법

  • 사용 후 삭제되는 컨테이너

    1
    2
    3
    4
    5
    
    docker run --rm -it `
       --volume="${PWD}:/srv/jekyll" `
       -p 4000:4000 -p 35729:35729 `
       jekyll/jekyll:latest `
       jekyll serve --watch --force_polling --livereload
    
  • 재활용 가능 컨테이너

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    docker run -it `
       --name chirpy-blog `
       --volume="${PWD}:/srv/jekyll" `
       -p 4000:4000 -p 35729:35729 `
       jekyll/jekyll:latest `
       jekyll serve --watch --force_polling --livereload
    
    # 재사용
    docker start -ai chirpy-blog
    

위 두 컨테이너에서 공통적으로 발생하는 문제는 깃허브 보안으로 인한 소유권과 권한 문제. 오류 메시지는 아래와 같이 나오고, 저게 한두번 나오는 게 아니라 빌드하다가 끊어질 때까지 계속 나옴.

1
2
3
4
fatal: detected dubious ownership in repository at '/srv/jekyll'
To add an exception for this directory, call:

   git config --global --add safe.directory /srv/jekyll

이제 저 설정을 포함해서 다시 컨테이너 코드를 쓰면

1
2
3
4
5
6
docker run -it `
  --name chirpy-blog `
  --volume="${PWD}:/srv/jekyll" `
  -p 4000:4000 -p 35729:35729 `
  jekyll/jekyll:latest `
  sh -c "git config --global --add safe.directory /srv/jekyll && jekyll serve --watch --force_polling --livereload"

오류는 똑같이 계속 나옴.

이번엔 safe directory를 넓혀서 전부 다 safe하게 만들면

1
2
3
4
5
6
docker run -it `
  --name chirpy-blog `
  --volume="${PWD}:/srv/jekyll" `
  -p 4000:4000 -p 35729:35729 `
  jekyll/jekyll:latest `
  sh -c "git config --global --add safe.directory '*' && bundle install && bundle exec jekyll serve --watch --force_polling --livereload"

오류는 똑같음.

로컬에서도 똑같이 safe directory를 설정해도 오류는 안사라짐. 그래서 그냥 컨테이너에 환경을 직접 만들어서 설치할 거 다 설치하고 돌렸더니 해결되었다고 한다.

Gemini가 말하길 “공식 Jekyll 이미지는 이미 설정된 환경으로 인해 유연한 대응이 어려울 수 있으나, 기본 Ruby 이미지에서 수동으로 환경을 구축하면 소유권 문제와 빌드 오류를 단계별로 해결할 수 있다”고 함.

이 기사는 저작권자의 CC BY-NC-ND 4.0 라이센스를 따릅니다.

git 브랜치 관리하기

도커 컴포즈 (1)