Why files/folders are created with different ownership in docker run as root? - node.js

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?

Related

Docker compose linux volume - permission acess denied

Below is the Dockerfile for linux images. I get file path access denied error in Ubuntu VM
environment:
- ASPNETCORE_ENVIRONMENT=Production
- ASPNETCORE_Kestrel__Certificates__Default__Password=password123
- ASPNETCORE_Kestrel__Certificates__Default__Path=/abc/https/localhost.pfx
volumes:
- ./devops/https/localhost.pfx:/abc/https/localhost.pfx:ro
The path in the image and dockerfile was the same at that time. Attempted to run on ubuntu. ubuntu user is added to docker group.
Docker file content is provided for reference.
FROM mcr.microsoft.com/dotnet/aspnet:6.0
COPY . App/
WORKDIR /App
ENV ASPNETCORE_ENVIRONMENT="Production"
ENV ASPNETCORE_URLS="https://+:44123;"
ENV ABC_WORKDIR /App
ENV ABC_FILE_STORE /abc/source
EXPOSE 44123
RUN mkdir -p $ABC_FILE_STORE
RUN mkdir -p /abc/https
RUN chown abcuser /abc/https
RUN chown abcuser $ABC_FILE_STORE
RUN chown abcuser /App
USER abcuser
VOLUME /abc/https
VOLUME $ABC_FILE_STORE
WORKDIR $ABC_FILE_STORE
# sanity check: try to write a file
RUN echo "Hello from ABC" > hello.txt
WORKDIR $ABC_WORKDIR
ENTRYPOINT ["dotnet", "ABCService.dll"]
Should all the volume paths used by app, need to be mentioned and change the permission in Dockerfile
Should a docker file need to create a user and use it in dockerfile.
Above seems, both windows and linux need separate dockerfile for image creation

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

Nodejs Serverless Docker Image

I am trying to setup a docker image for my local serverless development and I'm having issues reaching the files using volumes.
Dockerfile
FROM node:8.10
ADD . /code
WORKDIR /code
RUN npm install -g serverless
RUN npm install serverless-offline
EXPOSE 3000
# COPY . /code
CMD ["serverless", "offline", "--host", "0.0.0.0", "--port", "5000"]
docker-compose-yml
version: "3"
services:
serverless_proj_1:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:5000"
volumes:
- .:/code
- /code/node_modules
Docker is listening to all my serverless endpoints correctly:
But when i'm triggering one of the api endpoints from Postman this is the error I'm getting:
docker container exec apps-services_serverless_proj_1_1
pwd returns /code
docker container exec apps-services_serverless_proj_1_1 ls -al returns my codebase
docker container exec apps-services_serverless_proj_1_1 ls /code -al again returns my codebase(both commands have same total)
docker container exec apps-services_serverless_proj_1_1 ls /code/node_modules -al returns all my dependencies(total 3074)
I don't see an RUN npm install. since you are marking a place holder for the node_modules you will need to install them inside the container.
EDIT
Please try attaching to your running docker container and looking in the node_modules folder. Just to double check that a) you have one, b) it is located where it should be and c) it contains all the modules you expect.
You can do this by running docker container exec -it serverless_proj_1 /bin/bash this should put you in the /code dir by default, then just run ls -al

Can not connect to node app running in Docker container from browser

I am running a nodejs application in a Docker container. The application is hosted on a bluehost centOS VPS to which I connect using SSH. I use the following command to run the app in the container: sudo docker run -p 80:8080 -d skepticalbonobo/dandakou-nodeapp. Then I check that the container is running using sudo docker ps and sure enough it is. But when I try to access the app from Chrome using the domain name or IP address I get: "This site can’t be reached". I have noticed however that in the output of sudo docker ps, under COMMAND I get docker-entrypoint... as opposed to node app.js and I do not know how to fix it.You can pull the container using docker pull skepticalbonobo/dandakou-nodeapp. Here is the content of my Dockerfile:
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
USER node
RUN npm install
COPY . .
USER root
RUN chown -R node:node . .
EXPOSE 8080
CMD [ "node", "app.js" ]
Thank you!
The default for Nodejs app is 3000.
Run following command and check on which port node app is running
sudo docker run -ti skepticalbonobo/dandakou-nodeapp /bin/sh
Expose in Dockerfile is just for documentation purpose.

Docker - Permission denied while trying to access folder created in Dockerfile

I have problem with my Dockerfile (code below)
FROM node:4.2.6
MAINTAINER kamil
RUN useradd -ms /bin/bash node
RUN mkdir -p /home/node/app && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY /myFolder .
USER node
COPY --chown=node:node . .
RUN ["chmod", "777", "/home/node/app"]
ENTRYPOINT /home/node/app
CMD ["node myApp.js"]
I'm building docker image with
"docker build -t my_docker_image ."
and it finished with no errors.
Next I am running it with command "docker run --name my_run_docker_image -d my_docker_image" and its also finished without errors, but when I want to check status of my new container with "docker ps -l" command i'm getting info that status of my container is "EXITED".
Hence i'm trying to run it once again with command "docker start -a my_run_docker_image" but I'm receiving error:
"node MyApp.js: 1: node myApp.js: /home/node/app: Permission denied"
I was trying to run it with root user, without specified user but every time I have the same issue.
It looks like you may have a problem with your user add command.
Change
RUN useradd -ms /bin/bash/node
to
RUN useradd -ms /bin/bash node
And also
RUN mkdir -p /home/node/app && -R node:node /home/node/app
Needs to change to
RUN mkdir -p /home/node/app && chown -R node:node /home/node/app
The ENTRYPOINT and CMD tell Docker what command to run when you start the container. Since ENTRYPOINT is a bare string, it’s wrapped in a shell, and CMD is ignored. So when you start your container, the main container process is
/bin/sh -c '/home/node/app'
Which fails, because that is a directory.
In this Dockerfile, broadly, I’d suggest two things. The first is to install your application as root but then run it as non-root, as protection against accidentally overwriting the application code. The second is to prefer CMD to ENTRYPOINT in most cases, unless you’re clear on how they interact. You might come up with something more like:
FROM node:4.2.6
MAINTAINER kamil
WORKDIR /app # Docker will create on first use
COPY myFolder .
RUN useradd node # its shell should never matter
USER node
CMD ["node", "myApp.js"]

Resources