Why does my docker container have files from a different image? - docker

My application requires two docker files. I am building them with docker compose. The compose file is like this
version: '3.4'
services:
cors:
container_name: cors
image: cors:latest
build:
context: ./compose/cors-anywhere
dockerfile: Dockerfile
user: "node"
ports:
- 8081:8081
command: node server.js
vite:
container_name: vite
image: vite:lts
build:
context: ./compose/vite
user: "node"
tty: true
working_dir: /app
ports:
- "5173:5173"
volumes:
- ./vite/:/app
command: /start
cors' Dockerfile is like this
ARG NODE_VERSION=lts
FROM node:${NODE_VERSION}
ENV NODE_ENV=production
ENV NODE_PATH=/usr/local/lib/node_modules
ARG version=latest
RUN npm install -g cors-anywhere#$version
COPY server.js .
CMD ["node", "server.js"]
EXPOSE 8081
and vite's docker file is like this
ARG NODE_VERSION=latest
FROM node:${NODE_VERSION}
RUN npm install -g npm#latest
COPY ./entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint
COPY ./start /start
RUN sed -i 's/\r$//g' /start
RUN chmod +x /start
ENTRYPOINT ["/entrypoint"]
vite's entrypoint script is like this
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
until cd /app && npm install
do
echo "Retrying npm install"
done
exec "$#"
After the images have been built, when the cors container comes 'up' it logs lots of errors because it is trying to run vite's entrypoint script. I don't understand why entrypoint has been copied to the cors image. Here is the file structure for the cors container
node#d960251bf35e:/$ ls -l
total 80
drwxr-xr-x 1 root root 4096 Jan 11 03:25 bin
drwxr-xr-x 2 root root 4096 Dec 9 19:15 boot
drwxr-xr-x 5 root root 340 Jan 12 10:52 dev
-rwxr-xr-x 1 root root 139 Jan 11 21:59 entrypoint
drwxr-xr-x 1 root root 4096 Jan 12 10:52 etc
drwxr-xr-x 1 root root 4096 Jan 11 07:59 home
drwxr-xr-x 1 root root 4096 Jan 11 03:25 lib
drwxr-xr-x 2 root root 4096 Jan 9 00:00 media
drwxr-xr-x 2 root root 4096 Jan 9 00:00 mnt
drwxr-xr-x 1 root root 4096 Jan 11 07:59 opt
dr-xr-xr-x 211 root root 0 Jan 12 10:52 proc
drwx------ 1 root root 4096 Jan 11 07:59 root
drwxr-xr-x 3 root root 4096 Jan 9 00:00 run
drwxr-xr-x 1 root root 4096 Jan 11 03:24 sbin
-rw-r--r-- 1 root root 2023 Jan 11 15:24 server.js
drwxr-xr-x 2 root root 4096 Jan 9 00:00 srv
-rwxr-xr-x 1 root root 71 Jan 11 21:59 start
dr-xr-xr-x 13 root root 0 Jan 12 10:52 sys
drwxrwxrwt 1 root root 4096 Jan 11 07:59 tmp
drwxr-xr-x 1 root root 4096 Jan 9 00:00 usr
drwxr-xr-x 1 root root 4096 Jan 9 00:00 var
What am I not understanding?

Related

how to replace nginx default page in docker using dockerfile

I am trying to host a static site in docker using dockerfile
dockerfile
FROM nginx:latest
COPY . /usr/share/nginx/html
Docker command
docker build -t newwebsite .
docker run --name website -d -p 8080:80 newwebsite
But it still displays the nginx default page when run localhost:8080
Ho do I go about debugging this?
Is there any content in the directory where you are running the docker build command?
COPY . /user/share/nginx/html
This indicates that the contents are being copied from the current directory to a path in the Docker image.
Another way is to enter the running container and debug it.
(host) $ docker exec -it website /bin/bash
root#5bae70747b2c:/#
root#5bae70747b2c:/# ls -ltra /usr/share/nginx/html
total 20
-rw-r--r-- 1 root root 497 Jan 25 15:03 50x.html
drwxr-xr-x 1 root root 4096 May 28 05:40 ..
-rw-r--r-- 1 root root 48 Jun 7 03:50 Dockerfile
-rw-r--r-- 1 root root 135 Jun 7 03:51 index.html
drwxr-xr-x 1 root root 4096 Jun 7 03:51 .
The above is an example of serving index.html with Nginx, and you can check if there are contents in /usr/share/nginx/html like this.

Permissions best-practices when using docker exec

I am going through a docker course and have a simple Docker script which sets up an image:
FROM node:14.16.0-alpine3.13
RUN addgroup app && adduser -S -G app app
USER app
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package*.json ./
RUN npm install
COPY . .
ENV APP_URL=http://api.myapp.com
EXPOSE 3000
CMD ["npm", "start"]
Now, in the script it switches to USER app but when I log in to Docker exec using docker exec -it 187 sh I can ask it whoami and get the response: app which is correct. The problem comes when I try to write a file using the echo command:
echo data > data.txt
sh: can't create data.txt: Permission denied
So then I run ls -la to view files and perms:
/app $ ls -la
total 1456
drwxr-xr-x 1 root root 4096 Oct 20 16:38 .
drwxr-xr-x 1 root root 4096 Oct 20 19:54 ..
-rw-rw-r-- 1 root root 13 Oct 20 13:46 .dockerignore
drwxr-xr-x 7 root root 4096 Mar 9 2021 .git
-rw-r--r-- 1 root root 310 Mar 5 2021 .gitignore
-rw-rw-r-- 1 root root 311 Oct 20 16:38 Dockerfile
-rw-r--r-- 1 root root 3362 Mar 5 2021 README.md
drwxr-xr-x 1 root root 4096 Oct 20 16:38 node_modules
-rw-rw-r-- 1 root root 1434378 Oct 20 16:10 package-lock.json
-rw-r--r-- 1 root root 814 Oct 20 16:10 package.json
drwxr-xr-x 2 root root 4096 Mar 9 2021 public
drwxr-xr-x 2 root root 4096 Oct 20 13:22 src
Which shows that root is the user and group set for these files/dirs. This was obviously intended as we don't want to be logging in as root. So what should I do to be able to add this file to the container? What is the best practice here? Maybe I missed a step somewhere?
Edit: Should the /app be owned by the USER app? If so, what is the point in adding a new user? should I add this to the docker script:
RUN chown app /app
Thanks!
Should the /app be owned by the USER app?
Definitely not. You want to prevent the application from overwriting its own code and static assets, intentionally or otherwise.
So what should I do to be able to add this file to the container?
Create a dedicated directory to hold your application's data. This should be a different directory from the directory with the source code; a subdirectory of your normal application directory is fine. In the Dockerfile, make this directory (only) be owned by your non-root user.
FROM node:14.16.0-alpine3.13
RUN addgroup app && adduser -S -G app app
# don't switch to this user quite yet
WORKDIR /app
# usual setup and build stuff
COPY package*.json ./
RUN npm ci
COPY . ./
RUN npm build
# create the data directory and set its owner
RUN mkdir data && chown app data
# _now_ switch to the non-root user when running the container
EXPOSE 3000
USER app
CMD ["npm", "start"]
In practice, you probably want to persist the application's data beyond the lifespan of a single container. One approach to this is to use a Docker named volume. If you do this, the volume will be initialized from the image, including its ownership, and so you don't need any special setup here.
docker volume create app-data
docker run -v app-data:/app/data ...
For several reasons you may prefer to use a bind mount (if you need to directly access the files from outside of Docker; it may be easier to back up and restore the files; ...). You can also use the docker run -v option to bind-mount a host directory into a container, but it brings along its host-system numeric uid owner. However, notice that the only thing in the image that has the app owner is the data directory, and the code is otherwise world-readable, so if we set the container to run with the same uid as the host user, this will still work.
docker run -v "$PWD/data:/app/data" -u $(id -u) ...
You should not normally need Docker volumes for your application code (it is contained in the image), nor should you need to build a specific host uid into the image.

Docker: COPY can't find files in local directory where the `docker build` runs

