I am new to docker and I just wanted to copy the shellscript inside the container and I wanted to execute the shellscript.
Dockerfile:
FROM amazonlinux
WORKDIR /opt
ADD ./test_Install.sh /opt/test_Install.sh
RUN chmod 777 /opt/test_Install.sh
WORKDIR /
RUN ./test_Install.sh
Build image: docker build -t "testinstallscript:dockerfile" .
When I use the command "docker build -t "testinstallscript:dockerfile" ." I get the following error:
standard_init_linux.go:178: exec user process caused "no such file or
directory"
The command '/opt/test_Install.sh' returned a non-zero code: 1
Can anyone tell me what i am doing wrong here?
You need to change RUN ./test_Install.sh to utilize ENTRYPOINT or CMD. RUN executes commands in a new layer creating new image so use it when setting up your container.
The below command worked:
RUN bash /opt/test_install.sh
Related
I am trying to run a webserver (right now still locally) out of a docker container. I am currently going step by step to understand the different parts.
Dockerfile:
FROM node:12.2.0-alpine as build
ENV environment development
WORKDIR /app
COPY . /app
RUN cd /app/client && yarn && yarn build
RUN cd /app/server && yarn
EXPOSE 5000
CMD ["sh", "-c","NODE_ENV=${environment}", "node", "server/server.js"]
Explanation:
I have the "sh", "-c" part in the CMD command due to the fact that without it I was getting this error:
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:346: starting container process caused "exec:
\"NODE_ENV=${environment}\": executable file not found in $PATH":
unknown.
Building the container:
Building the container works just fine with:
docker build -t auth_example .
It takes a little while since the build context is (even after excluding all the node_modules) roughly 37MB, but that's okay.
Running the container:
Running the container and the app inside works like a charm if I do:
MyZSH: docker run -it -p 5000:5000 auth_example /bin/sh
/app # NODE_ENV=development node server/server.js
However, when running the container via the CMD command like this:
MyZSH: docker run -p 5000:5000 auth_example
Nothing happens, no errors, no nothing. The logs are empty and a docker ps -a reveals that the container was exited right upon start. I did some googling and tried different combinations of -t -i -d but that didn't solve it either.
Can anybody shed some light on this or point me into the right direction?
The problem is you're passing three arguments to sh -c whereas you'd usually pass one (sh -c "... ... ...").
It's likely you don't need the sh -c invocation at all; use /usr/bin/env to alias that environment variable instead (or just directly pass in NODE_ENV instead of environment):
FROM node:12.2.0-alpine as build
ENV environment development
WORKDIR /app
COPY . /app
RUN cd /app/client && yarn && yarn build
RUN cd /app/server && yarn
EXPOSE 5000
CMD /usr/bin/env NODE_ENV=${environment} node server/server.js
Summary
docker run doesn't seem to build a container (but it also doesn't throw an error) despite docker build successfully building the container image.
Input and Output
1. Successful docker image creation..
$ docker build -t minitwitter:latest .
...
Successfully built da191988e0db
Successfully tagged minitwitter:latest
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
minitwitter latest da191988e0db 6 seconds ago 173MB
python 3.7-alpine b11d2a09763f 9 days ago 98.8MB
2. ..and docker run completes without error..
$ docker run --name minitwitter -d -p 8000:5000 --rm minitwitter:latest
e8835f1b4c72c8e1a8736589c74d56ee2d12ec7bcfb4695531759fb1c2cf0e48
3. ..but docker container doesn't seem to exist.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
And navigating to the port where the app should be exposed, http://localhost:8000, returns the connection error ERR_CONNECTION_REFUSED.
Docker file, boot.sh
The Dockerfile and boot.sh files are pretty simple I think:
Dockerfile
FROM python:3.7-alpine
RUN adduser -D minitwitter
WORKDIR /home/minitwitter
COPY requirements.txt requirements.txt
RUN python -m venv env
RUN env/bin/pip install -r requirements.txt
RUN env/bin/pip install gunicorn
COPY app app
COPY migrations migrations
COPY minitwitter.py config.py boot.sh ./
RUN chmod a+x boot.sh
ENV FLASK_APP minitwitter.py
RUN chown -R minitwitter:minitwitter ./
USER minitwitter
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
boot.sh
# BOOTS A DOCKER CONTAINER
#!/bin/sh
source env/bin/activate
flask db upgrade
exec gunicorn -b :5000 --access-logfile - --error-logfile - minitwitter:app
Place the 'shebang' -- #!/bin/sh -- on the first line of the boot.sh shell script.
How I found this answer: This blog post which refers to this Stackoverflow post.
The problem: the original script has a comment on the first line and the shebang on the second line.
Note: The title of the 'Question' is misleading: a docker container was built. The container, however, was short-lived and given I used the -rm option in the docker run command, the container was deleted after it terminated within 2 seconds; this is why it didn't appear in the docker images -a command.
I'm trying to create a Node.js based docker image. For that, I'm looking for options for Parent image. Security is one of the main considerations in the image and we wanted to harden the image by not allowing shell or bash in the container.
Google Distroless does provide this option, but Distroless-NodeJS is in the experimental stage and not recommended for production.
Possible options I could think of are (compromising Distroless feature):
Official Node Image (https://hub.docker.com/_/node/) / Alpine / CentOS based image (but all would have a shell I believe).
With that being said,
Is there any alternative for Distroless?
What are the best options for the parent image for Node.js based docker image?
Any pointers would be helpful.
One option would be to start with a Node image that meets your requirements, then delete anything that you don't want (sh, bash, etc.)
At the extreme end you could add the following to your Dockerfile:
RUN /bin/rm -R /bin/*
Although I am not certain that this wouldn't interfere with the running of node.
On the official Node image (excl Apline) you have /bin/bash, /bin/dash and /bin/sh (a symlink to /bin/dash). Just deleting these 3 flies would be sufficient to prevent shell access.
The Alpine version has a symlink /bin/sh -> /bin/busybox. You could delete this symlink, but it may not run without busybox.
I think you can build an image from scratch which only contains your node application and required dependency, nothing more even no ls or pwd etc.
FROM node as builder
WORKDIR /app
COPY . ./
RUN npm install --prod
FROM astefanutti/scratch-node
COPY --from=builder /app /app
WORKDIR /app
ENTRYPOINT ["node", "bin/www"]
scratch-node
So if someone tries to get the shell,like,
docker run --entrypoint bash -it my_node_scratch
Will get error
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:348: starting container process caused "exec:
\"bash\": executable file not found in $PATH": unknown.
I am referring this from official Node.js docker image.
Create a docker file in your project.
Then build and run docker image:
docker build - t test-nodejs-app
docker run -it --rm --name running-app test-nodejs-app
If you prefer docker compose:
Version: "2"
Services:
node:
image: "node:8"
user: "node"
working_dir: /home/node/app
environment:
- NODE_ENV=production
volumes:
- ./:/home/node/app
expose:
- "8081"
command: "npm start"
Run the compose file:
docker-compose up -d
I am using this docker file to build it
FROM microsoft/dotnet:2.1-sdk-alpine3.7 AS build
WORKDIR /app
COPY Packt.HelloWorld.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o /published
RUN ls -alrth /published
FROM microsoft/dotnet:2.1-runtime-deps-alpine3.7 AS base
WORKDIR /app
COPY --from=build /published .
RUN ls -alrth /app
# ENTRYPOINT ["dotnet", "TestApp.dll"] <-- I can run in Windows like this
ENTRYPOINT ["Packt.HelloWorld"]
The debug ls can show all files under the /app folder
But if I use this
ENTRYPOINT ["/app/Packt.HelloWorld"]
It complained there is no such a path.
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:348: starting container process ca
used "exec: \"/app/Packt.HelloWorld\": stat /app/Packt.HelloWorld: no such file or directory": unknown.
if I use
ENTRYPOINT ["Packt.HelloWorld"]
It gave me
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:348: starting container process caused "exec:
\"Packt.HelloWorld\": executable file not found in $PATH": unknown.
The image seems to build properly and content are also in there, it's just the running not successful.
Can anyone give me a hint what I am missing?
Thanks
# ENTRYPOINT ["dotnet", "TestApp.dll"] <-- I can run in Windows like this
This is pretty much exactly how it should work on Linux as well.
It looks like you are doing Framework Dependent Deployment (no -r or --runtime argument for dotnet publish). So the same steps to build/run on Windows should work on Linux as well.
You need to specify the runtime of the publish subcommand of dotnet-cli. Also, the publishing process must create a self-contained application. Check the link for more information.
I am trying to create a node-js base image by using the following docker file
Dockerfile:
FROM node:0.10-onbuild
# replace this with your application's default port
EXPOSE 8888
I then run the command " sudo docker build -t nodejs-base-image ."
This keeps failing with the error
FATA[0000] The Dockerfile (Dockerfile) must be within the build context (.)
I am running the above command from the same directory where the 'Dockerfile' is located. What might be going on?
I am on Docker version 1.6.2, build 7c8fca2
This was happening because I did not have appropriate permissions to the Dockerfile in question