I have a very simple project:
Dockerfile:
from node:lts
VOLUME /scripts
WORKDIR /scripts
RUN bash -c 'ls /'
RUN bash -c 'ls /scripts'
RUN script.sh
docker-compose.yml:
version: '3.7'
services:
service:
build: .
volumes:
- .:/scripts
Then I run docker-compose build but it fails with /bin/sh: 1: script.sh: not found
From the ls /scripts I can see that Docker isn't binding my script to the container. I have Docker 19.03.8. Do you know what I am doing wrong?
When you run a Docker Compose file, the build: block is run first, and it ignores all of the options outside that block. A Dockerfile never has mounted volumes, it can never make network calls to other Compose containers, and it won't see environment: variables that are set elsewhere.
That means you must explicitly COPY code into your image before you can RUN it.
FROM node:ls
WORKDIR /scripts
COPY script.sh .
RUN ./script.sh
Related
I have a docker-compose file with a service called 'app'. When I try to run my docker file I don't see the service with docker ps but I do with docker ps -a.
I looked at the logs:
docker logs my_app_1
python: can't open file '//apps/index.py': [Errno 2] No such file or directory
In order to debug I wanted to be able to see the home directory and the files and dirs contained there when the app attempts to run.
Is there a command I can add to docker-compose that would show me the pwd and ls -l of the container when it attempts to run index.py?
My Dockerfile:
FROM python:3
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "apps/index.py"]
My docker-compose.yaml:
version: '3.1'
services:
app:
build:
context: ./app
dockerfile: ./Dockerfile
depends_on:
- db
ports:
- 8050:8050
My directory structure:
my_app:
* docker-compose.yaml
* app
* Dockerfile
* apps
* index.py
You can add a RUN statement in the application Dockerfile to run these commands.
Example:
FROM python:3
COPY . .
RUN pip install -r requirements.txt
# Run your commands
RUN pwd && ls -l
CMD ["python", "apps/index.py"]
Then you chan check the logs of the build process and view the results.
I hope this answer helps you.
If you're just trying to debug an image you've already built, you can docker-compose run an alternate command:
docker-compose run apps \
ls -l ./apps
You don't need to modify anything in your Dockerfile to be able to do this (assuming it uses CMD correctly; see below).
If you need to do more intensive debugging, you can docker-compose run apps sh (or, if your image has it, bash) to get an interactive shell. The container will include any mounted volumes and be on the same Docker network as the named container, but won't have published ports.
Note that the command here replaces the CMD in the Dockerfile. If your image uses ENTRYPOINT for its main command, or if it has a complete command split between ENTRYPOINT and CMD (especially, if you have ENTRYPOINT ["python"]), these need to be combined into a single CMD for this to work. If your ENTRYPOINT is a wrapper script that does some first-time setup and then runs the CMD, this approach will work fine; the debugging ls or sh will run after the first-time setup happens.
I am having trouble creating a volume that maps to the directory "/app" in my container
This is basically so when I update the code I don't need to build the container again
This is my docker file
# stage 1
FROM node:latest as node
WORKDIR /app
COPY . .
RUN npm install
RUN npm run build --prod
# stage 2
FROM nginx:alpine
COPY --from=node /app/dist/my-first-app /usr/share/nginx/html
I use this command to run the container
docker run -d -p 100:80/tcp -v ${PWD}/app:/app docker-testing:v1
and no volume gets linked to it.
However, if I were to do this
docker run -d -p 100:80/tcp -v ${PWD} docker-testing:v1
I do get a volume at least
Anything obvious that I am doing wrong?
Thanks
The ${PWD}:/app:/app should be ${PWD}/app:/app.
If you explode ${PWD}, you'd obtain something like /home/user/src/thingy:/app:/app which does not make much sense.
EDIT:
I'd suggest using docker-compose to avoid this kind of issues (it also simplify a lot the commands to start up docker).
In your case the docker-compose.yml would look like this:
docker run -d -p 100:80/tcp -v ${PWD}:/app:/app docker-testing:v1
version: "3"
services:
doctesting:
build: .
image: docker-testing:v1
volumes:
- "./app:/app"
ports:
- "100:80"
I didn't really test if it works, there might be typos...
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:
I cannot create a directory with the mkdir command in a container with dockerfile.
My Dockerfile file is simply ;
FROM php:fpm
WORKDIR /var/www/html
VOLUME ./code:/var/www/html
RUN mkdir -p /var/www/html/foo
In this way I created a simple php: fpm container.
and I wrote to create a directory called foo.
docker build -t phpx .
I have built with the above code.
In my docker-compose file as follows.
version: '3'
services:
web:
container_name: phpx
build : .
ports:
- "80:80"
volumes:
- ./code:/var/www/html
later; run the following code and I entered the container kernel.
docker exec -it phpx /bin/bash
but there is no a directory called foo in / var / www / html.
I wonder where I'm doing wrong.
Can you help me?
The reason is that you are mounting a volume from your host to /var/www/html.
Step by step:
RUN mkdir -p /var/www/html/foo creates the foo directory inside the filesystem of your container.
docker-compose.yml ./code:/var/www/html "hides" the content of /var/www/html in the container filesystem behind the contents of ./code on the host filesystem.
So actually, when you exec into your container you see the contents of the ./code directory on the host when you look at /var/www/html.
Fix: Either you remove the volume from your docker-compose.yml or you create the foo-directory on the host before starting the container.
Additional Remark: In your Dockerfile you declare a volume as VOLUME ./code:/var/www/html. This does not work and you should probably remove it. In a Dockerfile you cannot specify a path on your host.
Quoting from docker:
The host directory is declared at container run-time: The host directory (the mountpoint) is, by its nature, host-dependent. This is to preserve image portability. since a given host directory can’t be guaranteed to be available on all hosts. For this reason, you can’t mount a host directory from within the Dockerfile. The VOLUME instruction does not support specifying a host-dir parameter. You must specify the mountpoint when you create or run the container.
I am able to create a directory inside the 'workdir' for docker as follows:
Dockerfile content
COPY src/ /app
COPY logging.conf /app
COPY start.sh /app/
COPY Pipfile /app/
COPY Pipfile.lock /app/
COPY .env /app/
RUN mkdir -p /app/logs
COPY logs/some_log.log /app/logs/
WORKDIR /app
I have not mentioned the volume parameter in my 'docker-compose.yaml' file
So here is what I suggest: Remove the volume parameter from the 'Dockerfile' as correctly pointed by the Fabian Braun.
FROM php:fpm
RUN mkdir -p /var/www/html/foo
WORKDIR /var/www/html
And remove the volume parameter from the docker-compose file. It will work. Additionally, I would like to know how you tested of there is a directory named 'foo'.
Docker-compose file content
version: '3'
services:
web:
build:
context: .
dockerfile: Dockerfile # The name of your docker file
container_name: phpx
ports:
- "80:80"
You can use the SHELL instruction of Dockerfile.
ENV HOME /usr/local
SHELL ["/bin/sh", "-c"]
RUN mkdir $HOME/logs
docker-compose.yaml:
web:
build: .
command: ./main
ports:
- "8888:3412"
volumes:
- .:/code
links:
- redis
redis:
image: redis
Dockerfile:
FROM golang:1.6
ADD main.go .
EXPOSE 3412
ENTRYPOINT /go
RUN go build main.go
so after running docker run -d imagename, there is no running container
also docker logs containername doesn't show anything
ENTRYPOINT /go
is equivalent to running /bin/sh -c /go
go is actually a directory in your container, so it will fail, because shell cannot execute a directory.
remove the background flag -d and use docker run imagename and you will see this error
What you probably want is:
ENTRYPOINT /usr/local/go/bin/go to use go as an executable from the container.
Or even better:
ENTRYPOINT ["/usr/local/go/bin/go"], so you would be able to pass arguments to go.