Running Apps in Docker, Part 1: Instantiation and Using PostgreSQL

After his introductory series, Tom Fenton deploys a database on Docker and integrates it with other apps deployed from other Docker images.

In my Introduction to Docker series, I covered the basics of what Docker is, how to install it and how to download images and start (instantiate) them. I also discussed networking and storage for Docker instances (running images).

While I stuck to just using a single Linux image in those articles, being able to deploy one or more images to create a multi-tiered application is where the real power of Docker comes into play. So, in this new series of articles, I will do that: deploy a database on Docker and then integrate it with other applications deployed from other Docker images.

[Click on image for larger view.]

There are many reasons why you would want to deploy an application in a Docker container rather than natively on the base OS, including isolation, ease of deployment and ease of upgrading. When multiple applications run natively on the same OS, they can interfere with one another. On the contrary, when each application runs in its own container, it is less likely to affect applications running in another container if another native or Docker instance has issues.

[Click on image for larger view.]

Because Docker applications are stored as images in a repository, they can be pulled down and deployed using just a few simple commands. As Docker is platform agnostic; identical images can be deployed on-premises, in the cloud, or on the Edge.

Instantiating PostgreSQL Instance
I will deploy the PostgreSQL database, a free, open source, relational database management system (RDBMS) whose origins date back to 1996. Since then, it has proven to be extremely reliable and performant. Although thousands of individuals and small businesses use PostgreSQL, it is also used by some of the largest corporations in the world and is the database for other applications. For example, VMware vCenter Server Appliance (VCSA) has an embedded PostgreSQL database. It also has a well-documented API that can be used to connect to it, and additionally has connectors that allow it to be used by most common programming languages, including Rust and Go.

[Click on image for larger view.]

Instantiating a PostgreSQL Image
Each example I provide below will be deployed on the Docker environment that I set up in my previous series of articles. Due to its agnostic nature, the following commands should work in other Docker environments, but they may require some minor tweaking. This article only touches on the basics of using PostgreSQL, but there is a list of free PostgreSQL tutorials located here.

Before deploying a PostgreSQL Docker image in my environment, I became root user, verified that the Docker engine was running, listed the Docker images, and examined my networking and volumes, as well as removed all unused instances, images, networks, and volumes, by entering:

  sudo bash
  systemctl status docker
  docker stats
  docker ps -a
  docker images
  docker network ls
  docker volume ls 
  docker system  prune --volumes
    

I listed PostgreSQL Docker images, downloaded the latest PostgreSQL image, instantiated (started) it and verified that it was started by entering:


  docker search postgres
  docker pull postgres


  docker run --name postgresql01 -e POSTGRES_USER=PostUser01 -e POSTGRES_PASSWORD=mypassword -p 5432:5432 -v /data:/var/lib/postgresql/data -d postgres
  docker ps -a

While many of the switches in this last command should be obvious, others may not be. The name of the instance is postgresql01, and the network connection between the host and instance is -p 5432:5432. The -v specifies the location where the persistent data is saved, and the -d runs the container in the background if you disconnect from the console.

Using PostgreSQL
One of the ways to manage PostgreSQL is by using psql, its command-line interface.

I entered my PostgreSQL container, launched psql as the user I created when I instantiated it, listed the existing tables (three are created by default), created a new database (TDB01), connected to it, and ran psql commands to show the current date and the version of PostgreSQL I was using by entering:


  docker exec -it postgresql01 
  psql -U PostUser01
  \list
  CREATE DATABASE TDB01;
  \l
  \c TDB01
  SELECT current_date;
  SELECT version;

Following the example in the PostgreSQL tutorial, I created tables and worked with the database without any issues.

I deleted the database that I created (TDB01) by disconnecting from it, and removed (dropped) it by entering:


  DROPDB TDB01
  \q

Importing Data into PostgreSQL
There are many ways to import data into the database, but I wanted to import data from the devices that I was monitoring using Edge DX, an endpoint monitoring and remediation tool from ControlUp (a company that I work for). This data can be exported via a comma separated value (CSV) file.

The data that I extracted from Edge DX had six columns of data that contained information about the device and the applications which were installed on the device.

