[node.js] node.js 설치는 nvm으로

node.js 설치를 위해서 nodejs.org의 다운로드에서 다운로드 받아 설치할 수도 있지만(이런 방식을 Node installer라고 한다), nvm을 이용하는 것이 좋다.

nvm은 node version manager의 약자로, node 버전을 필요에 따라 바꿔가며 사용할 수 있다. nvm의 설치는 https://github.com/nvm-sh/nvm#installing-and-updating를 참고하자.

nvm을 설치하고 나면 이 nvm을 통해 node.js의 특정 버전을 설치하면 된다. 현재 기준 LTS인 16을 설치하려면 다음과 같이 한다.

$ nvm install 16

그러면 해당 버전의 node.js와 함께 npm이 설치된다. npm은 node package manager의 약자이다.

최신 LTS 버전을 설치하고 싶을 때는 그냥 다음과 같이 하면 된다.

$ nvm install --lts

최신 npm을 다운로드하고 싶을 때는 npm 그 자체를 이용한다. 다음과 같이 하면 된다.

$ npm install --location=global npm

[Mac] Dock에 앱 관련 아이콘 추가

Launchpad 추가

기본으로 Dock에 Launchpad 아이콘은 추가되어 있다. 없앴을 때 복구하고 싶다면 다음과 같이 한다.

  1. “Finder” 실행
  2. 왼쪽 바의 “응용 프로그램”에서 우클릭 후 “Dock에 추가”

“응용 프로그램” 추가

아래처럼 “응용 프로그램” 전체를 볼 수 있는 아이콘을 추가한다.

  1. “Finder” 실행
  2. 왼쪽 바의 “위치”에서 “XXX의 MacBook Pro” / “Macintosh HD”
  3. “응용 프로그램”을 끌어다 Dock에 갖다 놓기

[Mac] Windows manager Rectangle쓰기

