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

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"]

Short answer
sshd server is not started automatically by default on alpine.
You may use an other node image to run your application like node:latest
https://hub.docker.com/_/node
based on debian, equivalent version alternative to node:alpine
Try to avoid ssh in a docker container, you may use a script as entrypoint to configure your container at runtime
Documentation : https://docs.docker.com/engine/reference/builder/#entrypoint
Best practices with example of script : https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#entrypoint
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 <daniel.guerra69#gmail.com>
# 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"]

Related

React app is not loading from docker image in local

My Docker file
# FROM node:16.14.2
FROM node:alpine
ENV NODE_ENV=production
WORKDIR /app
COPY ["package.json", "package-lock.json", "./"]
RUN npm install
COPY . .
CMD [ "npm", "start"]
Command to run image: docker run -it -d -p 4001:4001 react-app:test2
Project structure
project structure
Output after docker run
result after docker run
Based on this context, a possible mistake for me is basically that you do not copy the rest of the source code correctly.
Try to be more consistent in the Dockerfile, also have a look at the multistage Docker build (within the same file) to optimise the image.
Anyway, your file should be something like:
FROM node:16-alpine
ENV NODE_ENV=production
WORKDIR /app
COPY ["package.json", "package-lock.json", "./"]
RUN npm install
COPY . ./
CMD [ "npm", "start"]
Based on the code in the repo, I managed to spot the following problem.It's neither the Dockerfile, nor the code itslef. It throws some warnings though.
Implicitly, the application is supposed to be running on port 3000, if it is not chnaged manually at some point (in this project there are only default settings). Thus the application starts correclty on port 3000, However you expose 4001:4001. On this port nothing is running according to this Dockerfile.
Try using port 3000 instead and it should work just fine:
docker run -it -d -p 3000:3000 <image-name>:<image-tag>

Angular dockerize is not running on local port?

i have an angular app that i am trying to make it dockerize so with the below Dockerfile it is building an image , how do i run this app now locally for the port that i exposed 4200 i am new to docker stuff any help will be appreciated this will be without nginx.
Dockerfile
# --------------------------------------------------------------------------
FROM node:14 as builder
COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm install --production
# --------------------------------------------------------------------------
FROM gcr.io/distroless/nodejs:14
USER 9000:9000
# create the base directory
WORKDIR /apps/nodejs/gcp/
ENV HOME=/apps/nodejs/gcp/
# set the home directory
COPY --from=builder node_modules ./node_modules
COPY package.json ./
# copy readme.md
COPY README.md ./
# copy the dist to the home dir
COPY dist ./dist
# DO NOT COPY THE CERTS AND CONFIG FOLDER IN THIS IMAGE. THESE WILL BE INJECTED BY KUBERNETES.
# IN ORDER TO RUN THIS IMAGE IN LOCAL MOUNT THE HOST NODECERT AND CONFIG FOLDER TO THE DOCKER
# docker run -p 9082:9082 --rm \
#--env "NO_UPDATE_NOTIFIER=true NODE_ENV=production PORT=9082 \
#LOGCONSOLE=true CONFIGBASEPATH=/apps/nodejs/gcp/config/ CERTSBASEPATH=/apps/nodejs/gcp/nodecerts" \
#-v /apps/nodejs/gcp/nodecerts:/apps/nodejs/gcp/nodecerts -v /apps/nodejs/gcp/config/:/apps/nodejs/gcp/config/ <image name>
# TO GO INSIDE THE RUNNING CONTAINER
# docker container exec -it <container id> sh
#BUILDING Docker
# docker build -t <image name> .
# <image name>: all lowercase and if needed separated by hypen(-). eg redis-service
# port the server will be listening to.
EXPOSE 4200
CMD ng serve --host 0.0.0.0 --port 4200
Generate the build of the application
Use this command:
npm run build
Create a Dockerfile inside the build output folder and add this code in Dockerfile:
FROM nginx:latest
MAINTAINER yournick#winter.com
COPY ./ /usr/share/nginx/html/
EXPOSE 80
Finally build the docker image using this command:
docker build -t angular-dist-project:v1 .
Now run the image using this command:
docker run -d --name angular-app-container -p 2021:80 angular-dist-project:v1
Now go to browser and navigate http://your-ip:2021:
http://localhost:2021
Result: angular app is successfully dockerized
  NOTE: Do not forget and
remember that this only is an alternative, exist anothers many ways!
I hope you understand.
All the best 🌟

NestJS with Docker and Portainer

i'm trying to turn UP my project with a Virtual Private Server. I've installed Docker and Portainer and i can start the project. But its not running in any port. I did set to run in port 3000 but when i put in browser IP_Of_My_VPS:3000 nothing happens. I'm new with docker and every configuration that i did was based on my searchs.
This print shows that image is running in no one port.
This other print shows that my application is running (but i dont know how access it).
My docker config:
FROM node:12-alpine
RUN apk --no-cache add curl
RUN apk --no-cache add git
RUN git --version
WORKDIR /app
COPY package*.json ./
RUN npm set progress=false && npm config set depth 0 && npm cache clean --force
RUN npm ci
COPY . .
RUN npm run build && rm -rf src
HEALTHCHECK --interval=30s --timeout=3s --start-period=30s \
CMD curl -f http://localhost:3000/health || exit 1
EXPOSE 3000
CMD ["node", "./dist/main.js"]
When docker container up, perform port forwarding
for examples,
docker run -p <your_forwarding_port>:3000 ~~~
# docker-compose.yaml
~~~
ports:
- "<your_forwarding_port>:3000"
~~~
you can see ref
: docker-container port
: docker-compose port

Why files/folders are created with different ownership in docker run as root?

Could you explain why this happens?
When I have such Dockerfile:
FROM node:12
WORKDIR /app
CMD ["touch", "somefile"]
I execute:
sudo docker build -t test1 .
sudo docker run -it --mount type=/my_folder,dst=/app test1
I get somefile created by root user.
When I have such Dockerfile:
FROM node:12
WORKDIR /app
CMD ["npm", "install"]
I execute(the same as above):
sudo docker build -t test1 .
sudo docker run -it --mount type=/my_folder,dst=/app test1
I get node_modules created by non-root user
Why do I get different users for created files in both cases? Isn't is supposed to be root user?

NGINX fails at COPY --from=node /app/dist/comp-lib /usr/share/nginx/html,

COPY failed: stat /var/lib/docker/overlay2/1e9a0e53a11b406c13d4fc790336f37285927a1b87d1bac4d0e889c6d3cfed9b/merged/app/dist/comp-lib: no such file or directory
I tried running docker system prune, and restarted Docker a bunch of times. I also gave a shot at rm -rf /var/lib/docker in the docker VM, somehow that doesn't remove the directory.
Node version: v10.15.1
Docker version: 18.09.2, build 6247962
Dockerfile:
# stage-1
FROM node as builder
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build
# stage -2
FROM nginx:alpine
COPY --from=node /app/dist/comp-lib /usr/share/nginx/html
I expect the build to be successful but the above mentioned is the error I'm experiencing.
In your stage 2
COPY --from=node /app/dist/comp-lib /usr/share/nginx/html
should be
COPY --from=builder /app/dist/comp-lib /usr/share/nginx/html
since stage 1 is called builder and not node.
This is the dockerfile that I use for my Angular apps:
FROM johnpapa/angular-cli as angular-built
WORKDIR /usr/src/app
COPY package.json package.json
RUN npm install --silent
COPY . .
RUN ng build --prod
FROM nginx:alpine
LABEL author="Preston Lamb"
COPY --from=angular-built /usr/src/app/dist /usr/share/nginx/html
EXPOSE 80 443
CMD [ "nginx", "-g", "daemon off;" ]
I've never had any issues with this configuration. There's more information as well in this article.

Resources