Docker Image Contains files that Docker Container doesn't - docker

I have a Dockerfile that contains steps that create a directory and runs an angular build script outputing to that directory. This all seems to run correctly. However when the container runs, the built files and directory are not there.
If I run a shell in the image:
docker run -it pnb_web sh
# cd /code/static
# ls
assets favicon.ico index.html main.js main.js.map polyfills.js polyfills.js.map runtime.js runtime.js.map styles.js styles.js.map vendor.js vendor.js.map
If I exec a shell in the container:
docker exec -it ea23c7d30333 sh
# cd /code/static
sh: 1: cd: can't cd to /code/static
# cd /code
# ls
Dockerfile api docker-compose.yml frontend manage.py mysite.log pnb profiles requirements.txt settings.ini web_variables.env
david#lightning:~/Projects/pnb$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea23c7d30333 pnb_web "python3 manage.py r…" 13 seconds ago Up 13 seconds 0.0.0.0:8000->8000/tcp pnb_web_1_267d3a69ec52
This is my dockerfile:
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash -
RUN apt install nodejs
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
RUN mkdir /code/static
WORKDIR /code/frontend
RUN npm install -g #angular/cli
RUN npm install
RUN ng build --outputPath=/code/static
and associated docker-compose:
version: '3'
services:
db:
image: postgres
web:
build:
context: .
dockerfile: Dockerfile
working_dir: /code
env_file:
- web_variables.env
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
depends_on:
- db
In the second example, the static directory has never been created or built into. I thought that a container is an instance of an image. How can the container be missing files from the image?

You're confusing build-time and run-time, along playing with Volumes.
Remember that host mount has priority over FS provided by the running container, so even your built image has assets, they are going to be overwritten by .services.web.volumes because you're mounting the host filesystem that overwrites the build result.
If you try to avoid volumes mounting you'll notice that everything is working as expected.

Related

Preventing Docker Compose container from creating files as root

Dockerfile:
FROM node:18.13.0
ENV WORK_DIR=/app
RUN mkdir -p ${WORK_DIR}
WORKDIR ${WORK_DIR}
RUN mkdir ${WORK_DIR}/data
RUN chmod -R 755 ${WORK_DIR}/data
COPY package*.json ./
RUN npm ci
COPY . .
docker-compose.yml:
version: '3.8'
services:
fetch:
container_name: fetch
build: .
command: sh -c "npx prisma migrate deploy && npm start"
restart: unless-stopped
depends_on:
- postgres
volumes:
- ./data:/app/data:z
The container fetches new files and saves them into a directory configured by the app running in the container, defaulting to data/. The issue is that they're all created as root and cannot be manipulated by the host. If I chown the dir on the host, it works, but any new files are then created as root again.
I've tried a couple different variations of creating a new user in Dockerfile and passing host user info into the compose file but it always seems to result in a disconnect between the Dockerfile and compose file. I'm trying to keep things as easy as docker compose up, if possible.

Dockercompose run command on mounted directory

I am trying to create an editing environment for my project - I want to run poetry update on the code repository in the container when the container starts instead of manually having to do it.
When running docker-compose build editor-environment but obviously if we haven't run docker-compose up editor-environment the /code directory has not been mounted. How could I accomplish something like this?
Docker-Compose.yml
version: '3.6'
services:
editor-environment:
build:
dockerfile: env_docker/Dockerfile
volumes:
- .:/code
tty: true
Dockerfile
FROM python:3.10.4-slim-buster
RUN pip install poetry
RUN cd /code --> throws error, can't cd to /code
RUN poetry updates
ENTRYPOINT ["/bin/sh -c"]
CMD ["bash"]

Running docker-compose container from docker hub

I have created 2 containers locally and pushed them into docker hub to use on a VM, one is an Angular App and the other is a Django REST API with a db:
Angular App
Dockerfile
FROM node:latest as node
WORKDIR /app
COPY . .
RUN npm install npm#8.11.0 --legacy-peer-deps
RUN npm run build --prod
FROM nginx:alpine
COPY --from=node /app/dist/bom-e-barato /usr/share/nginx/html
I created the image by doing docker build -t andreclerigo/bom_e_barato:latest . then pushed it with docker push andreclerigo/bom_e_barato:latest and then I can run it on my VM by doing docker run -d -p 80:80 andreclerigo/bom_e_barato:latest
Django REST API
Dockerfile
FROM python:3.8.10
ENV PYTHONUNBUFFERED 1
RUN mkdir /rest-api-scraper
WORKDIR /rest-api-scraper
ADD . /rest-api-scraper/
RUN pip install -r requirements.txt
docker-compose.yml
version: '3'
services:
web:
build: .
command: bash -c "python backend/manage.py makemigrations && python backend/manage.py migrate && python backend/manage.py runserver 0.0.0.0:8000"
container_name: rest-api-scraper
volumes:
- .:/rest-api-scraper
ports:
- "8000:8000"
image: andreclerigo/rest-api-scraper:latest
I created the image by doing docker-compose build, then I pushed it to docker hub by doing docker-compose push to run locally I can do docker-compose up
Question
What steps do I need to take to pull this image and run the the image (docker-compose up) on my VM?

Docker compose ERROR: Service 'web' failed to build : COPY failed: forbidden path

I'm following the official docker tutorial to set up rails in docker the link of the same is given below
https://docs.docker.com/samples/rails/
My Dockerfile
# syntax=docker/dockerfile:1
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY ../compose /myapp
# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.yml
version: "3.9"
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: password
web:
build: .
command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
volumes:
- .:/myapp
ports:
- "3000:3000"
depends_on:
- db
The error which I'm getting when run this command
docker-compose run --no-deps web rails new . --force --database=postgresql
Error:
Step 7/12 : COPY ../compose /myapp
ERROR: Service 'web' failed to build : COPY failed: forbidden path outside the build context: ../compose ()
My dir structure is
docker-rails tree.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── docker-compose.yml
└── entrypoint.sh
0 directories, 5 files
I'm relatively new to docker setups. I saw similar kind of errors in SO but their set up files are different so couldn't understood how to fix it.
You are getting the error because you are trying to copy a file that is outside of the build context. the build context according to the documentation of docker-compose:
Either a path to a directory containing a Dockerfile, or a url to a
git repository.
When the value supplied is a relative path, it is interpreted as
relative to the location of the Compose file. This directory is also
the build context that is sent to the Docker daemon.
try changing COPY ../compose /myapp to COPY . .
and run the build command in a terminal within the directory

Docker for Windows - Volumes not working correctly

I am starting to work with Docker for Windows, but I can't make volumes to work with docker-compose.
First, I've created a simple Dockerfile:
FROM node:latest
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN npm install nodemon -g
Then, a docker-compose.yml:
version: '3'
services:
nodeServer:
build: .
volumes:
- './:/usr/src/app'
command: bash -c "npm run start"
When a volume is declared in the `docker-compose.yml´, it doesn't work.
But, when I try to bind a volume through the command line like this:
docker build .
docker run -it -v ${PWD}:/usr/src/app d0d9397e9194 bash
It works. I can't understand the difference between these two approaches.
I've checked more than once my configurations:

Resources