Why doesn't docker-compose 'down' take an optional [SERVICE...] argument? - docker-compose

docker-compose down does not have a [SERVICE...] argument.
Per docker-compose down --help:
Usage: down [options]
I would like to be able to bring just one of my many containers down. I know that I can down a single container using docker down instead of docker-compose down, but I'm wondering why doesn't the docker-compose down command take an optional [SERVICE...] argument?
All of the following docker-compose commands do take an optional [SERVICE...] argument:
docker-compose build
docker-compose create
docker-compose kill
docker-compose logs
docker-compose pause
docker-compose restart
docker-compose rm
docker-compose start
docker-compose stop
docker-compose unpause
docker-compose up
My docker-compose --version is 1.9.0

The following command is the equivalent of docker down for a single service:
docker-compose rm -s -v my_service
Usage: rm [options] [SERVICE...]
Options:
-s, --stop Stop the containers, if required, before removing
-v Remove any anonymous volumes attached to containers

There is no docker down. The corresponding docker command is closer to: docker stop; docker rm
From docker-compose down:
Stops containers and removes containers, networks, volumes, and images created by up.
By default, the only things removed are:
Containers for services defined in the Compose file
Networks defined in the networks section of the Compose file
The default network, if one is used
If docker-compose down removes networks also, then by removing one container, it should also automatically disconnect the other containers from these networks, which might be undesirable or confusing.
It could change so that by default docker down does not remove the networks, but that change might cause backwards-compatibility issues with the command.
This is just an assumption.

Related

How to return one container to a clean state in docker compose?

Using docker-compose restart <service> retains some persistent state of the container (e.g. it does not remove database tables from the postgres alpine container, presumably because a persistent volume is defined somewhere inside of that image, even without being mentioned in docker-compose.yaml).
Using e.g. docker-compose down && docker-compose up -d returns all containers to a fresh state.
How do you return just one container to a fresh state?
To recreate fresh a single service with docker-compose:
docker-compose rm -svf <service> && docker-compose up -d <service>
When you remove the container, the -v instructs to also evict from storage any anonymous volumes that were attached to it. If you omit this -v then you will accumulate unused volumes, and subsequently want to run docker volume prune to clean those up. The -s is just a shortcut instead of typing docker-compose stop <service> beforehand, and -f avoids prompting to confirm yes.
For comparison, if you merely attempt docker-compose restart <service> then any existing anonymous volumes will be maintained (i.e. the process will be rebooted but internal stored state of the container can persist). Supposedly docker-compose build <service> && docker-compose restart <service> would work if there had been any changes in the source for that container.
A more concise alternative is:
docker-compose up -V -d <service>
This does recreates a particular service, even if the services were already up; the -V (which can also be expressed as --renew-anon-volumes) means to create fresh anonymous volumes instead of retrieving those from the pre-existing container. However it leaves the previous volumes stored until subsequent pruning.
By using docker-compose down and up you cannot freshen a single container, but by using docker-compose restart <service name> you can restart single service.
Please check compose cli reference : https://docs.docker.com/compose/reference/

Start interactive shell into a sql server 2019 container running in an aks pod

I am using the mssql docker image (Linux) for sql server 2019. The default user is not root but mssql.
I need to perform some operations as root inside the container:
docker exec -it sql bash
mssql#7f5a78a63728:/$ sudo <command>
bash: sudo: command not found
Then I start the shell as root:
docker exec -it --user=root sql bash
root#7f5a78a63728:/# <command>
...
This works.
Now I need to do this in a container deployed in an AKS cluster
kubectl exec -it rms-sql-1-sql-server-deployment-86cc45dc5c-tgtm2 -- bash
mssql#rms-sql-1-sql-server-host:/$ sudo <command>
bash: sudo: command not found
as expected. But then:
kubectl exec -it --user=root rms-sql-1-sql-server-deployment-86cc45dc5c-tgtm2 -- bash
error: auth info "root" does not exist
So when the container is in an AKS cluster, starting a shell as root doesn't work.
I then try to ssh into the node and use docker from inside:
kubectl debug node/aks-agentpool-30797540-vmss000000 -it --image=mcr.microsoft.com/aks/fundamental/base-ubuntu:v0.0.11
Creating debugging pod node-debugger-aks-agentpool-30797540-vmss000000-xfrsq with container debugger on node aks-agentpool-30797540-vmss000000.
If you don't see a command prompt, try pressing enter.
root#aks-agentpool-30797540-vmss000000:/# docker ...
bash: docker: command not found
Looks like a Kubernetes cluster node doesn't have docker installed!
Any clues?
EDIT
The image I used locally and in Kubernetes is exactly the same,
mcr.microsoft.com/mssql/server:2019-latest untouched
David Maze has well mentioned in the comment:
Any change you make in this environment will be lost as soon as the Kubernetes pod is deleted, including if you need to update the underlying image or if its node goes away outside of your control. Would building a custom image with your changes be a more maintainable solution?
Generally, if you want to change something permanently you have to create a new image. Everything you described behaved exactly as it was supposed to. First you have exec the container in docker, then logged in as root. However, in k8s it is a completely different container. Perhaps a different image is used. Second, even if you made a change, it would exist until the container dies. If you want to modify something permanently, you have to create your new image with all the components and the configuration you need. For more information look at pod lifecycle.

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

docker-compose up, down, stop start difference

I cant find more information about those.
Should we use docker stop for containers which we started with docker start
Or same for docker-compose up?
What is the difference between stop and down?
In docker-compose help
stop Stop services
down Stop and remove containers and networks (optionally images and volumes as well)
# Stop services only
docker-compose stop
# Stop and remove containers, networks..
docker-compose down
# Down and remove volumes
docker-compose down --volumes
# Down and remove images
docker-compose down --rmi <all|local>
Following are the differences among various docker-compose command options:
docker-compose up - start and restart all the services defined in docker-compose.yml
docker-compose down - command will stop running containers, but it also removes the stopped containers as well as any networks that were created. You can take down one step further and add the -v flag to remove all volumes too. This is great for doing a full blown reset on your environment by running docker-compose down -v.
docker-compose start - command will only restart containers stopped previously
docker-compose stop - command will stop running containers but won’t remove them
Just to answer the other part of the question:
Use docker-compose up to start or restart all the services defined in a docker-compose.yml.
The docker-compose start command is useful only to restart containers that were previously created, but were stopped. It never creates new containers.
The docker-compose run command is for running “one-off” or “adhoc” tasks.
For further information visit this page.

Remove a named volume with docker-compose?

If I have a docker-compose file like:
version: "3"
services:
postgres:
image: postgres:9.4
volumes:
- db-data:/var/lib/db
volumes:
db-data:
... then doing docker-compose up creates a named volume for db-data. Is there a way to remove this volume via docker-compose? If it were an anonymous volume, then docker-compose rm -v postgres would do the trick. But as it stands, I don't know how to remove the db-data volume without reverting to docker commands. It feels like this should be possible from within the docker-compose CLI. Am I missing something?
docker-compose down -v
removes all volumes attached. See the docs
There's no way to target the removal of a specific named volume with the docker-compose cli. Instead this can be achieved using the docker cli. See the docs.
Use docker volume ls to find the name of specific volume.
Remove the volume using docker volume rm VOLUME_NAME. You will need to have stopped and removed containers using the volume.
An example approach:
# Stop and remove container's using the target volume
docker-compose stop NAME_OF_CONTAINER
# We need the force flag, "-f", as the container is still bound to the volume
docker-compose rm -f NAME_OF_CONTAINER
# Next find your volume name in the following list
docker volume ls
# Finally remove the volume
docker volume rm VOLUME_NAME
Jan, 2022 Update:
This removes all the containers, networks, volumes and images defined in the docker-compose.
docker-compose down -v --rmi all
"-v" is for all the volumes
"--rmi all" is for all the images
I had the same issue as you, excepting I wanted to discard the working state of my grafana container while leaving the other containers running, which are running detached (ie. sudo docker-compose up -d). Here's the procedure I've come up with:
sudo docker-compose ps
sudo docker-compose stop grafana
sudo docker-compose rm --force grafana
sudo docker volume rm metricsmonitoring_grafana_data
sudo docker-compose up --force-recreate -d grafana
I don't know (without playing further) how best to determine the name of the docker volume to remove.
This is on docker-compose version 1.18.0