Passing arguments to docker swarm containers - docker

I have three servers in a Docker Swarm cluster (1 master and 2 nodes).
I want to start containers that execute a command which has an incremental value.
Doing that from bash simply using Docker was very easy:
for i in `seq 1 6`;
do
sudo docker run --cpuset-cpus="$i" -d -v /tmp/out:/data_out -t -i image /binary $i
done
As you can see I'm starting several containers each one using a specific CPU id and passing the same id as argument to a binary which is within the container.
How can I do the same but using my Docker Swarm cluster?
Thank you

Related

"docker stack deploy": where are docker images?

I created a docker compose *.yml file where I have many services with specified image tags. Then I let docker deploy a stack for me (on my local machine) with docker stack deploy -c .\my-compose-file.yml --with-registry-auth dev and it is able to run all services. When I have docker events running simultaneously, I can see image pull messages in the log, so docker pulls missing images. But when I run docker image ls -a, the pulled images are not displayed here.
So I wondering and want to know, what live cycle do the downloaded images have (will then be removed from my drive when I do docker stack rm or not), and when not, how do I clean up such images?
I assume you have multi-node swarm configured. In such cases, the docker image ls is running in your local machine only, while the containers from the stack are distributed across nodes. The images are pulled on the nodes that will run the container.
To get the list of the containers, you will need to go to each member of the swarm and issue the command. Easy way to do it is to use, assuming you have ssh access to the nodes with identity key:
docker node ls | cut -c 31-49 | grep -v HOSTNAME | xargs -I"SERVER" sh -c "echo SERVER; ssh SERVER /usr/local/bin/docker image ls -a"

How to see the docker state instead of interacting with the shell?

I use following command to build web server
docker run --name webapp -p 8080:4000 mypyweb
When it stopped and I want to restart, I always use:
sudo docker start webapp && sudo docker exec -it webapp bash
But I can't see the server state as the first time:
Digest: sha256:e61b45be29f72fb119ec9f10ca660c3c54c6748cb0e02a412119fae3c8364ecd
Status: Downloaded newer image for ericgoebelbecker/stackify-tutorial:1.00
* Running on http://0.0.0.0:4000/ (Press CTRL+C to quit)
How can I see the state instead of interacting with the shell?
When you use docker run, the default behavior is to run the container detached. This runs in the background and is detached from your shell's stdin/out.
To run the container in the foreground and connected to stdin/out:
docker run --interactive --tty --publish=8080:4000 mypyweb
To docker start a container, similarly:
docker start --interactive --attach [CONTAINER]
NB --attach rather than -tty
You may list (all add --all) running containers:
docker container ls
E.g. I ran Nginx:
CONTAINER ID IMAGE PORTS NAMES
7cc4b4e1cfd6 nginx 0.0.0.0:8888->80/tcp nostalgic_thompson
NB You may use the NAME or any uniquely identifiable subset of the ID to reference the container
Then:
docker stop nostalgic_thompson
docker start --interative --attach 7cc4
You may check the container's logs (when running detached or from another shell) by grabbing the container's ID or NAMES
docker logs nostalgic_thompson
docker logs 7cc4
HTH!
Using docker exec is causing the shell to attach to the container. If you are comparing the behavior of docker run versus docker start, they behave differently, and it is confusing. Try this:
$ sudo docker start -a webapp
the -a flag tells docker to attach stdout/stderr and forward signals.
There are some other switches you can use with the start command (and a huge number for the run command). You can run docker [command] --help to get a summary of the options.
One other command that you might want to use is logs which will show the console output logs for a running container:
$ docker ps
[find the container ID]
$ docker logs [container ID]
If you think your container's misbehaving, it's often not wrong to just delete it and create a new one.
docker rm webapp
docker run --name webapp -p 8080:4000 mypyweb
Containers occasionally have more involved startup sequences and these can assume they're generally starting from a clean slate. It should also be extremely routine to delete and recreate a container; it's required for some basic tasks like upgrading the image underneath a container to a newer version or changing published ports or environment variables.
docker exec probably shouldn't be part of your core workflow, any more than you'd open a shell to interact with your Web browser. I generally don't tend to docker stop containers, except to immediately docker rm them.

How to run docker image as singleton

I'm new to docker.
I have an image that I want to run, but I want docker to see if that image is already running from another terminal...if it is running I don't want it to load another one...
is this something that can be done with docker?
if it helps, I'm running the docker with a privileged mode.
I've tried to search for singleton docker or something like that, but no luck.
updates-
1.working from ubuntu.
My scenario- from terminal X I run docker run Image_a
from terminal Y I run docker run Image_a
when trying to run from terminal Y, I want docker to check if there is already a docker running with Image_a, and the answer is true - I want docker not to run in terminal Y
You can use the following docker command to get all containers that running from specific image:
docker ps --filter ancestor="imagename:tag"
Example:
docker ps --filter ancestor="drone/drone:0.5"
Example Output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fb00087d4c1 drone/drone:0.5 "/drone agent" 6 days ago Up 26 minutes 8000/tcp drone_drone-agent_1
This approach uses docker api and docker daemon, so it doesnt matter if the run command executed in background or other terminal.
Aother approach:
If you have a single container form a single image:
Try naming your containers, You cant have 2 containers with the same name:
docker run --name uniquecontainer Image_a
Next time you run the above command you will get an error. Btw consider using -d so you dont have to switch terminals.
docker run -d --name uniquecontainer Image_a

'docker ps' and 'docker-compose ps' commands give different result

docker ps is giving me a different output compared to docker-compose ps.
For example
docker ps
is not showing the same containers as
docker-compose ps
and vice-versa.
What is the reason for this?
I was thinking docker-compose is working on top of docker.
docker ps lists all running containers in docker engine. docker-compose ps lists containers related to images declared in docker-compose file.
The result of docker-compose ps is a subset of the result of docker ps.
docker ps - lists all running containers in Docker engine.
docker-compose ps - lists containers for the given docker compose configuration. The result will depend on configuration and parameters passed to docker-compose command.
Example
Start the containers with the following command:
docker-compose -p prod up -d
(-p in the command above defines the project name)
Running docker-compose ps won't list containers since the project name parameters is not passed:
docker-compose ps
Name Command State Ports
------------------------------
Running docker-compose -p prod ps will list all containers:
Name Command State Ports
--------------------------------------------------------------------------------------------------------
dev_app_1 sh -c exec java ${JAVA_OPT ... Up 0.0.0.0:5005->5005/tcp, 0.0.0.0:9001->9000/tcp
dev_database_1 docker-entrypoint.sh postgres Up 0.0.0.0:5432->5432/tcp
dev_nginx_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:8443->443/tcp, 0.0.0.0:8080->80/tcp
dev_pgadmin_1 /entrypoint.sh Up 443/tcp, 0.0.0.0:9100->80/tcp
The same goes if you define for example docker compose files with -f parameter.

How to properly start Docker inside Jenkins that is also running in Docker

I'm trying to run Docker inside a Jenkins container that is also running in Docker (i.e. Docker in Docker). What I want to know is how to properly start the Docker service when booting Jenkins. The only solution I've found today is to build my own Jenkins image based on the official Jenkins image but change the jenkins script loaded by the entry point to also start up Docker:
# I've added this line just before Jenkins is started from the script:
sudo service docker start
# I've also removed "exec" from the original file which used "exec java $JAVA_TOPS ..." but that didn't work
java $JAVA_OPTS -jar /usr/share/jenkins/jenkins.war $JENKINS_OPTS "$#"
This works when I run (using docker run) a new container but the problem is that if I do (docker start) on stopped container the Docker service is not started.
I strongly suspect that this is not the right way to start my Docker service. My plan is to perhaps use supervisord to start Jenkins and Docker separately (I suppose container linking is out of the question since Docker should be executed as a service on the same container that Jenkins is running on?). My concern with this approach is that I'm going to lose the EntryPoint specified in the Jenkins Dockerfile which allows me to pass arguments to the Jenkins container when starting the container, for example:
docker run -p 8080:8080 -v /your/home:/var/jenkins_home jenkins -- <jenkins_arguments>
Does anyone have any recommendations on a good way to solve this preferably by not forking the official Jenkins image?
I'm pretty you cannot do that.
Docker in Docker doesn't mean you have to run docker inside docker with 3 level : host > First level container > Second Level Container
In fact, you just need to share docker with host, and this is your host who will run others containers.
To do that, you have to mount volume with -v parameter
-v /var/run/docker.sock:/var/run/docker.sock
with this command, when you will docker run inside you jenkins container, the docker client will communicate with docker deamon from your host in order to run new container.
To do that, you should run your jenkins container with privileged
--privileged
To resume, here is the full command line
docker run -d -v /var/run/docker.sock:/var/run/docker.sock --privileged myimage
And you you don't need to create a new jenkins image for that.
Hoping to have helped you
http://container-solutions.com/running-docker-in-jenkins-in-docker/

Resources