in a directory with prefix /home/gitlab-runner/builds/, there is a example.jar file and a Dockerfile, in the Dockerfile, there are statements as below:
COPY example.jar /app
I run
docker build -t image_name ./
then I get the following error:
COPY failed: stat /var/lib/docker/tmp/docker-builder457658077/example.jar: no such file or directory
why can't COPY find the example.jar from within the directory with prefix /home/gitlab-runner/builds/? how does the strange /var/lib/docker.. path jumps in? how to deal with this? thanks!
[root#koala 53bdd1747e3590f90fcc84ef4963d4885711e25f]# pwd
/home/gitlab-runner/builds/pica/eureka/53bdd1747e3590f90fcc84ef4963d4885711e25f
[root#koala 53bdd1747e3590f90fcc84ef4963d4885711e25f]# ls -al
total 52068
drwxrwxr-x 5 gitlab-runner gitlab-runner 4096 Dec 11 15:23 .
drwxrwxr-x 4 gitlab-runner gitlab-runner 4096 Dec 11 11:35 ..
-rw-rw-r-- 1 gitlab-runner gitlab-runner 17 Dec 11 11:35 APPLICATION_VERSION
-rw-rw-r-- 1 gitlab-runner gitlab-runner 644 Dec 11 11:35 docker-compose.yml
-rw-rw-r-- 1 gitlab-runner gitlab-runner 568 Dec 11 15:23 Dockerfile
drwxrwxr-x 8 gitlab-runner gitlab-runner 4096 Dec 11 11:35 .git
-rw-rw-r-- 1 gitlab-runner gitlab-runner 322 Dec 11 11:35 .gitignore
-rw-rw-r-- 1 gitlab-runner gitlab-runner 2438 Dec 11 11:35 .gitlab-ci.yml
-rw-rw-r-- 1 gitlab-runner gitlab-runner 53271183 Dec 11 11:35 example.jar
-rw-rw-r-- 1 gitlab-runner gitlab-runner 1043 Dec 11 11:35 pom.xml
drwxrwxr-x 4 gitlab-runner gitlab-runner 4096 Dec 11 11:35 src
drwxrwxr-x 8 gitlab-runner gitlab-runner 4096 Dec 11 11:35 target
[ copying my answer from server fault, didn't realize this question was cross-posted ]
COPY example.jar /app
This command expects an example.jar in the root of your build context. The build context is the last argument to docker build, in this case ., or the current directory. From the ls -al output, you do not file this jar file in the directory and docker is telling you the COPY command cannot find the example.jar in the build context. If it is in one of the other sub directories, you'll need to update the COPY command with that location.
To debug issues with the build context, you can build and run the following Dockerfile:
FROM busybox
COPY . /build-context
WORKDIR /build-context
CMD find .
That will copy the entire build context into an image and list the contents out with a find command when you run the container.

Docker compose throws permission denied on mac

I am using this on Mac. Creating and running the docker image works fine. But with docker-compose I get the following error:
"exec: \"./boot.sh\": permission denied": unknown
Dockerfile:
FROM python:3.7-alpine
RUN adduser -D teamreacher
WORKDIR /home/teamreacher
# copy and install dependencies
COPY ./requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install --upgrade pip
RUN venv/bin/pip install -r requirements.txt
# copy the app
COPY . .
RUN chmod +x boot.sh # Giving execution permissions here...
RUN chown -R teamreacher:teamreacher ./
USER teamreacher
# expose port and run server
EXPOSE 5000
CMD ["./boot.sh"] # ...so why do I get permission denied here?
Docker compose file:
version: '3'
services:
teamreacher-server:
build: ./server
volumes:
- ./server:/home/teamreacher
ports:
- 5000:5000
I've looked through similiar questions but none provided an answer for my specific problem.
boot.sh
#!/bin/sh
source venv/bin/activate
exec gunicorn -b :5000 --access-logfile - --error-logfile - wsgi:app
By bind-mounting your ./server directory into the same location where boot.sh is located on the conotainer, you're rewriting the permissions so that it is no longer executable.
Please see the below demonstration:
TJs-MacBook-Pro:stackoverflow tj$ ls -lah
total 8
drwxr-xr-x 4 tj wheel 128B Dec 23 14:58 .
drwxrwxrwt 15 root wheel 480B Dec 23 15:05 ..
-rw-r--r-- 1 tj wheel 143B Dec 23 14:57 docker-compose.yaml
drwxr-xr-x 6 tj wheel 192B Dec 23 15:03 server
TJs-MacBook-Pro:stackoverflow tj$ ls -lah server/
total 24
drwxr-xr-x 6 tj wheel 192B Dec 23 15:03 .
drwxr-xr-x 4 tj wheel 128B Dec 23 14:58 ..
-rw------- 1 tj wheel 177B Dec 23 15:06 .ash_history
-rw-r--r-- 1 tj wheel 508B Dec 23 14:56 Dockerfile
-rw-r--r-- 1 tj wheel 105B Dec 23 14:56 boot.sh
-rw-r--r-- 1 tj wheel 0B Dec 23 14:56 requirements.txt
TJs-MacBook-Pro:stackoverflow tj$ docker-compose build
Building teamreacher-server
Step 1/13 : FROM python:3.7-alpine
---> 020295c920c6
Step 2/13 : RUN adduser -D teamreacher
---> Using cache
---> 7dbd3131c941
Step 3/13 : WORKDIR /home/teamreacher
---> Using cache
---> d2754b1b8dc2
Step 4/13 : COPY ./requirements.txt requirements.txt
---> Using cache
---> 2d468491a297
Step 5/13 : RUN python -m venv venv
---> Using cache
---> 0c135fa6f980
Step 6/13 : RUN venv/bin/pip install --upgrade pip
---> Using cache
---> ea7df7153a5a
Step 7/13 : RUN venv/bin/pip install -r requirements.txt
---> Using cache
---> db540a631c19
Step 8/13 : COPY . .
---> 174a91493622
Step 9/13 : RUN chmod +x boot.sh # Giving execution permissions here...
---> Running in b9cedb0f163a
Removing intermediate container b9cedb0f163a
---> 6d5ce7df1969
Step 10/13 : RUN chown -R teamreacher:teamreacher ./
---> Running in 2e672e8ac6ef
Removing intermediate container 2e672e8ac6ef
---> 48342c4c31e3
Step 11/13 : USER teamreacher
---> Running in 4d3bc99fb515
Removing intermediate container 4d3bc99fb515
---> 11bdc7be7f84
Step 12/13 : EXPOSE 5000
---> Running in 0924db9c175b
Removing intermediate container 0924db9c175b
---> 0d96d773f42f
Step 13/13 : CMD ["./boot.sh"] # ...so why do I get permission denied here?
---> Running in 4a33ab4e342a
Removing intermediate container 4a33ab4e342a
---> a9acefb4eeac
Successfully built a9acefb4eeac
Successfully tagged stackoverflow_teamreacher-server:latest
TJs-MacBook-Pro:stackoverflow tj$ docker run stackoverflow_teamreacher-server ls -lah /home/teamreacher
total 24
drwxr-sr-x 1 teamreac teamreac 4.0K Dec 23 20:07 .
drwxr-xr-x 1 root root 4.0K Dec 23 19:56 ..
-rw------- 1 teamreac teamreac 177 Dec 23 20:06 .ash_history
-rw-r--r-- 1 teamreac teamreac 508 Dec 23 19:56 Dockerfile
-rwxr-xr-x 1 teamreac teamreac 105 Dec 23 19:56 boot.sh
-rw-r--r-- 1 teamreac teamreac 0 Dec 23 19:56 requirements.txt
drwxr-sr-x 1 teamreac teamreac 4.0K Dec 23 19:59 venv
TJs-MacBook-Pro:stackoverflow tj$ docker run -v $(pwd)/server:/home/teamreacher stackoverflow_teamreacher-server ls -lah /home/teamreacher
total 16
drwxr-xr-x 6 teamreac teamreac 192 Dec 23 20:03 .
drwxr-xr-x 1 root root 4.0K Dec 23 19:56 ..
-rw------- 1 teamreac teamreac 177 Dec 23 20:06 .ash_history
-rw-r--r-- 1 teamreac teamreac 508 Dec 23 19:56 Dockerfile
-rw-r--r-- 1 teamreac teamreac 105 Dec 23 19:56 boot.sh
-rw-r--r-- 1 teamreac teamreac 0 Dec 23 19:56 requirements.txt
It turns out I had to give the file boot.sh execution permissions on my mac as well. That means running:
chmod +x boot.sh
in my project directory.

How to copy subfolders in docker

I have following folder structure:
nova-components
component1
dist
...
component2
dist
...
component3
dist
...
...
Is there any way to copy only dist folders in docker.
I am thinking about something like:
COPY --from=assets /nova-components/*/dist /var/www/nova-components/*/dist
The end goal is to include generated dist folders in the final image and keep the directory tree structure.
Currently multi-stage docker build do not respect .dockerignore, see this discussion, so you had to do it yourself, one way is to clean things in the first stage, like follows:
Dockerfile:
FROM ubuntu:16.04 AS assets
RUN mkdir -p /nova-components/component1/dist && \
mkdir -p /nova-components/component1/others && \
mkdir -p /nova-components/component2/dist && \
mkdir -p /nova-components/component2/others
RUN find /nova-components/*/* ! -name "dist" -maxdepth 0 | xargs rm -fr
FROM ubuntu:16.04
COPY --from=assets /nova-components /var/www/nova-components/
RUN ls -alh /var/www/nova-components
RUN ls -alh /var/www/nova-components/*
test:
# docker build --no-cache -t try:1 .
Sending build context to Docker daemon 2.048kB
Step 1/7 : FROM ubuntu:16.04 AS assets
---> b9e15a5d1e1a
Step 2/7 : RUN mkdir -p /nova-components/component1/dist && mkdir -p /nova-components/component1/others && mkdir -p /nova-components/component2/dist && mkdir -p /nova-components/component2/others
---> Running in d4c9c422d53a
Removing intermediate container d4c9c422d53a
---> d316032dd59d
Step 3/7 : RUN find /nova-components/*/* ! -name "dist" -maxdepth 0 | xargs rm -fr
---> Running in b6168b027f4c
Removing intermediate container b6168b027f4c
---> 9deb57cb5153
Step 4/7 : FROM ubuntu:16.04
---> b9e15a5d1e1a
Step 5/7 : COPY --from=assets /nova-components /var/www/nova-components/
---> 49301f701db2
Step 6/7 : RUN ls -alh /var/www/nova-components
---> Running in 9ed0cafff2fb
total 16K
drwxr-xr-x 4 root root 4.0K Nov 6 02:13 .
drwxr-xr-x 3 root root 4.0K Nov 6 02:13 ..
drwxr-xr-x 3 root root 4.0K Nov 6 02:13 component1
drwxr-xr-x 3 root root 4.0K Nov 6 02:13 component2
Removing intermediate container 9ed0cafff2fb
---> f1ee82cff972
Step 7/7 : RUN ls -alh /var/www/nova-components/*
---> Running in 23a27e5ce853
/var/www/nova-components/component1:
total 12K
drwxr-xr-x 3 root root 4.0K Nov 6 02:13 .
drwxr-xr-x 4 root root 4.0K Nov 6 02:13 ..
drwxr-xr-x 2 root root 4.0K Nov 6 02:13 dist
/var/www/nova-components/component2:
total 12K
drwxr-xr-x 3 root root 4.0K Nov 6 02:13 .
drwxr-xr-x 4 root root 4.0K Nov 6 02:13 ..
drwxr-xr-x 2 root root 4.0K Nov 6 02:13 dist
Removing intermediate container 23a27e5ce853
---> b9d5ab8f5157
Successfully built b9d5ab8f5157
Successfully tagged try:1
With the clean in first stage using RUN find /nova-components/*/* ! -name "dist" -maxdepth 0 | xargs rm -fr, then you can make it, let's wait for possible official feature support.
Add a .dockerignore file with your Dockerfile
nova-components/*/*
!nova-components/*/dist
And copy like
COPY nova-components/ /var/www/nova-components
EDIT
So with multi stage build, this is currently not working. A new solution is to run, on the last stage,
rsync -avz --include='dist/' nova-components/ nova-components-dist/.
then at the final stage,
COPY --from=assets /nova-components-dist/ /var/www/nova-components

Resources