Docker - Retrieve command line from an image - command-line

I'd like to know if there is a way to retrieve the "docker run" command which started a container ?
Because I'd like to add some parameters to a stopped container, I need to retrieve the original command, add my new parameters and start it.
Thank you for your help.

If the only thing you want to change is the restart policy, you can now (in docker engine 1.11) use docker-update. docker-update can be applied to either a running or a stopped container, see man docker-update, eg:
# docker update --restart=unless-stopped containername
Some useful info is available in the output of docker ps, notably the port mappings, eg:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
75d1e6adbb37 my-fancy-image "/usr/sbin/sshd -D" 22 hours ago Up 22 minutes 0.0.0.0:8022->22/tcp fancy_torvalds
All the other command-line parameters that were used to start the container can be found in the output of docker inspect, eg:
# docker inspect containername
...
"Path": "/usr/sbin/sshd",
"Args": [
"-D"
],
...
"HostConfig": {
"Binds": [
"/home/user/workspace/thing:/home/other/workspace/thing"
],
...
"PortBindings": {
"22/tcp": [
{
"HostIp": "",
"HostPort": "8022"
}
]
},
"RestartPolicy": {
"Name": "unless-stopped",
"MaximumRetryCount": 0
},
...
If it isn't just the restart policy you want to change (and you do have application data inside your container) you can save the container as an image, then run it as a new container. This should use no significant additional disk space. You don't need to push it to any repository:
# docker commit -m="Message" -a="Author Name" containername username/imagename:latest
# docker run <new options here> username/imagename:latest
I have to question why you want to do this at all. Do you have all your application data contained inside the same container as the application itself, making you reluctant to just delete the container and spin up a new one with your preferred options? There are many excellent discussions on this subject to be found, notably:
How to deal with persistent storage (e.g. databases) in docker
How to upgrade docker container after its image changed
Manage data in containers

Related

How to reconnect to same postgres database on Docker

I'm very new to using docker and I've created a postgres container using
docker run --name mytrainingdb -e POSTGRES_PASSWORD=mysecretpassword -d postgres. Then I connected to it with docker exec -it <container-id> bash and then psql.
Then I stop the container.
My query is, what do I do reconnect to the same database? I tried to run same docker run command, but it says the name 'mytrainingdb' is used, which means it is trying to create it afresh, which is not what I want. Hope my expectation is right, as in when I restart my laptop or resume work I can just restart the same container and my data/config would be preserved?
The documentation also mentions that we can link a host directory to volume of pg container to have the stored data accessible to us, but I'm ok with docker managing my storage for that database.
You will have error when you try to re-run the same command, because docker is trying to create a new container with same name as the previous one "mytrainingdb". If you close docker and reopen it you will still find your container , but its not running , you can start it again with docker start mytrainingdb or you can remove it with docker rm mytrainingdb .
However , dont restart docker because you want to create a new container with the same name! If you want to start a new container with the same name and your container is still running you can first stop it with docker stop mytrainingdb and docker rm mytrainingdb or you can just do docker rm -f mytrainingdb (this will remove you running container with force ) and then create a new container..
As for the volumes ,you just created one by default which is named is kind of hash , and its found at volumes/var/lib/docker/volumes/ .Because generally containers such PostgreSQL, or databases in general persists volumes. The volume gets created when running the container and is handy to save persistent data, whether you start the container with -v or not.
The volume you talked about in your question , is called mounted volume , is when you basically just bind a certain directory or file from the host (outside) to inside the container
docker run -v /hostdir:/containerdir in your case docker run -v /hostdir:/var/lib/postgresql/data
If you restart docker or your computer running containers won't be automatically restarted. You can start your container again with docker start mytrainingdb (related question), then connect with your docker exec command.
(one tip: instead of running bash, then psql, you can directly run psql, e.g. docker exec -it mytrainingdb psql --user postgres)
Your understanding of data persistence is correct, docker will manage the data and it will still be around.
From the postgres image documentation
There are several ways to store data used by applications that run in Docker containers. We encourage users of the postgres images to familiarize themselves with the options available, including:
Let Docker manage the storage of your database data by writing the database files to disk on the host system using its own internal volume management. This is the default and is easy and fairly transparent to the user. The downside is that the files may be hard to locate for tools and applications that run directly on the host system, i.e. outside containers.
You can add --rm argument so that whenever you stop the container manually, or container stops for any reasons (his task is done or it fails), it will remove that container.
In your case, you can use this:
docker run --name mytrainingdb --rm -e POSTGRES_PASSWORD=mysecretpassword -d postgres

ECS + EFS - files never make their way out of the container

I'm trying to do a POC with ECS + EFS (MySQL for a personal site), but the file changes to the mounted volume within docker don't make their way to EFS.
I have it mounted on the container host:
us-east-1a.fs-#####.efs.us-east-1.amazonaws.com:/ on /mnt/mysql-data-docker type nfs4 (rw,relatime,vers=4.0,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.0.0.128,local_lock=none,addr=10.0.0.90)
My task definition (relevant parts) shows:
"mountPoints": [
{
"containerPath": "/var/lib/mysql",
"sourceVolume": "mysql-data",
"readOnly": null
}
]
and
"volumes": [
{
"host": {
"sourcePath": "/mnt/mysql-data-docker"
},
"name": "mysql-data"
}
],
I can write a file there, terminate the host, have the new host come up via scaling group and get mounted, and the file is still there, so I know that's working (and EFS shows 12kb on that FS instead of 6kb).
Looking at the running MySQL container:
[ec2-user#ip-10-0-0-128 ~]$ docker inspect e96a7 | jq '.[0].Mounts'
[
{
"Source": "/mnt/mysql-data-docker",
"Destination": "/var/lib/mysql",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
/mnt/mysql-data-docker on the host only shows my test file I verified with. In the container, there's a bunch of stuff in /var/lib/mysql but it never makes its way to the host or to EFS.
Turns out its because:
If you're using the Amazon ECS-Optimized AMI or Amazon Linux AMI's docker packages, the Docker daemon's mount namespace is unshared from the host's at launch. Some other AMIs might also have this behaviour.
On any of those, a filesystem mount will not propagate to the Docker daemon until the next time it's restarted.
So running sudo service docker restart && sudo start ecs solved it.
When you startup an EC2 instance you can specify a "user data" script that is run at boot time, BEFORE the docker start up
In your case, something like this should work:
#cloud-boothook
#!/bin/bash
# Install nfs-utils
sudo yum install -y nfs-utils
# Mount EFS, writing the volume to fstab ensures it will automatically mount even on reboot
sudo mkdir -p /mnt/mysql-data-docker
sudo echo "us-east-1a.fs-#####.efs.us-east-1.amazonaws.com:/ /mnt/mysql-data-docker nfs4 nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2" >> /etc/fstab
sudo mount -a

Docker volume details for Windows

I am learning docker and deploying some sample images from the docker hub. One of them requires postgresql. When I deploy without specifying a volume, it works beautifully. When I specify the volume 'path on host', it fails with inability to fsync properly. My question is when I inspect the volumes, I cannot find where docker is storing those volumes. I'd like to be able to specify a volume so I can move the data if/when needed. Where does Docker store this on a windows machine? I tried enabling volume through Kinematic but the container became unusable.
> docker volume inspect 0622ff3e0de10e2159fa4fe6b7cd7407c6149067f138b72380a5bbe337df8f62
[
{
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/0622ff3e0de10e2159fa4fe6b7cd7407c6149067f138b72380a5bbe337df8f62/_data",
"Name": "0622ff3e0de10e2159fa4fe6b7cd7407c6149067f138b72380a5bbe337df8f62",
"Options": {},
"Scope": "local"
}
]
I can create a volume through docker but am not sure where it is stored on the harddisk.
If you're on windows 10 and use Docker For Windows, docker will create a VM and run it on your local hyper-v, the volumes you create are then located inside of this VM which is stored in something called MobyLinuxVM.vhdx (you can check it in the settings of docker).
One way to have your data on your host computer for now is to share a drive on docker settings and then map your postgres data folder to your windows hard drive.
Something like docker run -it -v /c/mypgdata:/var/lib/postgresql/data postgres
Another way would be to create a volume with a specific driver, take a look at existing volume drivers if one can do what you want.
This one could be of interest for you : https://github.com/CWSpear/local-persist
You can also enter the MobyLinux VM with this "kind of" hack
#get a privileged container with access to Docker daemon
docker run --privileged -it --rm -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker alpine sh
#run a container with full root access to MobyLinuxVM and no seccomp profile (so you can mount stuff)
docker run --net=host --ipc=host --uts=host --pid=host -it --security-opt=seccomp=unconfined --privileged --rm -v /:/host alpine /bin/sh
#switch to host FS
chroot /host
#and then go to the volume you asked for
cd /var/lib/docker/volumes/0622ff3e0de10e2159fa4fe6b7cd7407c6149067f138b72380a5bbe337df8f62/_data
Found here : http://docker-saigon.github.io/post/Docker-Beta/

How to set docker mongo data volume

I want to use Dockerizing MongoDB and store data in local volume.
But .. failed ...
It has mongo:latest images
kerydeMacBook-Pro:~ hu$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mongo latest b11eedbc330f 2 weeks ago 317.4 MB
ubuntu latest 6cc0fc2a5ee3 3 weeks ago 187.9 MB
I want to store the mono data in ~/data. so ---
kerydeMacBook-Pro:~ hu$ docker run -p 27017:27017 -v ~/data:/data/db --name mongo -d mongo
f570073fa3104a54a54f39dbbd900a7c9f74938e2e0f3f731ec8a3140a418c43
But ... it not work...
docker ps -- no daemon mongo
kerydeMacBook-Pro:~ hu$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
try to run "mongo" --failed
kerydeMacBook-Pro:~ hu$ docker exec -it f57 bash
Error response from daemon: Container f57 is not running
docker inspect mongo
kerydeMacBook-Pro:~ hu$ docker inspect mongo
[
{
"Id": "f570073fa3104a54a54f39dbbd900a7c9f74938e2e0f3f731ec8a3140a418c43",
"Created": "2016-02-15T02:19:01.617824401Z",
"Path": "/entrypoint.sh",
"Args": [
"mongod"
],
"State": {
"Status": "exited",
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 100,
"Error": "",
"StartedAt": "2016-02-15T02:19:01.74102535Z",
"FinishedAt": "2016-02-15T02:19:01.806376434Z"
},
"Mounts": [
{
"Source": "/Users/hushuming/data",
"Destination": "/data/db",
"Mode": "",
"RW": true
},
{
"Name": "365e687c4e42a510878179962bea3c7699b020c575812c6af5a1718eeaf7b57a",
"Source": "/mnt/sda1/var/lib/docker/volumes/365e687c4e42a510878179962bea3c7699b020c575812c6af5a1718eeaf7b57a/_data",
"Destination": "/data/configdb",
"Driver": "local",
"Mode": "",
"RW": true
}
],
If I do not set data volume, mongo image can work!
But, when setting data volume, it can't. Who can help me?
Try and check docker logs to see what was going on when the container stopped and go in "Existed" mode.
See also if specifying the full path for the volume would help:
docker run -p 27017:27017 -v /home/<user>/data:/data/db ...
The OP adds:
docker logs mongo
exception in initAndListen: 98
Unable to create/open lock file: /data/db/mongod.lock
errno:13 Permission denied
Is a mongod instance already running?
terminating 2016-02-15T06:19:17.638+0000
I CONTROL [initandlisten] dbexit: rc: 100
An errno:13 is what issue 30 is about.
This comment adds:
It's a file ownership/permission issue (not related to this docker image), either using boot2docker with VB or a vagrant box with VB.
Nevertheless, I managed to hack the ownership, remounting the /Users shared volume inside boot2docker to uid 999 and gid 999 (which are what mongo docker image uses) and got it to start:
$ boot2docker ssh
$ sudo umount /Users
$ sudo mount -t vboxsf -o uid=999,gid=999 Users /Users
But... mongod crashes due to filesystem type not being supported (mmap not working on vboxsf)
So the actual solution would be to try a DVC: Data Volume Container, because right now the mongodb doc mentions:
MongoDB requires a filesystem that supports fsync() on directories.
For example, HGFS and Virtual Box’s shared folders do not support this
operation.
So:
the mounting to OSX will not work for MongoDB because of the way that virtualbox shared folders work.
For a DVC (Data Volume Container), try docker volume create:
docker volume create mongodbdata
Then use it as:
docker run -p 27017:27017 -v mongodbdata:/data/db ...
And see if that works better.
As I mention in the comments:
A docker volume inspect mongodbdata (see docker volume inspect) will give you its path (that you can then backup if you need)
Per Docker Docs:
Volumes are the preferred mechanism for persisting data generated by and used by Docker containers.
docker volume create mongodbdata
docker run -p 27017:27017 -v mongodbdata:/data/db mongo
Via Docker Compose:
version: '2'
services:
mongodb:
image: mongo:latest
volumes:
- ./<your-local-path>:/data/db
/data/db is the location of the data saved on the container.
<your-local-path> is the location on your machine AKA the host machine where the actual database journal files will be saved.
For anyone running MongoDB container on Windows: as described here, there's an issue when you mount volume from Windows host to MongoDB container using path (we call this local volume).
You can overcome the issue using a Docker volume (volume managed by Docker):
docker volume create mongodata
Or using docker-compose as my preference:
version: "3.4"
services:
....
db:
image: mongo
volumes:
- mongodata:/data/db
restart: unless-stopped
volumes:
mongodata:
Tested on Windows 10 and it works
Found a link: VirtualBox Shared Folders are not supported by mongodb.

Howto persist MongoDB - data of a running Docker container in a new image?

i have a running Mongo DB Container called xyz from offical Mongo Image. i created the container with docker run -d -p 21707:21707 mongo
In this container i created 2 collections with sample data.
Now i want to extract this container in a new image on dockerhub.
I used docker commit and created a new image, pushed it on the docker hub. If i pull the image on a other system and create a new container from this image, there are no data like in my origin container xyz.
After research i found out that the mongo image could used with a volume, but i missed this step in the past... I think the container use /data/db as standard volume(docker inspect), on commit this volume is not attached to the new image?!
Also i tried docker export/import with the same problem mentioned above!
Now my Question, how could i reach to migrate this "xyz" running container with my sample data in a new image/container?
Thanks a lot!
I used docker commit and created a new image, pushed it on the docker hub. If i pull the image on a other system and create a new container from this image, there are no data like in my origin container xyz.
The mongo docker image writes its data into a volume. As a result, those data won't be saved to a new docker image created with docker commit. docker export won't produce your data for the same reason.
how could i reach to migrate this "xyz" running container with my sample data in a new image/container?
What you want is either:
create a new container re-using the first container's volume → see --volumes-from
save the first container's volume data into a directory on your docker host, and create a new container mounting this directory into the container → the docker run -v option
Also, this SO question might help you figure out volumes.
I wanted to make an image to test things around authentication and I has the same issue. I solved it this way:
Dockerfile
FROM mongo
COPY setup.sh /
RUN chmod +x /setup.sh
RUN /setup.sh
ENTRYPOINT ["/usr/bin/mongod"]
CMD ["--auth", "--dbpath=/containerdb"]
setup.sh
#!/bin/bash
mkdir containerdb
mongod --auth --dbpath=/containerdb &
until mongo admin --eval 'db.createUser({"user":"root", "pwd":"password", "roles": [ "root" ] })'
do
echo 'Mongo not yet ready, waiting 1 sec until retry'
sleep 1
done
mongod --shutdown --dbpath=/containerdb
Bim! When you run this image you have a mongodb with authentication activated and a root user.
The key is to workaround the VOLUME in the base Dockerfile by storing the data somewhere else.