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
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
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
Command explanation
The
docker run
command first creates a writeable container layer over the specified image, and then starts it. Read moreThe
-p 127.0.0.1:5442:5432/tcp
part specifies theport
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 portsThe
-e POSTGRES_PASSWORD=mysuperpassword
part specifies theenvironment
variables that the image can detect. You should read the postgres image docs to see a complete list but the most common are:
- -
POSTGRES_DB
- -
POSTGRES_USER
- -
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 themThe
-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 thelatest
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
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
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
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
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 needpostgres
. Also we can specify a tag, which is12
. 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 toalways
, 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
*docker-compose.yml: *
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
-
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 nameddb-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.
- Create a new connection with your own settings: