DEV Community

Cover image for 🐳Upgrade a Database Without Recreating It With Docker
Joey Ohannesian
Joey Ohannesian

Posted on

🐳Upgrade a Database Without Recreating It With Docker

😟We don't typically have to worry about what happens to the data on our computers. When our computers turn on, they pull the information from the hard drive and that's that. It's not so easy with containers.

🫙Much like geysers, you're not really supposed to go in them once created. Containers are meant to be used and thrown away. They're used for cloud environments and micro-services with tons of moving parts. Containers are ephemeral. They are essentially disposable. Best practice is to not modify containers once they're running and instead to make your changes and then spin up a new instance.

🥅Goal

The goal here is to complete a minor version upgrade of a database container while preserving the DB data.

💯Success Criteria

Success in this case will be an upgrade of postgres 9.6.1 to postgres 9.6.2 without version 9.6.2 having to boot up from scratch on first start.

🧑‍🏫Instructions

  • Data base upgrade with containers
  • Create a postgres container with version 9.6.1
  • Use Docker Hub documentation to learn VOLUME path
  • Check logs, stop container
  • Create a new postgres container with same volume using 9.6.2
  • Check logs to validate

🧑‍🍳Prerequisites

📌 Docker Engine + CLI installed
📌 Internet connection

⏰Time to Start

Step 1 : Figure Out Where to Store Data

-e PGDATA=/var/lib/postgresql/data/pgdata \
-v pgresdb:/var/lib/postgresql/data

postgres Docker Hub documentation

Searching the docs for postgres on Docker Hub, I found the above section. This is exactly what is needed to change the place where data is stored, except we change /custom/mount: to pgresdb to name our volume as such.

Step 2: Run the Container

docker container run \
-e POSTGRES_PASSWORD=k \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v pgresdb:/var/lib/postgresql/data \
postgres:9.6.1

  • docker container run tells Docker we want to start a container
  • -e POSTGRES_PASSWORD is required to set a password for postgres
  • postgres:9.6.1 specifies we want to download postgres version 9.6.1
Step 3: Check the Logs

docker logs -f 'container_id_here'

Successful psql start

The log file should be pretty long here since the database is being initialized. The -f variable let's us follow the output of the logs as they are created.

Step 4: Stop & Start Updated Instance

First, stop the container with docker container stop 'instance_id_here'.

Then run this command:

docker container run \
-e POSTGRES_PASSWORD=k \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v pgresdb:/var/lib/postgresql/data \
postgres:9.6.2

Look familiar? That's because it's the exact same as step 2's command, but with a minor version bump!

Step 5: Check the Logs

docker logs -f 'container_id_here'

shorter log file!

The log file should be significantly shorter here because it's pulling the DB information from the volume we created earlier.

Mistakes

  • Instead of naming a volume, I put $(pwd). I thought I had to name the working directory the in head of the -v command. This lead to creating a pgdata but the volume not being shown with the command docker volume ls. This led to permissions errors which were hard to troubleshoot.
  • Not running the password environment variable led to the server not starting.

🔥Results


I learned how to create a volume with Docker via the CLI and do a minor database upgrade without having to recreate the database. I also learned how to access the working directory and how to access/read through log files.

I was actually thinking of this problem before completing this tutorial. I was wondering how developers could account for data persisting through container failures and upgrades, so it's nice to see that Docker has a solution already built in that's fairly easy to implement.

Top comments (0)