8

I sometimes stop/start docker very often when I am release new features in my application.

docker-compose up -d
docker-compose stop

I am using pretty much the bare bones postgres docker setup (see below). I am mapping the /data folder to my host.

Is there anything I should be worried about if I stop/start docker many times in a day in terms of data getting corrupted?

Is calling docker-compose stop the best way to be stopping my postgres instance?

My postgres service in my docker-compose looks like this:

  db:
    image: postgres:9.4
    volumes:
      - "/home/deploy/data/pgdata:/var/lib/postgresql/data"
    restart: always

This setup currently is running smoothly in development, but once it goes to production I want to make sure I am following best practices etc.

4 Answers 4

5

Databases in particular are usually designed so that it's very hard to lose data, even if the machine loses power in the middle of writing something to disk. (This comes at some performance cost.) So long as you don't have more than one PostgreSQL instance at a time using the same backing data store, I'd expect it to not lose data or otherwise corrupt itself; the worst you should expect to see is a message at startup that it's recovering from a write-ahead log or something along those lines.

docker stop will send a signal to a container that prompts it to shut down cleanly, and PostgreSQL will take this as a cue to shut down. It looks like docker-compose stop, docker-compose down, and sending ^C to docker-compose up all use the same mechanism. So the way you're doing it now should result in a clean shutdown (provided PostgreSQL finishes its cleanup within 10 seconds).

I believe you can docker-compose restart specific services, or docker-compose up --force-recreate them. This would help if you rebuilt your application container and needed to restart that, but not its database.

Sign up to request clarification or add additional context in comments.

1 Comment

docker stop is documented to send SIGTERM, wait 10 seconds, then send SIGKILL; the procedure in the question is correct. I added a paragraph to my answer explaining this.
4

Use,

docker-compose down -v

What it does is basically removes all the volumes you added. If you don't those volumes will hang on and eat up your space. It only removes the volume inside the docker container. The volume in your host stays and survives container removal in case if you want that data to survive container removal.

Whenever you create a docker container by docker run, Docker creates a volume/ directory to keep the details about the containers. After you execute docker run, if you look into /var/lib/docker/containers, you will see one directory for each container you started. If you have not removed the volumes for previous container, you will see many directories under the "container" directory. The name of these directories will be very long random letters and number. So, if you don't tell the docker to remove these directories when you stop the container, it will be there forever. The v option I mentioned above, will delete these directories when you take down the container. Keep in mind, you can view the contents of the directory /var/lib/docker only as a root user. To change to root user, use sudo -i before you attempt to view the contents of the directory.

3 Comments

so what do you mean? if I do stop how will can I tell if those volumes are still lingering around? Sorry just don't understand "hang on and eat up your space" means, is there a docker commadn where I can see them lingering?
Total reclaimed space: 24.48GB thanks for the tip!
Wasn't the question how to stop PostgreSQL cleanly?
1

Yes, it is safe to simply stop a PostgreSQL Docker container with docker stop, docker compose stop or docker compose down.


The command docker stop (as well as docker compose stop or docker compose down) does not simply kill processes, but sends a stop signal to them.

By default, Docker (as well as Docker Compose) sends the SIGTERM signal to the process and if the application is not terminated within a certain time, a SIGKILL signal is sent (this kills the process hard).

For a normal or soft shutdown, PostgreSQL uses three different signals: SIGTERM, SIGINT and SIGQUIT.

SIGTERM is very accommodating and waits until open connections are closed by the client. Depending on the application, however, connections to the database can sometimes be kept open for a very long time, which can ultimately lead to PostgreSQL waiting a very long time before terminating.

In contrast to SIGTERM, SIGINT does not wait passively until open connections are closed before terminating the database, but actively closes the connections itself. This helps to terminate the database server in good time before Docker kills it after a timeout.

In 2020, the default shutdown signal for the Docker variant of PostgreSQL was changed to SIGINT to further reduce the risk of data loss by allowing PostgreSQL to shut down properly on its own and not be killed by the Docker daemon.

Comments

0

Stopping the container will usually work, but this is a "hope for the best" that you may not want in production. The issue is that docker stop will send a SIGINT signal (since 2020, before it was SIGTERM) to the process. This will trigger your database to initiate a fast and hopefully safe stop. However after a delay (10s by default) docker stop goes on and will send a SIGKILL signal. This signal cannot be trapped and will kill the database process. So if it did not finish its cleanup within this 10s delay, your data will not be in an clean state.

Databases try very hard to be in a clean state, but a dirty stop will require extra time for your engine to clean up the mess and ensure data is consistent. For production you are usually willing to minimize both startup time and risk of data corruption.

Best option is to trigger a manual stop of your database by executing a pg_ctl stop command within your container, and wait for the proper shutdown. A mitigation can be to extend the delay before the KILL signal is sent: docker allows the --stop-timeout option to extend the delay before killing the process., and for docker compose the option is stop_grace_period. Not that here again you are betting that the database will cleanly stop within this delay, which is never guaranteed (big updated, full scans requests, etc.).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.