I'm trying to build a web application based on flask and vue.js, using docker containers.
I use volume sharing in docker-compose and I'm facing an issue with the container structure.
I'd like to share the application folder from the host with the /app container folder. To do so the docker-compose is set up as
volumes:
- type: bind
source: ./
target: /app
inspecting the container shows that the data from the host is placed inside the folder /app/app and not inside the folder /app as expected. The working directory is set up inside the docker container:
FROM continuumio/miniconda3:latest
WORKDIR /app
COPY dependency.yml .
RUN conda env create -f dependency.yml
COPY setup.py .
RUN pip install -e .
In an attempt to try to understand the relative/absolute path I tried to change the target volume to /data in the docker-compose file. In this case the application files are installed in the /app and the host files are copied in the /data folder, as expected.
The question is: why if I try to use the absolute /app folder in the container does the system use it as relative to the WORKDIR, and this happens only if the WORKDIR has the same name as the target folder?
I have an Angular - Flask app that I'm trying to dockerize with the following Dockerfile:
FROM node:latest as node
COPY . /APP
COPY package.json /APP/package.json
WORKDIR /APP
RUN npm install
RUN npm install -g #angular/cli#7.3.9
CMD ng build --base-href /static/
FROM python:3.6
WORKDIR /root/
COPY --from=0 /APP/ .
RUN pip install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["app.py"]
On building the image and running the image, console gives no errors. However, it seems to be stuck. What could be the issue here?
Is it because they are both in different directories?
Since I'm dockerizing Flask as well as Angular, how can I put both in same directory (right now one is in /APP and the other in /root)
OR should I put the two in separate containers and use a docker-compose.yml file?
In that case, how do I write the file? Actually my Flask calls my Angular and both run on same port. So I'm not sure if running in two different containers is a good idea.
I am also providing the commands that I use to build and run the image for reference:
docker image build -t prj .
docker container run --publish 5000:5000 --name prj prj
In the Angular build first stage of the Dockerfile, use RUN instead of CMD.
CMD is for running a command after the final image is built.
In the docker docs getting started tutorial part 2, it has one make a Dockerfile. It instructs to add the following lines:
# Set the working directory to /app
WORKDIR /app
# Copy the current directory contents into the container at /app
COPY . /app
What is /app, and why is this a necessary step?
There are two important directories when building a docker image:
the build context directory.
the WORKDIR directory.
Build context directory
It's the directory on the host machine where docker will get the files to build the image. It is passed to the docker build command as the last argument. (Instead of a PATH on the host machine it can be a URL). Simple example:
docker build -t myimage .
Here the current dir (.) is the build context dir. In this case, docker build will use Dockerfile located in that dir. All files from that dir will be visible to docker build.
The build context dir is not necessarily where the Dockerfile is located. Dockerfile location defaults to current dir and is otherwise indicated by the -f otpion. Example:
docker build -t myimage -f ./rest-adapter/docker/Dockerfile ./rest-adapter
Here build context dir is ./rest-adapter, a subdirectory of where you call docker build; the Dokerfile location is indicated by -f.
WORKDIR
It's a directory inside your container image that can be set with the WORKDIR instruction in the Dockerfile. It is optional (default is /, but base image might have set it), but considered a good practice. Subsequent instructions in the Dockerfile, such as RUN, CMD and ENTRYPOINT will operate in this dir. As for COPY and ADD, they use both...
COPY and ADD use both dirs
These two commands have <src> and <dest>.
<src> is relative to the build context directory.
<dest> is relative to the WORKDIR directory.
For example, if your Dockerfile contains...
WORKDIR /myapp
COPY . .
then the contents of your build context directory will be copied to the /myapp dir inside your docker image.
WORKDIR is a good practice because you can set a directory as the main directory, then you can work on it using COPY, ENTRYPOINT, CMD commands, because them will execute pointing to this PATH.
Docker documentation: https://docs.docker.com/engine/reference/builder/
The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.
The WORKDIR instruction can be used multiple times in a Dockerfile. If a relative path is provided, it will be relative to the path of the previous WORKDIR instruction.
Dockerfile Example:
FROM node:alpine
WORKDIR '/app'
COPY ./package.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "start"]
A alpine node.js was created and the workdir is /app, then al files are copied them into /app
Finally npm run start command is running into /app folder inside the container.
You should exec the following command in the case you have sh or bash tty:
docker exec -it <container-id> sh
or
docker exec -it <container-id> bash
After that you can do ls command and you will can see the WORKDIR folder.
I hope it may help you
You need to declare a working directory and move your code into it, because your code has to live somewhere. Otherwise your code wouldn't be present and your app wouldn't run. Then when commands like RUN, CMD, ENTRYPOINT, COPY, and ADD are used, they are executed in the context of WORKDIR.
/app is an arbitrary choice of working directory. You could use anything you like (foo, bar, or baz), but app is nice since it's self-descriptive and commonly used.
Below is my dockerfile, I do a copy of js file in copy command and set working directory after that,followed by volume and run command.Below is my dockerfile
1) I understand node_modules(Which is created because of running npm install) IS getting wipedoff when container is first initialized because of create volume in the same location
My quesion why my app.js which i copied in step 3 is not getting wiped of since its also on the same path as volume?
FROM node:latest
ENV NODE_ENV=production
ENV PORT=3000
COPY . /app
WORKDIR /app
VOLUME ["/app"]
RUN npm install
EXPOSE $PORT
ENTRYPOINT ["node","app.js"]
Q: Why is my app.js (which i copied in step 3) is not getting wiped off while node_modules is.
A: As explained in docker's documentation under the volume section.
Quote:
Changing the volume from within the Dockerfile:
If any build steps
change the data within the volume after it has been declared, those
changes will be discarded.
Reference: https://docs.docker.com/engine/reference/builder/#notes-about-specifying-volumes
docker build Dockerfile .//running it correctly.
1.) I have mentioned in the comments each command will execute as written, Is that correct working of this Dockerfile?
2.)These commands will be used to make the image when I ran docker build, so
[ec2-user#ip-xx-xx-xx-xx ~]$cd /project/p1
[ec2-user#ip-xx-xx-xx-xx p1]$ls
Dockerfile a b c d
My Dockerfile consists of following commands.
Dockerfile
node 8.1.0 //puls the image from hub
RUN mkdir -p /etc/x/y //make directory in the host at path /etc/x/y
RUN mkdir /app //make directory in the host at path /app
COPY . /app //copy all the files that is
WORKDIR /app //cd /app; now the working directory will be /app for next commands i.e npm install.
RUN npm install
EXPOSE 3000 //what this will do?
Question 1: how to run docker build?
docker build Dockerfile . # am I running it correctly.
No, you run it with docker build . and docker will automatically look for the Dockerfile in the current directory. Or you use docker build -f Path_to_the_docker_file/DockerFile where you clearly specify the path to the DockerFile.
Question 2: Fixing errors and clarifying commands
There are few mistakes in the Dockerfile, check the edited comments:
# pulls the image from dockerhub : YES
# Needs to be preceeded with FROM
FROM node 8.1.0
# all directories are made inside the docker image
# make directory in the image at path /etc/x/y : YES
RUN mkdir -p /etc/x/y
# make directory in the image at path /app : YES
RUN mkdir /app
COPY . /app # copy all the files that is : YES
WORKDIR /app # cd /app; now the working directory will be /app for next commands i.e npm install. : YES
RUN npm install
EXPOSE 3000 # what this will do? => tells all docker instances of this image to listen on port 3000.