Dockerfile in a docker compose yaml and copying problem

Hi,

I have a Dockerfile which works if i make a container out of it, but doesnt work completely when i run it via compose yaml file.

Dockerfile:

FROM alpine:latest
LABEL maintainer="hasham1983@yahoo.com"
RUN mkdir -p /tmp/hasham
COPY ./shell.sh /tmp/hasham/
RUN chmod 775 /tmp/hasham/shell.sh
RUN echo '*/1  *  *  *  *    /tmp/hasham/shell.sh' > /etc/crontabs/root
CMD crond && sleep infinite

The shell script gets copied from my context directory into the container at /tmp/hasham/

However the problem is whenever I run this dockerfile as a part of docker compose, the shell script created on the container is empty. the filename is there in the container but with no contents. I dont understand why is this happening only when running through compose.

please can someone tell me what am i doing wrong?

test.yaml

services:
    my_app:
        container_name: myapp
        build:
            dockerfile: ./alpine.Dockerfile
        networks:
            - mynetwork
networks:
    mynetwork:
        name: mynetwork
        driver: bridge

please help !

thanks

H

Hello nystateofhealth@hasham1983,

You’re encountering an issue with copying files from your Dockerfile into the container when using Docker Compose. Let’s troubleshoot this together.

The problem you’re facing might be related to how volumes are mounted in Docker Compose. Let’s break down the issue and provide a solution.
In your docker-compose.yaml, you’ve defined a volume for your service:

volumes:
    - ./carrier:/var/local/Config/

This volume mounts the local directory ./carrier (from your host machine) into the container at /var/local/Config/.
When you use volumes, the content inside the container’s target directory (/var/local/Config/) is replaced by the content from the host directory (./carrier).
In your Dockerfile, you’re copying the shell script from the context directory into the container:
COPY ./shell.sh /tmp/hasham/

The COPY command should work as expected, but the issue arises when the volume is mounted.
When you run your container using Docker Compose, the volume mount (./carrier:/var/local/Config/) takes precedence over the content inside the container.
As a result, the shell script copied during the build process is overwritten by the empty directory from the host.
To fix this, you can modify your Dockerfile to copy the shell script directly into the target directory (/var/local/Config/) instead of relying on the volume mount.
Update your Dockerfile as follows:

FROM alpine:latest
LABEL maintainer="hasham1983@yahoo.com"
RUN mkdir -p /tmp/hasham
COPY ./shell.sh /var/local/Config/
RUN chmod 775 /var/local/Config/shell.sh
RUN echo '*/1  *  *  *  *    /var/local/Config/shell.sh' > /etc/crontabs/root
CMD crond && sleep infinite

By copying the script directly into the container’s target directory, it won’t be affected by the volume mount.
After updating your Dockerfile, rebuild your image:
docker-compose build

Then run your container using Docker Compose:
docker-compose up -d

Check if the shell script is correctly placed inside the container:
docker exec -it myapp ls -al /var/local/Config/

This modification should ensure that your shell script is copied correctly into the container even when using Docker Compose.

Best Regards,
nystateofhealth

1 Like

ah good thanks, what if i want to use my own directory like /tmp/hasham or /apps/ something like that? there should be a way of copying the files from context folder to a directory of our choice in the container.

is this volume mount (/var/local/Config/) a sort of default doker compose volume and cannot be changed?
or you just gave an example, and can be changed. ie. i use
volumes: ./docker_test_4:/tmp/hasham/ ?

I mean i want to move this shell.sh to that /tmp/hasham/ directory and dont want to move it to /var/local/confg directory

This response appears to be AI generate content, as it refers to something that is not part of the original post. Posting AI generated content is not welcome in these forums, and leads to permanent ban.

@hasham1983 please ignore everything regarding volumes in the post of @christy2951hernandez.

A build does not use volumes defined in the volumes: key of a service. Everything must be declared underneath the build key. You can specify the build context, which in your case should default to the location of the compose file. The Dockerfile needs to be specified relative to the build context. COPY instructions inside a Dockerfile only allow copying files from the build context into the image. Every file, subfolder, and files in subfolders will be available in the build context.

So if your folder structure looks like this:

|- test.yml
|- shell.sh
|- alpine.Dockerfile

And you build with docker compose -f test.yaml build, the content of shell.sh on the host should be the same, as /tmp/hasham/shell.sh inside the container.

thanks Meyay, let me try again but i cant get my head around the fact that it is creating the file but an empty file !

can someone please try this and let me know where its going wrong?

Thats resolved now.

everytime i was running compose up and compose down command, it was deleting the containers only and not the image, so whenever I was running the compose up command, it was using the already exisitng image rather creating a new one, hence i was unable to see my data in the shell script (probably when i created this image the first time i didnt put anything in the shell script)