cancel
Showing results for 
Search instead for 
Did you mean: 
cancel

Running NSO in a Docker Container

NetDevOp
Beginner
Beginner

I've been following the instructions to set up NSO in a docker container here:

https://github.com/NSO-developer/nso-docker

 

The image seems to have built correctly but when I try to run it, the container exits almost immediately:

owl@GBNPW0Z2E:/mnt/c/Users/owl$ docker run -itd --name nso-dev1 -v $(pwd):/src cisco-nso-dev:5.3
b7765b9a7baf6331d85a2fa7586bf7a5095c86ee293b3fd6f9b4b2b565c808ce
owl@GBNPW0Z2E:/mnt/c/Users/owl$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
owl@GBNPW0Z2E:/mnt/c/Users/owl$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
b7765b9a7baf        cisco-nso-dev:5.3   "/enter-shell.sh"   8 seconds ago       Exited (1) 7 seconds ago                       nso-dev1
owl@GBNPW0Z2E:/mnt/c/Users/owl$ docker logs b7765b9a7baf
standard_init_linux.go:211: exec user process caused "no such file or directory"

I've tried changing the eol characters in the Dockerfile from CRLF to LF but no luck.

1 ACCEPTED SOLUTION

Accepted Solutions

alexstev
Cisco Employee
Cisco Employee

Hi CLI_Owl,

 

Cool name! So, I'm not a Docker expert but I have built and run containers from images. I did some searching online and found the following which may be helpful (full disclosure: I found this all on StackOverflow

 

You can try changing the entry point:

ENTRYPOINT ["sh","/run.sh"]
The docs require the first parameter to be the executable:

ENTRYPOINT has two forms:

ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)

ENTRYPOINT command param1 param2 (shell form)


Others have also noted the following possible causes:

- The architecture an image was built for does not match the one of your system. For instance, trying to run an image built for arm64 on a x86_64 machine can generate this error.

- Not actually having the file inside your container. Some people try to run a command from the host without adding it to their image. Some people shadow their command by mounting a volume on top of the command they wanted to run. If you run the same container, but with a shell instead of your normal entrypoint/cmd value, and run an ls /path/to/cmd you'll see if this exists.

- The next cause is running the wrong command. This often appears with json/exec formatting of the command to run that doesn't parse correctly. If you see a command trying to run ["app", or something similar, the json string wasn't parsed by Docker and Linux is trying to use a shell to parse the command as a string. This can also happen if you misorder the args, e.g. trying to run -it is a sign you tried to place flags after the image name when they must be placed before the image name.

- With shell scripts, this error appears if the first line with the #! points to a command that doesn't exist inside the container. For some, this is trying to run bash in an image that only has /bin/sh. And in your case, this can be from Windows linefeeds in the script. Switching to Linux/Unix linefeeds in your editor will correct that.

 

Hope this helps!

View solution in original post

3 REPLIES 3

alexstev
Cisco Employee
Cisco Employee

Hi CLI_Owl,

 

Cool name! So, I'm not a Docker expert but I have built and run containers from images. I did some searching online and found the following which may be helpful (full disclosure: I found this all on StackOverflow

 

You can try changing the entry point:

ENTRYPOINT ["sh","/run.sh"]
The docs require the first parameter to be the executable:

ENTRYPOINT has two forms:

ENTRYPOINT ["executable", "param1", "param2"] (exec form, preferred)

ENTRYPOINT command param1 param2 (shell form)


Others have also noted the following possible causes:

- The architecture an image was built for does not match the one of your system. For instance, trying to run an image built for arm64 on a x86_64 machine can generate this error.

- Not actually having the file inside your container. Some people try to run a command from the host without adding it to their image. Some people shadow their command by mounting a volume on top of the command they wanted to run. If you run the same container, but with a shell instead of your normal entrypoint/cmd value, and run an ls /path/to/cmd you'll see if this exists.

- The next cause is running the wrong command. This often appears with json/exec formatting of the command to run that doesn't parse correctly. If you see a command trying to run ["app", or something similar, the json string wasn't parsed by Docker and Linux is trying to use a shell to parse the command as a string. This can also happen if you misorder the args, e.g. trying to run -it is a sign you tried to place flags after the image name when they must be placed before the image name.

- With shell scripts, this error appears if the first line with the #! points to a command that doesn't exist inside the container. For some, this is trying to run bash in an image that only has /bin/sh. And in your case, this can be from Windows linefeeds in the script. Switching to Linux/Unix linefeeds in your editor will correct that.

 

Hope this helps!

Good call, the issue does seem to have something to do with the entrypoint...

 

If I change it from ["enter-shell.sh"] to ["bash"], the image no longer crashes on startup and I can log into the container.

 

I have yet to verify if anything was affected by changing but nso does seem to work.

 

enter-shell.sh is in the home directory once the image starts:

 

 

-rwxrwxrwx 1 root root 637 Feb 5 14:52 enter-shell.sh

 

 

 

This is the content of "enter-shell.sh", looks like it is just supposed to drop the user into a bash prompt:

#!/bin/bash

# magic entrypoint that runs an interactive bash login shell if no arguments are
# given, which means that invoking the container with docker run and no
# arguments will yield a interactive bash login shell. Being a login shell, it
# has read the .profile that contains the necessary includes for setting NSO
# specific paths.
#
# If arguments are provided, it is treated as a command and will again be run by
# a bash login shell, allowing a user to do for example:
#   docker run -it cisco-nso-dev:5.3 ncs-make-package --help
#

if [ $# -eq 0 ]; then
    exec /bin/bash -l
else
    exec bash -lc "$(printf ' %q' "$@")"
fi

The command to start the container is: docker run -itd --name nso-dev1 -v $(pwd):/src cisco-nso-dev:5.3

 

krlarsso
Cisco Employee
Cisco Employee

The cisco-nso-dev image is mean for development. It contains compilers and other tools you need for development. Its entrypoint starts an interactive shell, since that is likely what you want for development. For example, you have mounted in the current directory into /src, so you have the local files available there and can compile things or similar.

 

If you want a running NSO system, you want to use the cisco-nso-base image instead or to be more exact, you want an image that is *based* on cisco-nso-base. It runs the /run-nso.sh script that starts up NSO. It is also a smaller image since the developer tools have been stripped out. To build your own Docker image based on cisco-nso-base, it is recommended to use a repository skeleton, see https://gitlab.com/nso-developer/nso-docker/-/tree/master/skeletons

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: