I want to be able to get some information on the service file that created the docker process from the container id.
The flow:
fleetctl start myapp.service1
fleetctl start myapp.service2
fleetctl start myapp.service3
docker ps --no-trunc
for each container id on each record
find the service name it was created with
I would appriciate any solution or work around like set an environment variable using the service file, and pull it later on using the docker container id.
The easiest way to do this is with the container names. Have myapp1.service contain docker run --name myapp1 as the ExecStart and then you'll be able to find it with docker ps.
Related
When writing a bash script that starts a docker container, it is useful to refer to the started docker container. How do you get the specific container id of a docker container when you start it?
P.S. I know that I can use --name to name the container, which I can use to filter the list of containers using docker ps -aqf "name=containername", but this will fail if I ever start the script twice. And then there's the possibility of name conflicts. Besides, what's the point of container IDs if you can't use them?
When you start a detached container, it returns the container ID. e.g.:
$ docker run -d ubuntu:18.04
71329cf6a02d89cf5f211072dd37716fe212787315ce4503eaee722da6ddf18f
In bash, you can define a new variable from the output like this:
CID=$(docker run -d ubuntu:18.04)
Then, later you can use this variable to refer to your container like this:
docker stop $CID
docker rm $CID
In the documentation for docker run under "capture container id", they advise using the --cidfile flag for this purpose.
--cidfile takes a file name as an argument and will write the long ID of the container to that location. E.g.,
docker run --cidfile /tmp/hello-world.cid hello-world && cat /tmp/hello-world.cid
This is useful when you don't want to run the image in a detached state, but still want access to the ID.
I can view the list of running containers with docker ps or equivalently docker container ls (added in Docker 1.13). However, it doesn't display the user who launched each Docker container. How can I see which user launched a Docker container? Ideally I would prefer to have the list of running containers along with the user for launched each of them.
You can try this;
docker inspect $(docker ps -q) --format '{{.Config.User}} {{.Name}}'
Edit: Container name added to output
There's no built in way to do this.
You can check the user that the application inside the container is configured to run as by inspecting the container for the .Config.User field, and if it's blank the default is uid 0 (root). But this doesn't tell you who ran the docker command that started the container. User bob with access to docker can run a container as any uid (this is the docker run -u 1234 some-image option to run as uid 1234). Most images that haven't been hardened will default to running as root no matter the user that starts the container.
To understand why, realize that docker is a client/server app, and the server can receive connections in different ways. By default, this server is running as root, and users can submit requests with any configuration. These requests may be over a unix socket, you could sudo to root to connect to that socket, you could expose the API to the network (not recommended), or you may have another layer of tooling on top of docker (e.g. Kubernetes with the docker-shim). The big issue in that list is the difference between the network requests vs a unix socket, because network requests don't tell you who's running on the remote host, and if it did, you'd be trusting that remote client to provide accurate information. And since the API is documented, anyone with a curl command could submit a request claiming to be a different user.
In short, every user with access to the docker API is an anonymized root user on your host.
The closest you can get is to either place something in front of docker that authenticates users and populates something like a label. Or trust users to populate that label and be honest (because there's nothing in docker validating these settings).
$ docker run -l "user=$(id -u)" -d --rm --name test-label busybox tail -f /dev/null
...
$ docker container inspect test-label --format '{{ .Config.Labels.user }}'
1000
Beyond that, if you have a deployed container, sometimes you can infer the user by looking through the configuration and finding volume mappings back to that user's home directory. That gives you a strong likelihood, but again, not a guarantee since any user can set any volume.
I found a solution. It is not perfect, but it works for me.
I start all my containers with an environment variable ($CONTAINER_OWNER in my case) which includes the user. Then, I can list the containers with the environment variable.
Start container with environment variable
docker run -e CONTAINER_OWNER=$(whoami) MY_CONTAINER
Start docker compose with environment variable
echo "CONTAINER_OWNER=$(whoami)" > deployment.env # Create env file
docker-compose --env-file deployment.env up
List containers with the environment variable
for container_id in $(docker container ls -q); do
echo $container_id $(docker exec $container_id bash -c 'echo "$CONTAINER_OWNER"')
done
As far as I know, docker inspect will show only the configuration that
the container started with.
Because of the fact that commands like entrypoint (or any init script) might change the user, those changes will not be reflected on the docker inspect output.
In order to work around this, you can to overwrite the default entrypoint set by the image with --entrypoint="" and specify a command like whoami or id after it.
You asked specifically to see all the containers running and the launched user, so this solution is only partial and gives you the user in case it doesn't appear with the docker inspect command:
docker run --entrypoint "" <image-name> whoami
Maybe somebody will proceed from this point to a full solution (:
Read more about entrypoint "" in here.
If you are used to ps command, running ps on the Docker host and grep with parts of the process your process is running. For example, if you have a Tomcat container running, you may run the following command to get details on which user would have started the container.
ps -u | grep tomcat
This is possible because containers are nothing but processes managed by docker. However, this will only work on single host. Docker provides alternatives to get container details as mentioned in other answer.
this command will print the uid and gid
docker exec <CONTAINER_ID> id
ps -aux | less
Find the process's name (the one running inside the container) in the list (last column) and you will see the user ran it in the first column
What is the difference between docker run and docker create commands?
I usually use run but sometimes in documentation I see create.
Docker's --help tells
create Create a new container
run Run a command in a new container
Does it mean that run is used when we need to pass a command to a new container? What's the aim of create then?
docker run = docker create + docker start.
From docker documentation
The docker create command creates a writeable container layer over the
specified image and prepares it for running the specified command. The
container ID is then printed to STDOUT. This is similar to docker run
-d except the container is never started. You can then use the docker start command to start the container at any point.
This is useful when you want to set up a container configuration ahead
of time so that it is ready to start when you need it. The initial
status of the new container is created.
docker create command creates a writeable container from the image and prepares it for running.
docker run command creates the container (same as docker create) and starts it.
The other answers have this covered but I thought I'd show the equivalent shell command-lines because it makes it really clear:
$ docker run myimage
is the same as
$ docker start -a $(docker create myimage)
Here, docker create is used to create a container from the named image and outputs the created container id and docker start is used to start the container with that id. The -a option causes the terminal to attach so that the container runs in the foreground which is the default behaviour of docker run.
A container that has been created but never started will have a Created status; this can be seen with docker container ls -a.
I'm new to docker and just got around to playing with it;
My take is that docker run essentially does the following: (in the order of..) docker create, docker start, docker attach , since it immediately attaches to the active shell after you do the 'run' command.
to create a container:
to start a container:
to create and start with a single command:
Now to understand we must dig deep with create and start.
Process of creating a container is taking the file system from image, and kind of prep it for use in the new container. When we create the container we are just prepping or setting up the file system snapshot to be used to create the container to actually start the container.
So creating container is about the file system starting it is about actually executing the startup the command.
And to start the container, we actually execute the start up command that might start up the process.
Lets see it in terminal:
When I run command "sudo docker create hello-world" it prints bellow output.
In the output we saw characters printed out. This is the ID of the container that was just created, Now I can actually execute the hello world command inside of this container by running Docker start.
So what happened here, first off we kind of prop the container by getting the file system ready.
Then after that we actually executed the primary start up command in there with Docker start.
-a in the docker start command is for watching output from the container and print it out to your terminal.
So there is very small difference between Docker run and docker start, by default Docker run is going to show you all the logs or all the information coming out of the container. By default Docker start is the opposite Docker start is not going to show you information coming out of the terminal.
Now you know when you need to use Run / Create / Start
Docker run is basically for running commands in the container.
docker run -it <Container Name> /bin/bash
The above is for creating a bash terminal. And make us use bash commands in the container.
Docker create is to create a container from an Docker Image.
docker create -d /var/lib:/var/lib --name docker-ubuntu ubuntu
The above is to create a docker a container of the name "docker-ubuntu" from the image "ubuntu"
I have started working with docker and I faced a problem whenever i start a container it provides a ID but when the container goes down and after new startup this starts with new ID, in this case the data/logs belongs to last start-up gets lost. Is this possible to fix the containers-ID ?
Do you mean the container name? Use the option --name
Here is the sample that you can reserve the same name when start the container. But you need make sure that no container with same name is running.
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
Second, if you need manage logs, then
create a seperate log volume and mount it with container.
export the log to ELK/splunk
If you need some solutions now, try this repository
https://github.com/gliderlabs/logspout
Log routing for Docker container logs
I have only one docker instance running. My actual task to write shell script around this container.
However the first step is to get the container ID via a shell command.
Is there a shell command to do it?
you can do either
docker ps -q
or also, as the only running container is also the last one
docker ps -lq