Docker: how to map host directory? - docker

I am trying to reproduce steps to create an Ubuntu based image + nginx, described there:
https://www.howtoforge.com/tutorial/how-to-create-docker-images-with-dockerfile/
My host machine is Windows.
The image is built, then I have created d:\webroot folder on host, index.html file inside and try to run
docker run -v /d/webroot:/var/www/html -p 80:80 --name doom nginx_image
standard_init_linux.go:211: exec user process caused "no such file or directory"
What may be the reason and how to fix it?

The issue is with the start.sh script which is loaded from Windows. Excerpt below:
#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
You need to change the change line ending from CRLF to LF for the start.sh.
And then run: docker run -v /d/webroot:/var/www/html -p 80:80 --name doom nginx_image

Related

403 with nginx for file located in binded volume with docker

I am trying to use my nginx server on docker but I cannot use the files / folder if they belong to my volume. Problem, the goal of my test is to keep a volume between the file in my computer and the container.
I have searched during 3 days and tried a lot of solution but no effects...( useradd, chmod, chown, www_data, etc.....)
I don't understand how is it possible to use ngnix, a volume and docker?
The only solution actually for me is to copy the folder of my volume in another folder, and so I can chown the folder and use NGIX. There is no official solution on the web and I am surprised because for me using docker with a volume binded with his container would be the basic for a daily work.
If someone has managed to implement it, I would be very happy if you could share you code. I need to understand what I am missing.
FYI I am working with a VM.
Thanks !
I think you are not passing the right path in the volume option. There are a few ways to do it, you can pass the full path or you can use the $(pwd) if you are using a Linux machine. Let's say you are on /home/my-user/code/nginx/ and your HTML files are on html folder.
You can use:
$ docker run --name my-nginx -v /home/my-user/code/nginx/html/:/usr/share/nginx/html:ro -p 8080:80 -d nginx
or
$ docker run --name my-nginx -v ~/code/nginx/html/:/usr/share/nginx/html:ro -p 8080:80 -d nginx
or
$ docker run --name my-nginx -v $(pwd)/html/:/usr/share/nginx/html:ro -p 8080:80 -d nginx
I've created an index.html file inside the html folder, after the docker run, I was able to open it:
$ echo "hello world" >> html/index.html
$ docker run --name my-nginx -v $(pwd)/html/:/usr/share/nginx/html:ro -p 8080:80 -d nginx
$ curl localhost:8080
hello world
You can also create a Dockerfile, but you would need to use COPY command. I'll give a simple example that's working, but you should improve this by using a version and etc..
Dockerfile:
FROM nginx
COPY ./html /usr/share/nginx/html
...
$ docker build -t my-nginx:0.0.1 .
$ docker run -d -p 8080:80 my-nginx:0.0.1
$ curl localhost:8080
hello world
You can also use docker-compose. By the way, those examples are just to give you some idea of how it works.

Docker: Error parsing configuration files, file does not exist

I am following a tutorial and using sqlc in my project. However, it's weird that I seem to mount an empty volume. After checking another post mounting the host directory, I found docker creates another empty folder, confirming that I did something wrong about it. Docker documentation doesn't help resolve this issue. Currently, my command with bash terminal:
docker run --rm -v $(pwd)://src -w //src kjconroy/sqlc init
docker run --rm -v $(pwd)://src -w //src kjconroy/sqlc generate
The first command runs successfully but creates another empty folder. The built container is running, and it's path is: \\wsl$\docker-desktop-data\data\docker\volumes on my Windows 10. However, the folder structure is different from the tutorial when I download the desktop docker, so I'll add extra information about how I construct the setting. The construction is using Make with docker:
postgres:
docker run --name postgreslatest -p 5432:5432 -e POSTGRES_USER=root -e POSTGRES_PASSWORD=secret -d postgres
createdb:
docker exec -it postgreslatest createdb --username=root --owner=root simple_bank
dropdb:
docker exec -it postgreslatest dropdb simple_bank
migrateup:
migrate -path db/migration -database "postgresql://root:secret#localhost:5432/simple_bank?sslmode=disable" -verbose up
migratedown:
migrate -path db/migration -database "postgresql://root:secret#localhost:5432/simple_bank?sslmode=disable" -verbose down
.PHONY: postgres createdb dropdb migrateup migratedown
Any help is appreciated.
I got it working. First of all, I still have no idea why bash command cannot correctly locate the sqlc.yaml file. However, under Windows 10 OS, I succeeded locate and generating files with the command provided by docs.
The command is: docker run --rm -v "%cd%:/src" -w /src kjconroy/sqlc generate using ONLY CMD and the command also works combined with the MakeFile.

why do i keep seeing nginx index.html on localhost when i run my docker image

