Remove a named volume with docker-compose? - postgresql

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

Related

Docker Volume Data is not Persistent

I want to create two Docker volumes and have their data be persistent. I run sudo docker compose up -d, post some data to my website (text that is stores in a sqlite database and an image stored in the filesystem), then run sudo docker compose down. When I run sudo docker compose up -d again, all the data I posted is gone. With the following configs, I expect the data to still be present.
Dockerfile:
FROM python:3.9.16-buster
RUN pip install --upgrade pip
# The Debian/Buster default is to disable the password.
RUN adduser nonroot
RUN mkdir /home/site/ && chown -R nonroot:nonroot /home/site
RUN chown -R nonroot:nonroot /var/log/site
# two volumes created
VOLUME /home/site/db /home/site/static
WORKDIR /home/site
USER nonroot
# folders ./site/static and ./site/db exist in my host directory
COPY --chown=nonroot:nonroot . .
CMD ["python", "./site/main.py"]
compose.yaml:
services:
site:
build: flask
restart: always
ports:
- '8081:8081'
volumes:
- site_db:/home/site/db # same path as the volumes created in the Dockerfile
- site_static:/home/site/static
command: gunicorn -w 1 -t 3 -b 0.0.0.0:8081 --chdir ./site main:app
volumes:
site_db: # I find it odd these volumes keys don't have values, but that's what I have see other people do
site_static:
docker compose up and docker compose down delete my volumes.
docker compose start and docker compose stop do NOT delete my volumes.
Through the Flask app, check where you are uploading the files to, as well as where the sqlite3 db file is. If these paths do not align with the volumes paths, data will not persist.

Two Volumes are created when I run a docker container with volume mapping

I am creating postgreSQL container using following command
sudo docker run -d --name=pg -p 5432:5432 -e POSTGRES_PASSWORD=secret -e PGDATA=/pgdata -v pg:/pgdata postgres
After running this container when I check volumes by running following command
sudo docker volume ls
DRIVER VOLUME NAME
local 6d283475c6fe923155018c847f2c607c464244cb6767dd37a579824cf8c7e612
local pg
I get two volumes. pg volume is created in the command but what the second volume is??
If you look at the Docker Hub decomposition of the postgres image you will notice it has a declaration
VOLUME ["/var/lib/postgresql/data"]
If you don't explicitly mount something else on that directory, Docker will create an anonymous volume and mount it there for you. This behaves identically to a named volume except that it doesn't have a specific name.
docker inspect mostly dumps out low-level diagnostic information, but it should include the mount information, and you should see two volume mounts, one with the anonymous volume on the default PostgreSQL data directory and a second matching the explicit mount on /pgdata.

How to add volume mount to running postgreSQL container?

I have a running postgreSQL docker container and need to add a volume mount.
I followed the steps from How can I add a volume to an existing Docker container?, (ran docker commit on the container to save it as an image, and spun up another container based on that image with a named volume mounted in). All the data files from the first container are present in /var/lib/postgres/data of the second container.
However, when I try to query this second postgres database, I cannot see any tables that are in the first container. Been trying to fix this for a few days with no luck, am I missing something here (does mounting a volume obscure the existing data in /var/lib/postres/data)?
Commit will not work as there is the volume defined in the Dockerfile.
Volumes are useful in many cases, for example, for running
database-storage. However, since volumes are not 'part' of a
container, it makes containers no longer portable - which seems in
direct conflict with the slogan "Build once... Run anywhere.."
docker commit data container with VOLUME
One option that you can try is copying data folder to host from an existing container and then launch the container with mount path.
docker cp my_db_cotainer:/var/lib/postgresql/data db_data
then start a new container with this path so it will contain the same data as the previous one
docker run -d --name some-postgres -v $PWD/db_data/:/var/lib/postgresql/data postgres
same for mysql
docker cp some-mysql-old:/var/lib/mysql db_backup
docker run --rm --name some-mysql-new -v $PWD/db_backup:/var/lib/mysql -it mysql

docker-compose mounted volume remain

I'm using docker-compose in one of my projects. During development i mount my source directory to a volume in one of my docker services for easy development. At the same time, I have a db service (psql) that mounts a named volume for persistent data storage.
I start by solution and everything is working fine
$ docker-compose up -d
When I check my volumes I see the named and "unnamed" (source volume).
$ docker volume ls
DRIVER VOLUME NAME
local 226ba7af9689c511cb5e6c06ceb36e6c26a75dd9d619360882a1012cdcd25b72
local myproject_data
The problem I experience is that, when I do
$ docker-compose down
...
$ docker volume ls
DRIVER VOLUME NAME
local 226ba7af9689c511cb5e6c06ceb36e6c26a75dd9d619360882a1012cdcd25b72
local myproject_data
both volumes remain. Every time I run
$ docker-compose down
$ docker-compose up -d
a new volume is created for my source mount
$ docker volume ls
DRIVER VOLUME NAME
local 19181286b19c0c3f5b67d7d1f0e3f237c83317816acbdf4223328fdf46046518
local 226ba7af9689c511cb5e6c06ceb36e6c26a75dd9d619360882a1012cdcd25b72
local myproject_data
I know that this will not happen on my deployment server, since it will not mount the source, but is there a way to not make the mounted source persistent?
You can use the --rm option in docker run. To use it with docker-compose you can use
docker-compose rm -v after stopping your containers with docker-compose stop
If you go through the docs about Data volumes , its mentioned that
Data volumes persist even if the container itself is deleted.
So that means, stopping a container will not remove the volumes it created, whether named or anonymous.
Now if you read further down to Removing volumes
A Docker data volume persists after a container is deleted. You can
create named or anonymous volumes. Named volumes have a specific
source form outside the container, for example awesome:/bar. Anonymous
volumes have no specific source. When the container is deleted, you
should instruct the Docker Engine daemon to clean up anonymous
volumes. To do this, use the --rm option, for example:
$ docker run --rm -v /foo -v awesome:/bar busybox top
This command creates an anonymous /foo volume. When the container is
removed, the Docker Engine removes the /foo volume but not the awesome
volume.
Just remove volumes with the down command:
docker-compose down -v

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

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.