• Docker ubuntu의 npm install 명령에서 심볼릭링크(symlink) 관련 오류

    2022. 2. 2.

    by. 안녕진

    개인 공부 목적으로, 정확하지 않은 정보가 있을 수 있습니다.
    해결 방법만 궁금하신 분은 하단에서 확인해주시기 바랍니다.

    상황

    docker --volume 옵션으로 (호스트컴퓨터폴더) 와 우분투의 /root/workspace 디렉토리를 연결해놓은 상태이다.
    npm install --save express 명령으로 express를 설치하려는데, 아래와 같은 오류 메시지가 나타났다.

    root:~/workspace/info-cnu# npm install --save express
    npm ERR! code EPERM
    npm ERR! syscall symlink
    npm ERR! path ../mime/cli.js
    npm ERR! dest /root/workspace/info-cnu/node_modules/.bin/mime
    npm ERR! errno -1
    npm ERR! Error: EPERM: operation not permitted, symlink '../mime/cli.js' -> '/root/workspace/info-cnu/node_modules/.bin/mime'
    npm ERR!  [Error: EPERM: operation not permitted, symlink '../mime/cli.js' -> '/root/workspace/info-cnu/node_modules/.bin/mime'] {
    npm ERR!   errno: -1,
    npm ERR!   code: 'EPERM',
    npm ERR!   syscall: 'symlink',
    npm ERR!   path: '../mime/cli.js',
    npm ERR!   dest: '/root/workspace/info-cnu/node_modules/.bin/mime'
    npm ERR! }
    npm ERR! 
    npm ERR! The operation was rejected by your operating system.
    npm ERR! It is likely you do not have the permissions to access this file as the current user
    npm ERR! 
    npm ERR! If you believe this might be a permissions issue, please double-check the
    npm ERR! permissions of the file and its containing directories, or try running
    npm ERR! the command again as root/Administrator.
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /root/.npm/_logs/2022-02-02T08_32_45_468Z-debug.log

    문제 이해

    검색

    에러 로그를 읽어보면, symlink라는 것에서 뭔가 권한에 관련한 오류가 발생한 것으로 보인다.
    npm symlink error 라는 키워드로 구글링해보니, stack overflow 에서 --no-bin-links 옵션을 추가하여 해결하라는 글을 찾을 수 있었다. 나도 해결했다.
    그럼 --no-bin-links의 역할이 무엇이고 왜 문제가 생긴걸까?

    --no-bin-links

    --no-bin-links가 어떤 옵션인지 알아보기 위해, npm docs 에서 --no-bin-links 키워드를 찾아봤는데, --no-bin-links라는 옵션은 없고 --bin-links만 있었다.
    앞의 no라는 단어는 뒤의 옵션을 false값으로 만들어주는 단어인 것 같다.
    내 생각이 맞는지 확인해보기 위해 npm install --save --bin-links false express를 실행해보니 정상적으로 작동했다.
    그럼 bin-links의 값을 false로 설정하면 해결된다는 것인데, bin-links는 뭘까

    bin-links

    npm docs의 bin-links 관련 설명이다.

    bin-links
    Default: true
    Type: Boolean
    Tells npm to create symlinks (or .cmd shims on Windows) for package executables.
    Set to false to have it not do this. This can be used to work around the fact that some file systems don't support symlinks, even on ostensibly Unix systems.

    실행파일에 대한 심볼릭 링크를 생성하도록 하는 옵션이라는데, 기본값이 True이다.
    심볼릭 링크(sym link)를 지원하지 않는 시스템에서 false옵션이 사용될 수 있다고 한다.
    심볼릭 링크는 뭐지?

    심볼릭 링크

    우리가 흔히 사용하는 바로가기와 비슷한 역할이라고 한다.
    아래에서 화살표(->)로 표현된 것들이 심볼릭 링크이다.

    root:/# ls -al
    total 68
    drwxr-xr-x   1 root root 4096 Feb  2 08:11 .
    drwxr-xr-x   1 root root 4096 Feb  2 08:11 ..
    -rwxr-xr-x   1 root root    0 Feb  2 08:11 .dockerenv
    lrwxrwxrwx   1 root root    7 Jan  5 16:47 bin -> usr/bin
    drwxr-xr-x   2 root root 4096 Apr 15  2020 boot
    drwxr-xr-x   5 root root  360 Feb  2 08:11 dev
    drwxr-xr-x   1 root root 4096 Feb  2 08:17 etc
    drwxr-xr-x   2 root root 4096 Apr 15  2020 home
    lrwxrwxrwx   1 root root    7 Jan  5 16:47 lib -> usr/lib
    lrwxrwxrwx   1 root root    9 Jan  5 16:47 lib32 -> usr/lib32
    lrwxrwxrwx   1 root root    9 Jan  5 16:47 lib64 -> usr/lib64
    lrwxrwxrwx   1 root root   10 Jan  5 16:47 libx32 -> usr/libx32
    drwxr-xr-x   2 root root 4096 Jan  5 16:47 media
    drwxr-xr-x   2 root root 4096 Jan  5 16:47 mnt
    drwxr-xr-x   2 root root 4096 Jan  5 16:47 opt
    dr-xr-xr-x 259 root root    0 Feb  2 08:11 proc
    drwx------   1 root root 4096 Feb  2 08:32 root
    drwxr-xr-x   5 root root 4096 Jan  5 16:50 run
    lrwxrwxrwx   1 root root    8 Jan  5 16:47 sbin -> usr/sbin
    drwxr-xr-x   2 root root 4096 Jan  5 16:47 srv
    dr-xr-xr-x  11 root root    0 Feb  2 08:11 sys
    drwxrwxrwt   1 root root 4096 Feb  2 08:18 tmp
    drwxr-xr-x   1 root root 4096 Jan  5 16:47 usr
    drwxr-xr-x   1 root root 4096 Jan  5 16:50 var

    뭔가 권한오류라니까 docker --volume 옵션으로 내 실제 PC와 디렉토리를 연결해둔 것이 문제가 된 것 같다는 생각이 들었다.
    오류 로그를 한 줄 뜯어서 보자.

    npm ERR! Error: EPERM: operation not permitted, symlink '../mime/cli.js' -> '/root/workspace/info-cnu/node_modules/.bin/mime'

    /root/workspace/~ 디렉토리를 생각해보면, 내가 docker run --volume 옵션으로 실제PC폴더와 연결한 /root/workspace 디렉토리 아래에 위치한다.
    따라서 내 실제PC폴더에도 반영되어야 하기 때문에, 권한과 관련된 문제가 발생한 것이라고 생각된다.

    내 생각을 확인해보기 위해, 내 PC폴더에 영향을 주지않는 /root/test 디렉토리에서 실험을 해봤다.

    root@3664cc3615dd:~/test# ls
    package.json
    root@3664cc3615dd:~/test# npm install --save express
    
    added 50 packages, and audited 51 packages in 1s
    
    2 packages are looking for funding
      run `npm fund` for details
    
    found 0 vulnerabilities

    오류가 없이 실행되는 것을 확인할 수 있다.

    정확히 어떤 권한이 필요해서 문제가 발생하는 것인지는 아직 알아내지 못했다.


    해결

    1. install 시 --no-bin-links 옵션을 추가하면 된다.
    npm install --no-bin-links --save express

    혹은

    npm install --bin-links false --save express
    1. docker run --volume 옵션으로 연결된 디렉토리가 아닌 다른 디렉토리에서 실행한다.

    2번의 경우, 호스트컴퓨터의 폴더에 반영되지 않기 때문에, vscode를 사용해 접근할 수 없었다.
    vi에디터를 사용하기 싫었기 때문에 1번으로 문제를 해결했다.

    댓글