기존에 Windows manager로 Veer를 쓰다가 Rectangle이 더 나은 것 같아 갈아탔다. 설치는 Rectangle 사이트(https://rectangleapp.com/)에서 다운로드 받아 설치하면 된다.

내 Rectangle 설정 (32:9 모니터 기준)
내 Rectangle 설정 (32:9 모니터 기준)

나같은 경우는 아래 절반, 위 절반을 사용하지 않기 때문에 둘 모두 없앴다. 대신 높이 최대화를 Ctrl + Option + 위, 가운데 절반을 Ctrl + Option + 아래로 설정했다.

32:9 울트라 와이드 모니터의 경우 Ctrl + Option + D, F, G가 유용할 것 같다. Ctrl + Option + D만 눌러도 1/3씩 토글되면서 움직인다.

왼쪽 위, 오른쪽 위, 왼쪽 아래, 오른쪽 아래도 사용하지 않을 것 같아서 1/4 쪽으로 U, I, J, K도 바꿨다. 역시 Ctrl + Option + U만 눌러도 1/4씩 토글되면서 움직인다.

창 복원은 항상 Ctrl + Option + BackSpace 이다.

[Mac] 초기 마우스/키보드 설정

마우스

마우스 스크롤 방향 바꾸기

  • “시스템 환경설정” / “마우스” / “스크롤 방향: 자연스럽게” 체크 해제

Logitech Options 설치 (Logitech MX Master 2s, MX Vertical, Craft 키보드 사용 시)

키보드

키보드 지연 시간 설정

  1. “시스템 환경 설정” / “키보드” / “키보드”
  2. “키 반복”을 가장 오른쪽 “빠르게”
  3. “반복 지연 시간”을 가장 오른쪽 “짧게”

Karabiner-Element 설치

  1. Karabiner-Element 사이트에서 다운로드 받아 설치
  2. “시스템 환경 설정” / “보안 및 개인 정보 보호” / “개인 정보 보호” / “입력 모니터링”에 karabiner_grabber와 karabiner_observer 둘 모두 체크

Caps Lock으로 한영 전환 시 지연 없애기

  1. “Karabiner Element Preferences” / “Simple Modifications” / “For all devices” 에서 “Add Item”, 왼쪽 “—-” 를 누른 후, “Modifier keys” / “caps_lock”, 오른쪽 “—-” 를 누른 후, “To key”에 “Function keys” / “f19”
  2. “시스템 환경 설정” / “키보드” / “단축키” / “입력 소스”에서 “입력 메뉴에서 다음 소스 선택”의 오른쪽에 있는 단축키를 선택하고 Caps Lock 키를 눌러 “F19″로 설정.

외부 키보드 사용 시 Command 키와 Option 키 바꾸기

  1. “Karabiner Element Preferences” / “Simple Modifications” 에서 외부 키보드, 예를 들면 “REALFORCE_1 (Topre Coperation)” 을 선택
  2. “From key”에 “Modifier keys” / “left_option”, “To key”에 “Modifier keys” / “left_command”
  3. “From key”에 “Modifier keys” / “left_command”, “To key”에 “Modifier keys” / “left_option”

외부 키보드 사용 시 오른쪽 Alt(Option)키를 한영 전환키로 바꾸기

  1. “Karabiner Element Preferences” / “Simple Modifications” 에서 외부 키보드, 예를 들면 “REALFORCE_1 (Topre Coperation)” 을 선택
  2. “From key”에 “Modifier keys” / “right_option”, “To key”에 “Function keys” / “f19”

외부 키보드에 한영키가 있는 경우

  1. “Karabiner Element Preferences” / “Simple Modifications” 에서 외부 키보드, 예를 들면 “REALFORCE_1 (Topre Coperation)” 을 선택
  2. “From key”에 “International keys” / “lang1”, “To key”에 “Function keys” / “f19”

PC-Style Home / End 키 동작

  1. “Karabiner Element Preferences” / “Complex Modifications” / “Add rule”을 선택
  2. “Import more rules from the Internet (Open a web browser)”
  3. “pc style Shortcuts”를 입력
  4. “PC-Style Shortcuts”의 오른쪽 “Import” 버튼을 누른 후 “Import”
  5. 추가된 “PC-Style Shortcuts”의 rule 중 “Home key to the beginning of the line (Control + a)” 옆 “+ Enable”
  6. 추가된 “PC-Style Shortcuts”의 rule 중 “End key to the end of the line (Control + e)” 옆 “+ Enable”
  7. 추가된 “PC-Style Shortcuts”의 rule 중 “Home key to the beginning of the sentence (Command + Left). Doesnt work in terminal” 옆 “+ Enable”
  8. 추가된 “PC-Style Shortcuts”의 rule 중 “End key to the end of the sentence (Command + Right). Doesnt work in terminal” 옆 “+ Enable”
  9. 추가된 “PC-Style Shortcuts”의 rule 중 “PC-Style Home/End” 옆 “+ Enable”
  10. 위의 Enable 순서가 바뀌지 않도록 한다.

[Excel] timestamp를 날짜/시간으로 바꾸는 방법

열을 하나 더 만들어서 아래 수식을 입력한다. 아래에서 A2가 13자리 timestamp가 적힌 셀이다.

=A2/86400000+DATE(1970,1,1)

셀 서식에서 날짜나 시간으로 바꾼다. 날짜와 시간이 모두 필요한 경우 “사용자 지정”의 “종류”에 다음을 적는다.

yyyy.m.d h:mm:ss

timestamp가 11자리인 경우 86400000 대신 864000을, 16자리인 경우 86400000000을 쓴다.

[Mythril] myth analyze 시 import 에러

Mythril은 ConsenSys의 smart contract의 보함 결함을 점검해주는 툴이다. analyze를 통해 분석을 하려고 할 때 openzeppelin 등을 사용한 컨트랙트의 경우 solc의 import 에러를 겪을 수 있다.

$ myth analyze contracts/dasomoli.sol 
mythril.interfaces.cli [ERROR]: Solc experienced a fatal error.

ParserError: Source "@openzeppelin/contracts/token/ERC20/IERC20.sol" not found: File not found. Searched the following locations: "".
 --> contracts/dasomoli.sol:6:1:
  |
6 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

solc를 command line에서 사용할 때는 아래와 같이 remap을 해주면 된다.

solc @openzeppelin/=$(pwd)/node_modules/@openzeppelin/ contracts/dasomoli.sol
Compiler run successful, no output requested.

myth 사용 시에는 이를 json 파일을 만들어 --solc-json 옵션을 통해 줄 수 있다.

  • solc.json
{
   "remappings": [ "@openzeppelin/=/Users/dasomoli/src/smartcontract/node_modules/@openzeppelin/" ]
}
$ myth analyze --solc-json solc.json contracts/dasomoli.sol 
The analysis was completed successfully. No issues were detected.

참고

[Docker] docker in docker의 Permission denied 문제

도커 컨테이너 안에서 도커를 사용하는 방법은 Host의 /var/run/docker.sock를 컨테이너에서 bind mount하면 된다. 쉽게 설명해 docker run 할 때 아래처럼 -v /var/run/docker.sock:/var/run/docker.sock 옵션을 주면 된다는 뜻이다. 물론 컨테이너 안에는 도커가 설치되어 있어야 한다.

docker run -it --name ubuntu -v /var/run/docker.sock:/var/run/docker.sock ubuntu:20.04

이렇게 하면 도커 컨테이너 안에서 /var/run/docker.sock의 소유자가 root:docker 로 생기는데 이때의 그룹 id는 호스트의 그룹 id 값을 따르게 된다. 내 맥에서는 docker 그룹의 gid가 134이고, ubuntu 컨테이너의 docker 그룹의 gid는 1000이다.

$ cat /etc/group | grep docker # Host에서..
docker:x:134:dasomoli

컨테이너 안에서 /var/run/docker.sock를 살펴보면 아래처럼 소유자가 root:134 이다.

root@ce1351052f58:/# ls -l /var/run/docker.sock
srw-rw---- 1 root 134 0 Dec 21 13:19 /var/run/docker.sock

그러나 컨테이너 내에서 도커 설치 후 docker 그룹의 gid는 호스트의 gid인 134가 아닌 컨테이너 내부 환경에서 주어진다. 아래에서는 999이다.

root@ce1351052f58:/# cat /etc/group | grep docker
docker:x:999:

따라서 컨테이너 내부에서 root가 아닌 일반 유저로 도커를 사용하려고 하면 아래처럼 Permission denied 에러가 발생하게 된다.

$ id
uid=1000(dasomoli) gid=1000(dasomoli) groups=1000(dasomoli)

$ docker ps -a
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json?all=1": dial unix /var/run/docker.sock: connect: permission denied

이 문제의 해결 방법으로 사람들이 이야기하는 방법은 chown으로 컨테이너 내부에서 owner를 root:docker 로 바꾸고 사용하는 방법, 또는 chmod로 아예 a+rw 를 주는 방법을 이야기하는데, chown으로 owner를 바꾸면 컨테이너 외부의 호스트 파일의 소유자 정보도 바뀌는 문제가 있다. 위의 docker의 gid가 컨테이너에서는 999, 호스트에서는 134인 경우에 컨테이너에서 chown root:docker를 해보면 호스트에서 gid가 999인 그룹에 속한 파일로 나온다. 즉, 호스트의 도커 실행 환경에 문제가 생긴다.

$ ls -l /var/run/docker.sock
srw-rw---- 1 root systemd-coredump 0 12월 21 22:19 /var/run/docker.sock # docker가 아니고 systemd-coredump 그룹 소유로 바뀌었다!!

$ cat /etc/group | grep systemd-coredump
systemd-coredump:x:999:

따라서 이 방법보다는 둘 모두의 docker 그룹의 gid를 맞춰주는 방법이 더 낫다. 컨테이너 안에서 groupmod로 다음을 실행한다. 아래에서 134는 호스트에서의 docker 그룹의 gid이다.

root@ce1351052f58:/# groupmod -g 134 docker

root@ce1351052f58:/# chown root:docker /var/run/docker.sock # 컨테이너가 실행 중이었다면 owner를 바꾼다.

root@ce1351052f58:/# ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 Dec 21 22:19 /var/run/docker.sock

호스트에서도 확인해보자.

$ ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 12월 21 22:19 /var/run/docker.sock

도커 이미지를 빌드할 때 Dockerfile 내에서 아예 먼저 해준다면, 실행 시에 따로 해주지 않아도 된다.

# Dockerfile 안의 내용
ARG HOST_DOCKER_GID="134"

RUN groupmod -g ${HOST_DOCKER_GID} docker

위의 Dockerfile로 도커 이미지를 빌드할 때는 다음과 같은 방식으로 넘겨도 된다.

$ docker build --build-arg HOST_DOCKER_GID=$(stat -c "%g" /var/run/docker.sock) -t ubuntu20.04

위에서 사용한 호스트에서 docker 그룹의 gid를 얻는 방법은 “[Linux/Mac] group id 얻기” 글을 참조한다. 호스트와 컨테이너 둘 간의 gid 충돌은 유의하자.

[Linux/Mac] group id 얻기

그룹 이름으로부터 GID 얻기

$ getent group <GROUP_NAME> | cut -d: -f3

예를 들어, docker 그룹의 gid를 얻고 싶다면

$ getent group docker | cut -d: -f3

파일의 소유 그룹의 GID 얻기

어느 파일의 소유 그룹의 gid를 얻고 싶다면.

$ stat -c "%g" <FILE_NAME>

예를 들어, /var/run/docker.sock의 소유자가 root:docker일 때 docker의 gid를 얻고 싶다면

$ stat -c "%g" /var/run/docker.sock