Let's say you're on Windows and you want to mount a volume like so:
docker run --name nginx -v "C:\\my\\path:/usr/share/nginx/html" -p "8080:80" nginx
This works perfectly with Docker Desktop, which uses WSL2.
However, with a custom Docker in WSL2, you'll get:
docker: Error response from daemon: invalid mode: /usr/share/nginx/html.
There are some questions covering this topic:
Docker on Windows without Docker Desktop volume mounting
Docker Desktop for Windows, having trouble w/ -v bind mount
How do you create a bind mount in Docker when running with the WSL2 backend?
Their bottom line is: Use /mnt/c/.... But Docker Desktop doesn't need this. When you inspect a container created by Docker Desktop, you'll even see:
"Mounts": [
{
"Type": "bind",
"Source": "C:\\my\\path",
"Destination": "/usr/share/nginx/html",
"Mode": "rw",
"RW": true,
"Propagation": "rprivate"
}
],
How is it possible that Docker Desktop's WLS2 Docker daemon can handle Windows paths?
Related
I'm testing to see if two containers (tomcat and busybox) in a same network 'myNetwork' are able to communicate with each other.
I followed the steps:
Create a network, 'myNetwork'
docker network create -d bridge myNetwork
Run a 'myTomcat' container in 'myNetwork'
docker run -it --name myTomcat --net=myNetwork tomcat
Run a 'busybox' container in the same network as 'myTomcat' network. i.e 'myNetwork'
docker run -it --net=container:myTomcat busybox
Test if tomcat container is accessible from busybox container using wget command
docker container exec -it {busybox_container_id}
/# wget localhost:8080
Here I I got an error wget: server returned error: HTTP/1.1 404
I wonder why I can't connect to tomcat container from busybox container even though I configured both containers in the same network.
So I inspected by doing:
docker network inspect myNetwork
[
{
"Name": "myNetwork",
...
"Containers": {
"43ba4d7ae27753f8085f5697cf6afc4eb872dbdbd2cf18138e3c6e3f90d54d15":{
"Name": "myTomcat",
"EndpointID":"03a98...",
...
"IPv4Address": "172.20.0.2/16",
"IPv6Address": ""
}
}
]
docker inspect {tomcat_container_id}
[
...
"Networks": {
"myNetwork": {
"NetworkID": "54bf...",
...
"Gateway": "172.20.0.1",
"IPAddress": "172.20.0.2"
...
}
...
]
docker inspect {busybox_container_id}
[
...
"NetworkSettings": {
"Bridge": "",
...
"Networks": {}
}
...
]
It seems tomcat is in 'myNetwork', but inspecting busybox container doesn't seem to show any network information. I'd appreciate for any help
Using localhost always point to the current machine. Using it in a Docker container targets the current container.
If you need your containers to communicate in a Docker network you can make use of the embedded DNS server by using container names as host names. As you named your Tomcat container myTomcat you should be able to do:
wget myTomcat:8080
For implementing integration tests for a project that I'm working on, there's a requirement to run integration tests by spinning up services as docker containers. So there are 2 services that stay in a fixed state through out the tests and those services are added into a docker-compose file. I am starting those services at the beginning of the tests. After that for a group of tests, I need to start another service using docker run command and add that service into the same network that is created when I start the previous 2 services as docker-compose. Is that possible ?
I tried the following steps to ensure that adding a docker container to a network created by docker-compose is possible or not.
Sample docker-compose file.
version: '3.7'
services:
backend_service_1:
image: solsson/http-echo
networks:
- envoymesh
environment:
- PORT=8000
networks:
envoymesh:
name: envoymesh
driver: bridge
Run another docker container and try to add to the same network.
docker run solsson/http-echo -e PORT=9000 --network=envoymesh --driver=bridge
Run docker network inspect envoymesh to see the containers in the network. But I'm seeing only the container from the docker-compose.
"Containers": {
"bd3c1b20be141cc66144f24a7e7adeaaa894e694004139f88f2b9563c729e8e1": {
"Name": "docker-network_backend_service_1_1",
"EndpointID": "d43f97ef5f0948ed2f6c7e4045164439ebf2596176868efcf6640927c1bc376e",
"MacAddress": "02:42:ac:1b:00:02",
"IPv4Address": "172.27.0.2/16",
"IPv6Address": ""
}
},
What am I doing wrong here ? Is it possible to achieve my requirement ?? Thanks in advance.
PS: docker network connect envoymesh [container id] works.
Solution
It was a issue with the way that I was using the docker run command. It should be used like follows with image name at the end.
docker run -e PORT=8000 --network envoymesh solsson/http-echo
I'm not sure why the docker run command doesn't work but have you tried this:
docker network connect envoymesh container-name
Command format:
docker network connect [OPTIONS] NETWORK CONTAINER
Description:
Connects a container to a network. You can connect a container by name or by ID. Once connected, the container can communicate with other containers in the same network.
Source: network connect
I know that Docker Compose (compose) is a tool that among other things makes setting up interconnectivity between containers much easier, but I am trying to practice doing that without compose to see what that process is like (and gain a deeper appreciation for compose in the long run).
Is the reason it is hard to run an app (in my case rails) + a sql server without compose because they are isolated units, so they don't know about each others file system and so don't know how to locate one another and that's why we use compose? Is there another reason?
How would you approach connecting the containers without using compose? If it's helpful I posted some metadata about the two containers below.
When run docker inspect on my postgres container I see an ENV and network config of:
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/postgresql/12/bin",
"PGDATA=/var/lib/postgresql/data"
]
"Networks": {
"bridge": {
"NetworkID": "e68fdafe2110067389853515b05b09cd0ce75c500190fae85abff82417794b7f",
"EndpointID": "0d5564c073286bf7c1d708d52146653cf75705f34c1e175963eba4c158424399",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"MacAddress": "02:42:ac:11:00:02",
}
}
And for the rails container:
"Env": [
"PATH=/usr/local/bundle/bin:/usr/local/bundle/gems/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
]
"Networks": {
"bridge": {
"NetworkID": "e68fdafe2110067389853515b05b09cd0ce75c500190fae85abff82417794b7f",
"EndpointID": "e76ad694f04b7ca07e388ab39ab81b00409500d4c175b5ce9f90a8c740da7246",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.3",
"MacAddress": "02:42:ac:11:00:03",
}
}
Docker compose is handy when you have bunch of containers and you want to start/stop whole environment by using single commands like docker-compose up or docker-compose down. And as you noted it also creates some common stuff to help containers talk to each other - like networks.
If you want to make it hard to yourself you can always not use compose and start your containers manually and connect them to a common network :
docker network create mynetwork
this will create a network named mynetwork with default bridge driver.
Next you will have to run your containers and connect them to this network :
docker container run --network mynetwork --name container1 image1
docker container run --network mynetwork --name container2 image2
and this is similiar to what compose is doing - you can access those containers over this network by DNS names - container1 and container2.
I am new to docker and I'm trying to get a permanent installation of Rancher started. To create the docker container I run the following command:
docker run -d --name rancher-server -p 8080:8080 rancher/server
Note that I want to forward the container's 8080 port to my hosts' 8080, since 80 is occupied by nginx on my host.
Now, when I stop the above container and try to start it again using docker start <Container ID> I get the following error:
Error response from daemon: driver failed programming external connectivity on endpoint rancher-server (c18940f957ed1f737fd5453ea29755adea762d758643a64984d5e3ce8bd3fdbe): Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use
Error: failed to start containers: c93794a8c0ad
I know that this happens since nginx is using port 80, so my question is how do I start my existing container and tell it to forward its ports?
Running docker start -d -p 8080:8080 c93794a8c0ad gives me the following error: unknown shorthand flag: 'd' in -d
So how do I start a container with forwarded ports? Thank you!
The problem might be that two programs are working on the same port.
You can change the port settings when you are running the docker run command.
For instance, you can bind port 8080 of the container with an arbitrary port on your computer, like 8081:
docker run -d --name rancher-server -p 8081:8080 rancher/server
The left-hand port number is the docker host port - your computer - and the right-hand side is the docker container port.
You CAN modify the ports
You can change the ports of a docker container without deleting it. The way quin452 puts it - with minor revision:
Get the container ID:
docker ps -a
Stop the container:
docker stop [container name]
Edit the container hostconfig.json file, found at
var/lib/docker/containers/[container ID]/hostconfig.json
Within the PortBindings section,
either edit the existing HostPort to the port you would like,
or add them yourself (see below)
Save and exit the config file
Restart docker:
sudo systemctl restart docker
Start up the container:
docker start [container name]
An example config file:
"PortBindings": {
"3306/tcp": [
{
"HostIp": "",
"HostPort": "23306"
}
],
"443/tcp": [
{
"HostIp": "",
"HostPort": "2443"
}
],
"80/tcp": [
{
"HostIp": "",
"HostPort": "280"
}
]
}
I deleted the container and created a new one with the command the Rancher docs recommend sudo docker run -d --restart=unless-stopped -p 8080:8080 rancher/server and now stopping and starting the container work as expected, on the correct ports. I don't know what the problem was before, but it now works.
To change port mappings, you need to delete and recreate the container. So docker rm your existing container then docker run it with the new port settings.
try to use the following
$docker run -d --name rancher-server -p 8080:80 rancher/server
I am running Docker Toolkit 1.9.1 on windows 10 64bit, and I am trying to look at the james turnbull book and a simple build up example site.
In a Docker shell, I have created a directory dockerBuilds. In that directory, I created another directory called my-tomcat.
I cd into that directory and run touch Dockerfile. I then created a simple docker build file like this
# start from base image
FROM library/tomcat
MAINTAINER Will Woodman "will.woodman#btinternet.com"
from this I build my image with
docker build -t my-tomcat .
When I start a container with
docker run --name tomcatApp -i -p 8080:8080 my-tomcat
I can see the log trace as tomcat starts up, and when it is settled, connections to http://localhost:8080 fails with Chrome or other browsers.
I stopped and removed the container and then tried:
docker run --name tomcatApp -i -p 127.0.0.1:8080:8080 my-tomcat
and get the same problem.
I even tried to connect to the default docker vm by pointing the browser to http://192.168.99.100:8080, and still can't connect.
So I must be doing something wrong but I don't know what. The logs look fine and the server says it is up. but I'm not seeing any connection when I browse. docker stats tomcatApp shows container is running.
What am I missing here for the port mappings from my windows localhost to the containers ports?
I see this using docker inspect - which looks ok to me
"NetworkSettings": {
"Bridge": "",
"SandboxID": "7c58e33e5d3821fc8a1dc6bb6957031d11e07c04bf34f8aa7b17f8afeff03700",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"8080/tcp": [
{
"HostIp": "127.0.0.1",
"HostPort": "8080"
}
]
},
What am I doing wrong?
If you are using docker-machine and try to contact localhost, you would need to add "Port forwarding in docker-machine?"
either port forward the 8080port on the VirtualBox level (meaning localhost:8080 will work)
VBoxManage controlvm "boot2docker-vm" natpf1 "tcp-port5000,tcp,,8080,,8080";
or use the ip returned by $(docker-machine ip <yourMachine>)
And don't use -p 127.0.0.1:8080:8080, but -p 8080:8080: 127.0.0.1 refers to the localhost of the VirtualBox, not of your host (Windows).
Build image and Run container as
$ docker build tomcatApp .
$ docker run -p 8080:8080 -t tomcatApp
Hit given command to find IP address of docker-machine
$ docker-machine ls
The output will be like :
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default * virtualbox Running tcp://192.168.99.100:2376 v1.10.3
Now run your application from host machine as :
http://192.168.99.100:8080/myapp