DEV Community 👩‍💻👨‍💻

Cover image for Dockerize Postgres: How to install Postgres with Docker
José María CL
José María CL

Posted on • Updated on

Dockerize Postgres: How to install Postgres with Docker

Hi. I'm about to take a CubeJS tutorial to create a nice dashboard and it seems that I need a Postgres DB.

So it's obvious that I have to use docker as usual and I want to share how to install Postgres in Docker because I wish someone had instructed me how to do it and save some time.

I will show you 2 ways to do it: the very simple way (single line command), and the most common and accepted way (using docker-compose.yml file).

One thing you have to know is that the container will be installed in the path you currently are, so I suggest you to create a directory for your project and create the container there.

1. Install it with the command line

Use the command below to install the postgres "image". You should customize it.

❯ docker run -p 127.0.0.1:5442:5432/tcp  -e POSTGRES_PASSWORD=mysuperpassword --name postgres_cube -d postgres:12
Enter fullscreen mode Exit fullscreen mode

Once you ran that command, your terminal will show you something like the code below. This is the container ID which means it's up and running.

❯ 90a63c0aa9b597d63f644ecd178e549f161d12fa84d7a16a47545aaa92087124
Enter fullscreen mode Exit fullscreen mode

To verify the container is up and running just run this command and you should see the postgres_cube is Up

❯ docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS                     PORTS                    NAMES
17a8bca60f6d   postgres:12   "docker-entrypoint.s…"   3 minutes ago   Up 3 minutes               0.0.0.0:5442->5432/tcp   postgres_cube
Enter fullscreen mode Exit fullscreen mode

Command explanation

  • The docker run command first creates a writeable container layer over the specified image, and then starts it. Read more

  • The -p 127.0.0.1:5442:5432/tcp part specifies the port option to map the host (the real machine) port to the container port. Put attention on the 5442:5432. In this case I'm specifying that I want to use my machine 5442 port to connect with the container 5432 port (which is the postgres service port living in the container). I'll use the 5442 to connect my DB Client (DBeaver in my case). Read more about published ports

  • The -e POSTGRES_PASSWORD=mysuperpassword part specifies the environment variables that the image can detect. You should read the postgres image docs to see a complete list but the most common are:

  1. - POSTGRES_DB
  2. - POSTGRES_USER
  3. - POSTGRES_PASSWORD

For postgres the POSTGRES_PASSWORD is required.

  • In this case I'm specifying the required POSTGRES_PASSWORD to set a password. The user by default is "postgres" and the default database is "postgres" and other 2 template databases (as usual).

  • --name postgres_cube specifies a custom name for the container. postgres_cube in my case. If you don't pass it, docker will use a random name but it's a good idea to give it a name to identify your container when using just a few of them

  • The -d is an option that allows us to detach our terminal session, which means that we don't need to keep a terminal open while the container is running.

  • And finally, the postgres:12 is the image (postgres) name and the tag (12). This is useful to install a specific version. If the tag is not specified, you will install the latest version.

2. Use a docker-compose file

First step is to create a docker-compose.yml in your project folder.

After that, copy, paste and save the content below:

version: "3"

networks:
  net-cube-tutorial:

volumes:
  db-cube-tutorial:

services:
  postgres:
    image: postgres:12
    hostname: postgres
    restart: unless-stopped
    container_name: postgres_cube
    environment:
      POSTGRES_DB: cube_tutorial
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: mysuperpassword
    ports:
      - 5442:5432
    volumes:
      - db-cube-tutorial:/var/lib/postgresql/data
    networks:
      - net-cube-tutorial

Enter fullscreen mode Exit fullscreen mode

Finally run the command below. Docker will look for the docker-compose.yml file at the current path automatically, so you don't need to worry about.

❯ docker-compose up  -d
Enter fullscreen mode Exit fullscreen mode

Your terminal will output something like the messages bellow, which means everything is fine.

Creating network "cubejs_net-cube-tutorial" with the default driver
Creating postgres_cube ... done
Enter fullscreen mode Exit fullscreen mode

To verify the container is up and running just run this command and you should see the postgres_cube is Up

❯ docker ps -a
CONTAINER ID   IMAGE         COMMAND                  CREATED         STATUS                     PORTS                    NAMES
17a8bca60f6d   postgres:12   "docker-entrypoint.s…"   3 minutes ago   Up 3 minutes               0.0.0.0:5442->5432/tcp   postgres_cube
Enter fullscreen mode Exit fullscreen mode

File structure explanation

  • What does the docker-compose.yml? Compose is a tool for defining and running multi-container Docker applications. With Compose, you use a YAML file to configure your application’s services. Then, with a single command, you create and start all the services from your configuration. Read more about it
  • version: "3" specifies we will use the syntax version 3. Read more about compose versions
  • networks lets you to define container internal networks. This is perfect when you need to connect or join multiple services in the same container. Read more about networking
  • volumes is the virtual storage for the container if we wan't to keep the data. It's useful to set a name for it because it will let us to reference the services to use it. Read more about volumes
  • services is the list of the services will run on the container. Here we can specify a set of images and its configuration. In this case we only need the postgres service connected to the named container network, using the named storage and map the network port to our host port to be able to connect the DB with an external program outside the container.
  • image is the image name, in this case we need postgres. Also we can specify a tag, which is 12. If you don't specify it, it will use the "latest" version.
  • hostname lets you assign a name to the service as host in the network. It's useful if we want to allow services to communicate between them. We can use the host name to reference the services at network level.
  • restart specifies the restart policy. unless-stopped always restart the container if it stops, Similar to always, except that when the container is stopped (manually or otherwise), it is not restarted even after Docker daemon restarts.
  • container_name allow to set a name for the container so we can easily find it. If you don't give it a name, a randomly generated name will be used.
  • environment is the section where we are able to specify environment variables supported by the image. For postgres there is a list you can explore in the docs but the most common are
  • - POSTGRES_DB
  • - POSTGRES_USER
  • - POSTGRES_PASSWORD

I recommend you to avoid exposing the variable values in the docker-compose.yml. Instead, you should specify them in a .env file and use it in the docker-compose.yml in this way

*.env file: *

DB_USER=mypostgresuser
DB_PASSWORD=mysuperpassword
Enter fullscreen mode Exit fullscreen mode

*docker-compose.yml: *

   POSTGRES_USER: ${DB_USER}
   POSTGRES_PASSWORD: ${DB_PASSWORD}
Enter fullscreen mode Exit fullscreen mode
  • ports lets you map your actual machine (the host) to the container network ports. In this case I'm using the port 5442 of my machine to access to the container port 5432 to be able to connect DBeaver to the database directly.
  • volumes here we map the container folder called "data" (/var/lib/postgresql/data) to be accesible from the root of our volume named db-cube-tutorial
  • networks allow us to connect our service to the specified container network.

Bonus: Connect a DB client (DBeaver) to our DB

I'll use thee DBeaver program to easily use my DB, but you can use whatever you want.

  1. Create a new connection with your own settings:

New DBeaver Connection Setup

  1. Test the connection
    Connection Test Result

    1. Enjoy DBeaver Connected to the DB

Top comments (0)

Git push

Stop by this week's meme thread!