Fooling around with Docker CLI commands with PostgreSQL image

14 / Jan / 2023 by shivang.chaturvedi 0 comments

Currently, I am developing a side project wherein I wanted to use Postgres as my project database using its docker image. This blog is my brain dump of the docker basics I have learned so far, and I have attempted to break down the CLI commands I used or came across during the course of development for my own better understanding.

We’ll start with simple basics like:

  1. Docker: A definition
  2. Docker Image
  3. Docker Container

Feel free to skip these sections if you know these concepts already. Finally, I’ll explain how you can download Postgres images from the docker hub, and we will jump right into CLI Commands.

Note: Please note that this blog assumes that you have docker already installed in your system. If not, then you can download it from here.

Docker: A definition

Docker is an open-source project for building the shipping and running programs. It is a command line program, a background process and a set of remote services that simplifies your experience of installing, running, publishing and removing a software.

It accomplishes this by using something called containers.

Docker Image

An image is a program bundled/packaged together with the dependencies required to run that program.

Docker Container

container is a running instance of an image. The running state of a container is directly tied to the running state of the program inside the container. Unlike virtual machines, Docker containers do not use any hardware virtualization.

Docker is not a hardware virtualization technology but it helps you use container technology already built into your operating system kernel.

Run Postgres image locally using docker

docker pull postgres:<version>

#Example
docker pull postgres:15.1

You can checkout the available image versions at https://hub.docker.com/_/postgres.

Start the postgres instance on docker along with its Port Mapping:

docker run --name <container_name> -e POSTGRES_USER=root -e POSTGRES_PASSWORD=root -p 5432:5432 -d postgres:<version>

#example:
docker run --name myPostgres -e POSTGRES_USER=root -e POSTGRES_PASSWORD=root -p 5432:5432 -d postgres:15.1

This command returns a long unique ID:

Let’s break this down:

  1. run command looks for the image locally or remotely(docker hub which is a public docker repository). If found, run installs the image if it isn’t already. Finally, it creates and starts the container immediately.
  2. -d flag is used for telling the docker to run the container in the background or detached mode
  3. -e flag is used for passing the environment variables if we want to customise the containers by passing environment variables like POSTGRES_USER or POSTGRES_PASSWORD . Similarly, the environment variable POSTGRES_DB can be used to define the name of the database. If name is not defined, the POSTGRES_USER is taken as default name for database.
  4. 5432:5432 is the port mapping of the running instance. Docker container runs in a separate virtual network which is different from the host network that we are on. So we cannot simply connect to the postgres server running on the port 5432 of the container network unless we tell docker to create a kind of a bridge between our localhost network and the container’s network. We do that by using the -p flag (which means port), then specify the port of the host network followed by a colon, then the corresponding port of the container network :
    -p <host_network_port>:<container_network_port>Example: -p 5432:5432 .
    <host_network_port> and <container_network_port> cannot necessarily be the same but we can set the same port for the sake of convenience while developing locally.

A container is an instance of the application contained in the image which can be started by docker run command. We can start multiple containers from one single image.

Run the following command to list the containers:

//This will list all the running containers
docker ps 

//or 

//This will list all the containers regardless of their status(active or inactive)
docker ps -a


Voila ?, our container is running!

Connecting to Postgres container console:

Now that the postgres server is ready, we can connect to it and access its console by using the docker exec command as follows:

// syntax: docker exec -it <CONTAINER_NAME_OR_ID> <CMD> -U <USER>

docker exec -it myPostgres psql -U root

The docker exec command runs or “Executes” a new command in a running container.

Lets take a deep dive:

  1. -it flag tells docker to run the command as an interactive TTY**(terminal = tty = text input/output environment)** session
  2. psql will enable us to access the postgres console
  3. -U flag tells the psql that we want to connect with the root user
  4. In localhost, postgres container doesn’t need a password as postgres image sets up Trust Authentication mechanism for authenticating a user. However, a password will be needed if connecting from a different host or container.

That worked well!! 🙂

Connecting to the container shell:

The shell for postgres running container can be accessed through the following command:

docker exec -it <CONTAINER_NAME> <EXECUTABLE>

#example
docker exec -it myPostgres /bin/sh

This gives us access to all the linux commands.

/bin/sh is an executable representing the system shell and usually implemented as a symbolic link pointing to the executable for whichever shell is the system shell. The system shell is basically the default shell that the script should use.

woohooo.. I can run linux commands on my container shell

Using shell to execute database commands:

We can use the shell to execute the database commands

createdb --username=<USERNAME> --owner=<USERNAME> <DB_NAME>

#Example
createdb --username=root --owner=root test_database

I can see a newly created test_database on “TablePlus” database list

Just like createdb , you can drop your database using the command dropdb <DB_NAME> inside the shell.

You can use the exit command to come out of the container shell.

Now from outside the container, we chain the createdb command directly with the docker exec command:

docker exec -it <CONTAINER_NAME> createdb --username=root --owner=root <DB_NAME>

#Example
docker exec -it myPostgres createdb --username=root --owner=root test_database

Similarly, other database operations can be chained with docker exec command like:

#Example 1
docker exec -it myPosygres dropdb test_database

#Example 2 : if you want to access postgres console of test_database
docker exec -it myPostgres psql test_database

Some more useful commands:

  1. If you want to stop a running container, you can use the following command: docker stop <CONTAINER_NAME_OR_ID>
  2. If you want to run a container again, you can use the following command: docker start <CONTAINER_NAME_OR_ID>
  3. If you have stopped your container and you want to completely remove it, you can run the following command: docker rm <CONTAINER_NAME> . This command will not work unless you have stopped your container.

Difference between docker create, start and run:

Here’s what these commands do:

  1. docker create command creates a fresh new container from a docker image. However, it doesn’t run it immediately.
  2. docker start command will start any stopped container. If you used docker create command to create a container, you can start it with this command.
  3. docker run command is a combination of create and start as it creates a new container and starts it immediately. In fact, the docker run command can even pull an image from Docker Hub if it doesn’t find the mentioned image on your system.

Note of thanks ❤️

Thank you for stopping by. Hope, you find this article useful. If you do, please follow me on medium. That will truly encourage me to put out more content.

P.S.: If you feel something can be improved or lacks proper explanation, drop me a note in the comment box or mail me at shiva.chaturvedi91@gmail.com. After all, you can teach me a thing or two as well.

 

FOUND THIS USEFUL? SHARE IT

Leave a Reply

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