anyway to setup npm credentials over `npm login` without reading input from STDIN?

I’m trying to automate npm publish inside a docker container but I got trouble when $npm login command tries to read username and email from prompts:

npm login << EOF
username
password
email
EOF

it works in terminal bash but not in container without STDIN open and show the following error message:

  • How to add variable to docker daemon in CentOS?
  • Run dockerd as with non-default group in centos6 as a service?
  • How can I mount a volume among remote Docker Machines?
  • Why does the new built image does not have the new installed package?
  • How can JVMs running inside Bluemix container groups be monitored?
  • Mounting local directory into Docker container path that is not exposed as a VOLUME
  • Username: Password: npm ERR! cb() never called!
    npm ERR! not ok code 0
    

    According to npm-adduser:

    The username, password, and email are read in from prompts.

    So how can I run npm login without STDIN open?

  • Docker Cache BUNDLE INSTALL not working
  • Which Official Docker Image(s) should I use for running an application with multiple dependencies?
  • Kibana docker run
  • With Docker, which directories are impacted by disk I/O
  • Default elasticsearch configuration for docker container
  • How To run from host machine bash script inside docker container and remain in bash in container [duplicate]
  • 4 Solutions collect form web for “anyway to setup npm credentials over `npm login` without reading input from STDIN?”

    TL;DR: Make an HTTP request directly to the registry:

    TOKEN=$(curl -s \
      -H "Accept: application/json" \
      -H "Content-Type:application/json" \
      -X PUT --data '{"name": "username_here", "password": "password_here"}' \
      http://your_registry/-/user/org.couchdb.user:username_here 2>&1 | grep -Po \
      '(?<="token": ")[^"]*')
    
    npm set registry "http://your_registry"
    npm set //your_registry/:_authToken $TOKEN
    

    Rationale

    Behind the scenes npm adduser makes an HTTP request to the registry. Instead of forcing adduser to behave the way you want, you could make the request directly to the registry without going through the cli and then set the auth token with npm set.

    The source code suggests that you could make a PUT request to http://your_registry/-/user/org.couchdb.user:your-username with the following payload

    {
      name: username,
      password: password
    }
    

    and that would create a new user in the registry.

    Many thanks to @shawnzhu for having found a more cleaner approach to solve the problem.

    An expect script worked for me. You need to make sure expect is installed, this command should do it for ubuntu:

    apt-get install expect-dev
    

    Your script could look something like this (npm_login_expect):

    #!/usr/bin/expect -f
    
    # set our args into variables
    set i 0; foreach n $argv {set "p[incr i]" $n}
    
    set timeout 60
    #npm login command, add whatever command-line args are necessary
    spawn npm login
    match_max 100000
    
    expect "Username"    
    send "$p1\r"
    
    expect "Password"
    send "$p2\r" 
    
    expect "Email"
    send "$p3\r"
    
    expect {
       timeout      exit 1
       eof
    }
    

    And then call it like this:

    expect -f npm_login_expect myuser mypassword "myuser@domain.com"
    

    You could use an expect script instead or write a node script that uses pty.js.

    For the solution 2 exposed by ke_wa in this duplicated post has worked.

    Mashup:

    export NPM_USERNAME=mUs34
    export NPM_PASSWORD=mypassW0rD
    export NPM_EMAIL=user@domain.com
    npm adduser<<!
    $NPM_USERNAME
    $NPM_PASSWORD
    $NPM_EMAIL
    !
    
    Docker will be the best open platform for developers and sysadmins to build, ship, and run distributed applications.