I am new to Docker and I do have some problems.
My goal:
Here is my setup:
Dockerfile
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --global gulp-cli
RUN npm install
COPY . .
EXPOSE 3000
CMD ["gulp --version" , "gulp"] or? [gulp --version , gulp]
package.json
{
"name": "docker-test",
"version": "1.0.0",
"description": "Testing Docker",
"main": "index.js",
"scripts": {
"test": "test"
},
"author": "",
"license": "",
"devDependencies": {
"gulp": "^4.0.0"
}
}
gulpfile.js
function defaultTask(cb) {
console.log("Default task for gulp 4.0 for docker")
cb();
}
exports.default = defaultTask
docker-compose.yml (I don't think we need this for my question but I will post it anyway since I am not exactly sure If this could make some problems)
version: '3'
services:
html:
container_name: gulp-docker-test
restart: always
build: .
ports:
- '80:3000'
My problems right now:
First of all I am really confused about the workflow of docker. Do I understand it correctly if I run:
docker build . --tag gulp-docker-test
I will create a new docker-container on my computer with the content of the dockerfile? If I need to update anything inside it I have to run it again so the container is updated?
If I use:
docker start gulp-docker-test
it will start the container? What if I change anything inside it? Will it be back on reboot of the container? Or is it gone because it is only a temporary image?
Beside that if I try to run it I get this error:
ERROR: for gulp-docker-test Cannot start service html: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"gulp --version\": executable file not found in $PATH": unknown
ERROR: for html Cannot start service html: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: \"gulp --version\": executable file not found in $PATH": unknown
I did try those things: execute it with exec, removing the quotes inside the CMD of the Dockerfile but I think I do have some basic knowledge missing. I don't understand how to boot this container inside the shell so docker knows the $path.
Thank you for your help in advance
Edit:
I did found out how to run docker with the shell.
docker run -it --entrypoint bash gulp-docker-test3
root@8a27dc3a9c85:/usr/src/app# gulp -v
[15:01:53] CLI version 2.0.1
[15:01:53] Local version 4.0.0
root@8a27dc3a9c85:/usr/src/app# gulp
[15:02:38] Using gulpfile /usr/src/app/gulpfile.js
[15:02:38] Starting 'default'...
Default Task von Gulp 4.0 für Docker
[15:02:38] Finished 'default' after 4.28 ms
root@8a27dc3a9c85:/usr/src/app#
It looks like it should work if I can add default bash to the dockerfile.
If I run
docker build
I will create a new container?
It will execute the contents of the Dockerfile, and create a new image.
You need to docker run
(or, rarely, docker create
) the image to create a container from it. When you update the Dockerfile or your application source, you need to repeat the docker build
step, docker stop && docker rm
the existing container, and docker run
a new one. Your docker-compose.yml
fragment encapsulates this, but note that Docker Compose will delete and recreate a container when it's appropriate.
If I use
docker start gulp-docker-test
...
It will start a container with that name. That's a separate namespace from the image namespace. The container has to already exist and be stopped (usually from an explicit docker stop
command). This is a slightly unusual state to be in.
CMD ["gulp --version" , "gulp"]
This looks for a binary named gulp --version
, and runs it with a single parameter gulp
. Since you probably don't have a single file named /usr/local/bin/gulp --version
(with the spaces and "version" as part of the filename) you get an error.
You only get one CMD in a Dockerfile. (Or one ENTRYPOINT instead, but I tend to find CMD preferable except in a couple of extremely specific cases.) Each "word" you'd type in a shell becomes a separate "word" in the syntax. So you could, for instance, write
CMD ["gulp", "--version"]
Alternatively, if you leave off the brackets, Docker will wrap the CMD text in sh -c ...
, so something closer to what you actually wrote is
CMD gulp --version && gulp
In practice you'd usually run build tools like Gulp as part of building the image, and use the CMD to actually start your application.
RUN gulp
CMD ["npm", "start"]