I created a new database (appsdata), connected to the database, created a table (apps) in the database, displayed the tables in the database, and then displayed the columns in the table by entering:


  CREATE DATABASE appsdata;
  \c appsdata
  CREATE TABLE Apps("_device_id" VARCHAR(40),"created_local" DATE,"device_name" VARCHAR(40),"name" VARCHAR(120),"publisher" VARCHAR(120) ,"version" VARCHAR(120));
  \dt+
  \d+ apps

I used SCP to transfer the CSV data from my laptop to the host system that Docker was running on. I then transferred it from the host machine to the Docker instance from the host by entering:

  docker cp /tmp/Apps.csv postgresql01:/tmp/Apps.csv

I copied the data from the CSV file into the apps table, displayed all the rows of the data, and displayed and counted the different applications (starting with the most-used app and then by name) by entering the following in psql:


  COPY apps FROM '/tmp/Apps.csv'  DELIMITER ','  CSV HEADER;
  SELECT * FROM apps;
  SELECT NAME, count (*) from apps05 GROUP BY NAME ORDER BY COUNT DESC;
  SELECT NAME, count (*) from apps GROUP BY NAME ORDER BY NAME;
[Click on image for larger view.]

Outputting Query Information to a File
I copied the output of my query in CSV format to a file in the /tmp directory, exited the database, and verified that the new file existed by entering:


  copy (select NAME, count (*) from apps04 GROUP BY NAME ORDER BY COUNT) to '/tmp/Appcount.txt' with csv;
  \q
  ls -l /tmp/A*
[Click on image for larger view.]

Here are PostgreSQL commands I used:

Command

Notes

psql -U PostUser01

Connect to the PostgreSQL as user PostUser01

\list or \l

List the databases

CREATE DATABASE TDB01

Create a database called tdb01 (database will be created in lowercase)

\c

Show what database you are currently connected to

\c TDBO1

Connect to database TDB01

SELECT current_date;

Show the current date

SELECT version;

Show the version of PostgreSQL that you are running

DROPDB TDB tdb01

Remove (drop) database tdb01

\q

Quit (exit) psql

CREATE TABLE Apps("_device_id" VARCHAR(40),"created_local" DATE,"device_name" VARCHAR(40),"name" VARCHAR(120),"publisher" VARCHAR(120) ,"version" VARCHAR(120));

 

Create a table with columns

\dt+

Display the tables in the current database

\d+ apps

Display the columns in the apps04 table

COPY apps FROM '/tmp/Apps.csv' DELIMITER ',' CSV HEADER;

 

Import (copy) the CSV data in the file /tmp/Apps.csv into the table apps (ignore the first line of data as it has the headers for the CSV data)

SELECT * FROM apps;

Display the contents in all the columns in the apps table

SELECT NAME, count (*) from apps05 GROUP BY NAME ORDER BY COUNT DESC;

Count the number of unique values in the NAME column and display them in descending order

copy (select NAME, count (*) from apps04 GROUP BY NAME ORDER BY COUNT) to '/tmp/Appcount.txt' with csv;

Write (copy) the results of the query to the file /tmp/Appcount.txt in CSV format

New Docker commands used in this article:

Command

Notes

docker cp /tmp/Apps.csv postgresql01:/tmp/Apps.csv

 

Copy the content of /tmp/Apps.csv on the Docker host machine to the Docker instance postgresql01 in the file /tmp/Apps.csv

Conclusion
In this article, I showed you how to deploy PostgreSQL in a Docker container. I ran through a few psql commands to show its viability and explained how to perform Docker functions such as copying data from the Docker host to the container. Hopefully this gives you an idea for how easy it is to deploy a PostgreSQL database using a Docker image. This image can be deployed in the cloud or on the Edge as easily as it was my on-premises system. I deployed the latest PostgreSQL image, but I could have deployed older versions of PostgreSQL just as easily for regression testing.

In the next article, I will dive deeper into PostgreSQL and deploy additional Docker images for PostgreSQL management in order to demonstrate how multiple images interoperate with Docker containers.

Featured