Copy files from a stopped container
First, you need to find it. On your system, stopped containers are
included in the docker ps
list if you add --all
:
$ docker ps --all
CONTAINER ID IMAGE COMMAND CREATED
bb72360b919e foo "/usr/bin/foo" 12 minutes ago
Now, use the container id to copy the files you need:
$ docker cp bb72360b919e/var/log/foo.log /tmp
The syntax is similar to that of scp
, except that you don't add a
colon after the hostname.
Docker networking doesn't work
Possibility #1 - you've changed network access on the host
You've changed network configuration on your laptop and the dockerd
hasn't been restarted.
I've found that if I change from e.g. wired to wireless on my laptop,
the outgoing network traffic from all docker containers is
broken. I've so far found no better way of remedying this than to
restart the dockerd
and thus restarting the docker containers, since
they are all children of dockerd
:
# ifdown eth0
# ifup wlan0
# service docker restart
Possibility #2 The firewall doesn't contain the docker hooks
Docker sets up a lot of networking for you "magically". For instance,
the EXPOSE
directives in the Dockerfile
s and the docker run
--publish
parameter will set up network routing so that it's possible
for the host machine (and the outside world if it allows for this) to
access services listening on various ports inside the
container. Likewise, Docker ensures that one container can access the
services on another container by the docker run --name
parameter.
For all of this to work, docker must have some pre-defined hooks in
your firewall setup. These hooks are called chains
in the iptables
Linux firewall.
To ensure that the Docker firewall chains exists, run the following command:
# iptables -L | grep -i docker
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
DOCKER all -- anywhere anywhere
Chain DOCKER (2 references)
Chain DOCKER-ISOLATION (1 references)
Chain DOCKER-USER (1 references)
If nothing is returned, you need to set up these chains so that Docker can do its magic.
These chains are set up with the /etc/init.d/docker
script from the
docker-ce
package on Debian systems. If the don't exist (perhaps
you've flushed your iptables
rules?), try to restart the init.d
script. The chains should be re-created each time the script runs.
Viewing logs
It seems to be the "Docker way" to only have one log per container and that log should be redirected to standard out so that Docker's logging framework can pick it up.
To see the standard out log of a container, do:
$ docker logs -f <id>
To see the log of a named container, use docker ps
first and ask it
to filter on name, gluu-oxtrust
in my case:
$ docker logs -f $(docker ps -qf "name=gluu-oxtrust")
Skybert: what if the container has multiple log files and their difference carries significance?
Skybert: how to see the standard error log? (
/dev/stderr
)
Logging into a container by name
Here, I have a container with name gluu-oxtrust
and I want to log
into it (which of course is a lie, there's no logging into containers,
they're running the host machine, but hey, let's pretend, shall we?):
$ docker exec -ti $(docker ps -qf "name=gluu-oxtrust") /bin/bash
Since I do this all the time, I've created
drshell
which does the above, allowing me to type: drshell <name>
.
Overview of container IPs and ports exposed
$ drps
CONTAINER ID IMAGE CREATED IP PORTS NAMES
9ddf7adcb85d gluufederation/nginx:latest 2018-02-28T13:44:14 172.18.0.5 map[443/tcp:[map[HostIp:0.0.0.0 HostPort:8085]] 80/tcp:[map[HostIp:0.0.0.0 HostPort:8084]]] /gluu-nginx
1f879a8c1145 gluufederation/oxtrust:latest 2018-02-28T13:44:13 172.18.0.4 map[8080/tcp:[map[HostIp:0.0.0.0 HostPort:9981]]] /gluu-oxtrust
53003952bb7b gluufederation/oxauth:latest 2018-02-28T13:44:13 172.18.0.3 map[8080/tcp:[map[HostPort:9980 HostIp:0.0.0.0]]] /gluu-oxauth
b524850b3af2 gluufederation/openldap:latest 2018-02-28T13:44:12 172.18.0.2 map[1389/tcp:<nil>]
Since docker ps
doesn't output the IP of the containers, I've
extended a snippet I found on the web to do it:
drps
Exposing a container's port to the world
When you use docker run --publish
or use the ports:
directive in
docker-compose.yaml
, docker
manipulates the firewall rules so that
requests from the outside world hits your container(s) on your
machine's local docker network.
You can see this with iptables
:
# iptables -t nat -L -n
[..]
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8600 to:172.18.0.6:8600
DNAT udp -- 0.0.0.0/0 0.0.0.0/0 udp dpt:8600 to:172.18.0.6:8600
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8500 to:172.18.0.6:8500
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8400 to:172.18.0.6:8400
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9005 to:172.18.0.11:9005
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:9006 to:172.18.0.12:9006
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8681 to:172.18.0.13:8681
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8680 to:172.18.0.13:8680
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:443 to:172.18.0.14:443
hDNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.18.0.14:80
Here can you e.g. see that TCP connections to port 80
are redirected
to the 80
port on the container listening on 172.18.0.14
. To see
which container this is, you can do:
$ docker ps -q | xargs docker inspect --format='{{printf "%.12s" .Id}} {{.Name}} {{range $net, $conf := .NetworkSettings.Networks}}{{$conf.IPAddress}}{{end}}'
1fce6f177878 /docker_um_1 172.18.0.14
e090e4a7b24f /docker_cue_um_1 172.18.0.13
640209ed51f5 /docker_oxtrust_1 172.18.0.12
9ade8895cfee /docker_oxauth_1 172.18.0.11
3e56c960f227 /docker_ldap_1 172.18.0.10
c6a65e34acbd /docker_redis_1 172.18.0.8
2f0e8d5724dc /docker_consul_1 172.18.0.6
180e1335d460 /docker_consul-server-1_1 172.18.0.7
0ba6a1514df2 /docker_consul-agent-2_1 172.18.0.5
9333f66d802a /docker_consul-server-2_1 172.18.0.4
72add9eb3ab0 /docker_consul-agent-1_1 172.18.0.3
0c973a09bccf /docker_consul-agent-3_1 172.18.0.2
We now know that requests to port 80
on the host machine is routed
to port 80
on container 1fce6f177878
with name docker_um
.
Copy a file from the host machine to a running Docker container
$ docker cp tmp/n.class cdde6a98ba79:/tmp/n.class
Where cdde6a98ba79
is the Docker ID of the running container, as
seen with e.g. docker ps
.