rewrewty1
rewrewty1

Reputation: 51

Can't connect to SSH from docker container ECONNREFUSED 127.0.0.1:22 - NodeJS

I'm using node-ssh module on nodejs. When I start the connection to ssh it's giving error. Also I'm using WSL Ubuntu 18. I have docker-compose file. I marked PasswordAuthentication as 'yes' on /etc/ssh/sshd_config. I can connect ssh from wsl ubuntu. But when I was trying to connect from my dockerized nodejs project. It's giving error ECONNREFUSED 127.0.0.1:22

On nodejs I'm making a request for user authentication, running some commands, etc.

const Client = require('node-ssh').NodeSSH;
var client   = new Client();   

client.connect({
     host              : 'localhost',
     port              : 22,
     username          : req.body.username,
     password          : req.body.password,
     keepaliveInterval : 30 * 1000, // 30 minutes for idle as milliseconds
     keepaliveCountMax : 1,
}).then(()=>{

     // LOGIN SUCCESS

}).catch((e)=>{

     console.log(e); // ECONFUSED ERROR
     // LOGIN FAILED

});

docker-compose.yml

version: '3.8'

services:
  api:
    build:
      dockerfile: Dockerfile
      context: "./server"
    ports:
      - "3030:3030"
    depends_on:
      - mysql_db
    volumes:
      - /app/node_modules
      - ./server:/app

 ...

And my api's Dockerfile

Dockerfile

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
RUN apk update \
&& apk add openssh-server 
COPY sshd_config /etc/ssh/
EXPOSE 22
CMD ["npm", "run", "start"]

[UPDATE__] [Dockerfile]

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i \
&& apk add --update openssh \
&& rm  -rf /tmp/* /var/cache/apk/*
COPY sshd_config /etc/ssh/
# add entrypoint script
ADD ./docker-entrypoint.sh /usr/local/bin
# make sure we get fresh keys
RUN rm -rf /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key
EXPOSE 22
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["/usr/sbin/sshd","-D"]

[UPDATE__2] [Dockerfile]

FROM node:alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
RUN apk update && \
apk add openssh-client \ 
&& rm -rf /tmp/* /var/cache/apk/*

EXPOSE 22
CMD ["npm", "run", "start"]

[SOLUTION]
I have changed Dockerfile and my nodejs code. I have connected WSL's SSH from docker container after applying as Stefan Golubović suggested host.docker.internal. And used node:latest instead of node:alpine docker image. Thanks to @StefanGolubović and @Etienne Dijon

[FIXED]

const Client = require('node-ssh').NodeSSH;
var client   = new Client();   

client.connect({
     host              : 'host.docker.internal', // It's worked on WSL2
     port              : 22,
     username          : req.body.username,
     password          : req.body.password,
     keepaliveInterval : 30 * 1000, // 30 minutes for idle as milliseconds
     keepaliveCountMax : 1,
}).then(()=>{

     // LOGIN SUCCESS

}).catch((e)=>{

     console.log(e); // ECONFUSED ERROR
     // LOGIN FAILED

});

Dockerfile [FIXED]

FROM node:latest
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
COPY ./ ./
RUN npm i
RUN apt-get update 
EXPOSE 22
CMD ["npm", "run", "start"]

Upvotes: 2

Views: 1657

Answers (1)

Etienne Dijon
Etienne Dijon

Reputation: 1303

Short answer

Test step by step your dockerfile

Something you can do to make sure everything works fine is to run it manually

docker run -it --rm --name testalpine -v $PWD:/app/ node:alpine /bin/sh

Then :

cd /app/
npm i
apk update && apk add openssh-server
# show listening services, openssh is not displayed
netstat -tlpn

As you can see, openssh is not started automatically

Alpine has a wiki about it which needs rc-update :

https://wiki.alpinelinux.org/wiki/Setting_up_a_ssh-server

rc-update is not available in alpine image.

Running sshd server in an alpine container

This image is all about running a ssh server on alpine :

https://github.com/danielguerra69/alpine-sshd

As you can see in Dockerfile, more steps are involved :

Check repository for updated dockerfile

FROM alpine:edge
MAINTAINER Daniel Guerra <[email protected]>

# add openssh and clean
RUN apk add --update openssh \
&& rm  -rf /tmp/* /var/cache/apk/*
# add entrypoint script
ADD docker-entrypoint.sh /usr/local/bin
# make sure we get fresh keys
RUN rm -rf /etc/ssh/ssh_host_rsa_key /etc/ssh/ssh_host_dsa_key

EXPOSE 22
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["/usr/sbin/sshd","-D"]

EDIT: If you need to run commands within your container

You can use docker exec once your container is started:

docker exec -it <container name/id> /bin/sh

documentation here :

https://docs.docker.com/engine/reference/commandline/exec/

  • Updated dockerfile
    FROM node:alpine
    
    WORKDIR /app
    
    COPY ./ ./
    
    RUN npm i
    
    ENTRYPOINT ["npm", "run", "start"]
    

Upvotes: 2

Related Questions