I installed and run nginx on my linux machine to understand the configurations etc. After a while i decided to remove it safely by following this thread in order to use it in docker
By following this documentaion i run this command
sudo docker run --name ngix -d -p 8080:80 pillalexakis/myrestapi:01
And i saw ngix's homepage at localhost
Then i deleted all ngix images & stopped all containers and i also run this command
sudo docker system prune -a
But now restarted my service by this command
sudo docker run -p 192.168.2.9:7777:8085 phillalexakis/myfirstapi:01 and i keep seeing at localhost ngix index.html
How can i totally remove it ?
Note: I'm new with docker and i might have missed a lot of things. Let me know what extra docker commands should i run in order provide better information.
Assuming your host have been preparing as below
your files (index.html, js, etc) under folder - /myhost/nginx/html
your nginx configuration - /myhost/nginx/nginx.conf
Solution
map your files (call volume) on the fly from outside docker image via docker cli
This is the command
docker run -it --rm -d -p 8080:80 --name web \
-v /myhost/nginx/html:/usr/share/nginx/html \
-v /myhost/nginx/nginx.conf:/etc/nginx/nginx.conf \
nginx
copy your files into docker image by build your own docker image via Dockerfile
This is your Dockerfile under /myhost/nginx
FROM nginx:latest
COPY ./html/index.html /usr/share/nginx/html/index.html
This is the command to build your docker image
cd /myhost/nginx
docker build -t pillalexakis/nginx .
This is the command to run your docker image
docker run -it --rm -d -p 8080:80 --name web \
pillalexakis/nginx

Docker how to pass a relative path as an argument

I would like to run this command:
docker run docker-mup deploy --config .deploy/mup.js
where docker-mup is the name the image, and deploy, --config, .deploy/mup.js are arguments
My question: how to mount a volume such that .deploy/mup.js is understood as the relative path on the host from where the docker run command is run?
I tried different things with VOLUME but it seems that VOLUME does the contrary: it exposes a container directory to the host.
I can't use -v because this container will be used as a build step in a CI/CD pipeline and as I understand it, it is just run as is.
I can't use -v because this container will be used as a build step in a CI/CD pipeline and as I understand it, it is just run as is.
Using -v to expose your current directory is the only way to make that .deploy/mup.js file inside your container, unless you are baking it into the image itself using a COPY directive in your Dockerfile.
Using the -v option to map a host directory might look something like this:
docker run \
-v $PWD/.deploy:/data/.deploy \
-w /data \
docker-mup deploy --config .deploy/mup.js
This would map (using -v ...) the $PWD/.deploy directory onto /data/.deploy in your container, set the current working directory to /data (using -w ...), and then run deploy --config .deploy/mup.js.
Windows - Powershell
If you're inside the directory you want to bind mount, use ${pwd}:
docker run -it --rm -d -p 8080:80 --name web -v ${pwd}:/usr/share/nginx/html nginx
or $pwd/. (forward slash dot):
docker run -it --rm -d -p 8080:80 --name web -v $pwd/.:/usr/share/nginx/html nginx
Just $pwd will cause an error:
docker run -it --rm -d -p 8080:80 --name web -v $pwd:/usr/share/nginx/html nginx
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to
delimit the name
Mounting a subdirectory underneath your current location, e.g. "site-content", $pwd/ + subdir is fine:
docker run -it --rm -d -p 8080:80 --name web -v $pwd/site-content:/usr/share/nginx/html nginx
In my case there was no need for $pwd, and using the standard current folder notation . was enough. For reference, I used docker-compose.yml and ran docker-compose up.
Here is a relevant part of docker-compose.yml.
volumes:
- '.\logs\:/data'

Understanding code executed after run command in Docker

I just saw the below script in the Docker doc's.
$ docker restart db
db
$ docker run -t -i --rm --link db:db training/webapp /bin/bash
root#aed84ee21bde:/opt/webapp# cat /etc/hosts
172.17.0.7 aed84ee21bde
. . .
172.17.0.9 db
What is happening after the run cammand is executed ? , the below part i mean:
root#aed84ee21bde:/opt/webapp# cat /etc/hosts
Can somebody explain this line by line, I fail to understand. Please this is really important to me.
docker run -t -i --rm --link db:db training/webapp /bin/bash
This line executes the command /bin/bash in a container created from the image training/webapp. /bin/bash is an interactive shell, and so executing it means that you're now in a shell inside the fake machine that is the Docker container. root#aed84ee21bde:/opt/webapp# is the shell's prompt, indicating that you are root on host aed84ee21bde with current directory /opt/webapp. cat /etc/hosts means the same thing here that it does outside the container, except that here it's referring to the /etc/hosts file inside the container, which is likely different from the one on your main system.

Resources