CYBERTEC PostgreSQL Logo

Quick start: How to build your first PostgreSQL container

12.2024 / Category: / Tags:

As announced in the first part of this series, this article is the second part of our journey towards Docker and Kubernetes. By the end of this post, you will have built your first PostgreSQL container and learned and applied various ideas for optimising your containers.

Some additional vocabulary

But before we start, let's take a quick look back:

In the first Post, we built our first container and learnt about the FROM, RUN, COPY, ENTRYPOINT and CMD commands.

Based on these commands, we will start by adding the following commands to our vocabulary:

  • ARG - Defines a variable that we only use within the build process. Important to know with ARG is that depending on whether I set ARG before or after the FROM, I have a different visibility. This means that if I set ARG after the FROM, the value only lives within the FROM clause. If I set it before, it lives globally.
  • ENV - With ENV we define an environment variable for the runtime of the container. This environment variable can be used by the container.
  • VOLUME - Defines a mount point in the container for persistence. It is important to know that I can also define a persistent storage at a desired mountpoint to start the container without a volume. By using volume, however, Docker will mount a volume at this path even without an explicit definition.
  • EXPOSE - Defines a port that is to be opened for the outside world. It should be noted that this is only used for documentation purposes in the Dockerfile. This must be explicitly specified when the container is started.
  • WORKDIR - The workdir defines the path which is used for all subsequent commands, unless an explicit path is specified. If the folder does not exist, it is created automatically.
  • USER - By default, we are always running as root in the container, with user we can switch to the corresponding user based on a username or the userid.

Stages and their use

Equipped with the additional vocabulary, let's take a look at the theme of the stages. A stage defines the part of the Dockerfile that begins with a FROM and all the statements belonging to this FROM. This means that I can define several from clauses and therefore several stages in a Dockerfile, which is then referred to as a multi-stage Dockerfile.

The multi-stage approach is primarily used to create images that are as small as possible. This means that we can clone and compile something from Github in a first stage, for example, for which we need packages that are not required in the container to be executed later. By creating an additional stage for the container to be executed and copying the compiled software, we reduce the size of our image.

Let's use the example of the CYBERTEC-pg-container and take a look at the Dockerfile for the exporter.

Obtaining and compiling the exporter project requires the additional packages git and go. Furthermore, we need additional packages which in this case are included in the regular rocky9 image. We also do not need these in the later running image, so we use a much smaller image for the from-clause for the second stage.

Now we could discuss why we need multi-stages and not simply remove everything unnecessary from the containers net and thus make them smaller.

The reason lies in the layers of a container. Every command in the Dockerfile, i.e. FROM, RUN, ... creates a layer in the container and this layer is unchangeable. This means that I can try to keep the layer as small as possible within a layer by removing unnecessary elements. We can see this, for example, in the second part of the RUN command for installing the packages. Here, before the end of the layer, everything we don't need is removed, including the cache.

However, as soon as we remove the packages again in a second layer, this enlarges the container as we have an additional layer and the package is still present in the previous layer.

However, we now use a different trick for our PostgreSQL container. Instead of using a new stage with a scaled-down image, as in our example, we start with an empty container, i.e. without a layer, and then create exactly one layer by copying everything from our previous builder stage, which we have previously freed of everything unnecessary in a final step. This works because we now take the last status, thus the cleaned status, and write it in exactly one layer.

What we have to bear in mind with this topic is that we only define certain work on the last and therefore final container. This concerns the following instructions, among others:

  • ENV
  • ENTRYPOINT
  • CMD

It should also be noted that certain permissions for folders and files still need to be changed if you are working with a different user in the final stage, i.e. in the build stage.

Now let's get to work
We now want to build a simple PostgreSQL container that provides us with an instance.
To do this, we will install PostgreSQL from the PostgreSQL Global Development Group repos, remove unnecessary items from our container and finally create a fresh container with the content of the build stage and start it up.

Our Dockerfile:

Our launcher.sh

Let's build and launch the container once

Summary

In this blog article, we have looked at the various Docker instructions and different approaches to building small containers. Finally, we built our first PostgreSQL container, which is of course only intended for experimentation.

In the next part, we will take a deeper look at productively usable PostgreSQL containers and think about the proper use of containers.

Leave a Reply

Your email address will not be published. Required fields are marked *

CYBERTEC Logo white
Get the newest PostgreSQL Info & Tools


    This site is protected by reCAPTCHA and the Google Privacy Policy & Terms of Service apply.

    ©
    2024
    CYBERTEC PostgreSQL International GmbH
    phone-handsetmagnifiercrosscross-circle
    linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram