Terminus
How To Launch A PostgreSQL Container In Docker

How To Launch A PostgreSQL Container In Docker

The short answer

In Docker, to launch a PostgreSQL container, you can use the following [.inline-code]docker run[.inline-code] command:

$ docker run -d \
-e POSTGRES_PASSWORD=<password> \
-p <host_port>:<container_port>
postgres

Where:

  • The [.inline-code]-d[.inline-code] flag is used to run the container in detached mode (i.e. in the background).
  • The [.inline-code]-e[.inline-code] flag is used to define environment variables for the container.
  • The [.inline-code]POSTGRES_PASSWORD[.inline-code] variable is used to set the PostgreSQL root password.
  • The [.inline-code]-p[.inline-code] flag is used to map the ports of the host and the container.
  • The [.inline-code]host_port[.inline-code] variable is the port on the host machine you want to map.
  • The [.inline-code]container_port[.inline-code] variable is the port on the container you want to expose.

For example:

$ docker run -d -e POSTGRES_PASSWORD=admin -p 5432:5432 postgres

This command launches the latest version of PostgreSQL in a Docker container in detached mode that matches the port 5432 of the host to the port 5432 of the container and sets the root username to [.inline-code]postgres[.inline-code] (default) and the root password to [.inline-code]admin[.inline-code].

If you are working with multi-container applications, you can read our article on how to launch PostgreSQL with Docker Compose.

[#easily-recall-with-ai] Easily retrieve this command using Warp’s AI Command Suggestions [#easily-recall-with-ai]

If you’re using Warp as your terminal, you can easily retrieve this command using the Warp AI Command Suggestions feature:

Entering [.inline-code]docker run postgres[.inline-code] in the AI Command Suggestions will prompt a [.inline-code]docker[.inline-code] command that can then quickly be inserted into your shell by doing [.inline-code]CMD+ENTER[.inline-code].

[#connect-to-the-container] Connecting to a Postgres container [#connect-to-the-container]

To connect to a PostgreSQL instance running within a Docker container, you can use the [.inline-code]docker exec[.inline-code] command combined with the [.inline-code]psql[.inline-code] command:

$ docker exec -it <container> psql -U <username>

Where:

  • [.inline-code]container[.inline-code] is the name or identifier of the Postgres container retrieved using the [.inline-code]docker ps[.inline-code] command.
  • [.inline-code]username[.inline-code] is the name of the Postgres user you want to connect to the database with.

Once connected, you can then use commands such as [.inline-code]\l[.inline-code] to list the databases or [.inline-code]\dt[.inline-code] to list the tables within the selected database.

For example:

$ docker exec -it database psql -U postgres

This command executes the [.inline-code]psql -U[.inline-code] command within the Postgres container named [.inline-code]database[.inline-code] using the default Postgres user named [.inline-code]postgres[.inline-code].

[#create-a-new-user] Creating a Postgres user [#create-a-new-user]

The default user created by the [.inline-code]postgres[.inline-code] image when launching a container is named [.inline-code]postgres[.inline-code].

To create a specific user with superuser privileges, you can use the [.inline-code]POSTGRES_USER[.inline-code] environment variable as follows:

$ docker run -d \
-e POSTGRES_USER=<username> \
-e POSTGRES_PASSWORD=<password> \
-p <host_port>:<container_port> \
postgres

Note that, the password defined in the [.inline-code]POSTGRES_PASSWORD[.inline-code] variable will be assigned to the user defined in the [.inline-code]POSTGRES_USER[.inline-code] variable.

For example:

$ docker run -d \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=admin \
-p 5432:5432 \
postgres

This command launches a Postgres container with a new root user named [.inline-code]admin[.inline-code], identified by the password [.inline-code]admin[.inline-code].

[#create-a-database] Creating a custom database [#create-a-database]

By default, Postgres creates a database matching the name of the user defined in the [.inline-code]POSTGRES_USER[.inline-code] variable.

To define a different name for the default database that is created when the image is first started, you can use the [.inline-code]POSTGRES_DB[.inline-code] variable as follows:

$ docker run -d\
-e POSTGRES_USER=<username>\
-e POSTGRES_PASSWORD=<password>\
-e POSTGRES_DB=<database>\
-p <host_port>:<container_port>\
postgres

For example:

$ docker run -d \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=admin \
-e POSTGRES_DB=myproject \
-p 5432:5432 postgres

This command launches a Postgres container with a new root user named [.inline-code]admin[.inline-code], identified by the password [.inline-code]admin[.inline-code], whose default database is [.inline-code]myproject[.inline-code].

[#persist-database-data] Persisting the database data [#persist-database-data]

By default, all the data present in a container's file system is automatically discarded as soon as the container is stopped and removed.

To preserve the database data on your local machine, you can either create a named volume, which is a data storage mechanism entirely managed by Docker, or a bind mount, which allows you to tie together a file on the host to a file within the container.

[#persist-data-with-volumes] Using a named volume [#persist-data-with-volumes]

To persist the Postgres data in a named volume, you can launch the Postgres container using the [.inline-code]docker run[.inline-code] command with the [.inline-code]-v[.inline-code] flag (short for [.inline-code]--volume[.inline-code]) as follows:

$ docker run -d \
-e POSTGRES_PASSWORD=<password> \
-v <volume>:/var/lib/postgresql/data \
-p <host_port>:<container_port> \
postgres

Where:

  • [.inline-code]volume[.inline-code] is the name of the volume.

For example:

$ docker run -d \
-e POSTGRES_PASSWORD=admin \
-v pgdata:/var/lib/postgresql/data \
-p 5432:5432 \
postgres

This command launches a Postgres container that stores the data generated by the container in the [.inline-code]/var/lib/postgresql/data[.inline-code] directory into the [.inline-code]pgdata[.inline-code] volume on the host.

Note that when using this command, Docker will automatically create the specified named volume if it doesn't exist.

[#persist-data-with-bind-mounts] Using a bind mount [#persist-data-with-bind-mounts]

On the other hand, to persist the Postgres data using a bind-mounted directory, you can launch the Postgres container using the [.inline-code]docker run[.inline-code] command with the [.inline-code]-v[.inline-code] flag (short for [.inline-code]--volume[.inline-code]) as follows:

$ docker run -d \
-e POSTGRES_PASSWORD=<password> \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v <host_mount_path>:/var/lib/postgresql/data \
-p <host_port>:<container_port> \
postgres

Where:

  • [.inline-code]PGDATA[.inline-code] is an environment variable used to specify the path to the subdirectory containing the database files within the container.
  • [.inline-code]host_mount_path[.inline-code] is the path to the bind-mounted directory on the host.

Note that, if the data volume you're using is a filesystem mountpoint, Postgres requires a subdirectory to be created within that mountpoint to contain the data.

For example:

$ docker run -d \
-e POSTGRES_PASSWORD=admin \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v /tmp/data:/var/lib/postgresql/data \
-p 5432:5432 \
postgres

This command launches a Postgres container that stores the data generated by the container in the [.inline-code]/var/lib/postgresql/data[.inline-code] directory into the [.inline-code]/tmp/data[.inline-code] directory on the host.

You can learn more about persisting data in Docker with our article on how to create bind mounts.

[#connect-to-pgadmin] Connecting pgAdmin to Postgres [#connect-to-pgadmin]

To manage your Postgres database using the pgAdmin interface, you can start by launching a pgAdmin container using the following [.inline-code]docker run[.inline-code] command:

$ docker run -d \
-e PGADMIN_DEFAULT_EMAIL=<email> \
-e PGADMIN_DEFAULT_PASSWORD=<password> \
-p <host_port>:<container_port> \
dpage/pgadmin4

Where:

  • [.inline-code]PGADMIN_DEFAULT_EMAIL[.inline-code] is used to create a new user account on pgAdmin.
  • [.inline-code]PGADMIN_DEFAULT_PASSWORD[.inline-code] is used as a password for the user account identified by [.inline-code]PGADMIN_DEFAULT_EMAIL[.inline-code].

Then connect to the pgAdmin interface by navigating to the following address [.inline-code]127.0.0.1:&lt;host_port&gt;[.inline-code] in your web browser.

For example:

$ docker run -d \
-e PGADMIN_DEFAULT_EMAIL=user@test.com \
-e PGADMIN_DEFAULT_PASSWORD=mysecret \
-p 8080:80
dpage/pgadmin4

This command launches a pgAdmin container in detached mode based on the [.inline-code]dpage/pgadmin4[.inline-code] image, that maps the port 8080 of the host to the port 80 (i.e. HTTP) of the container, to which you can connect to using the [.inline-code]user@test.com[.inline-code] email and [.inline-code]mysecret[.inline-code] password.

[#run-a-sql-script] Running a SQL script [#run-a-sql-script]

To run an SQL script against a containerized Postgres application, you can start by copying the script into the container using the [.inline-code]docker cp[.inline-code] command:

$ docker cp <src_path> <container>:<dst_path>

Where:

  • [.inline-code]src_path[.inline-code] is the path on your local machine of the SQL script you want to copy.
  • [.inline-code]container[.inline-code] is the name or the ID of the container you want to copy files to.
  • [.inline-code]dest_path[.inline-code] is the path in the container of the directory you want to copy the script to.

Then, connect into the container using the [.inline-code]docker exec[.inline-code] command:

$ docker exec -it <container> /bin/bash

Where:

  • [.inline-code]container[.inline-code] is the name or the ID of the container you want to connect into.

And finally, import the script into the Postgres database using the [.inline-code]psql[.inline-code] command with the input redirection operator ([.inline-code]&lt;[.inline-code]):

$ psql -U <username> -d <database> < <script>

Where:

  • [.inline-code]username[.inline-code] is the name of the user you want to connect to the database as.
  • [.inline-code]database[.inline-code] is the database you want to execute the script against.
  • [.inline-code]script[.inline-code] is the path within the container to the SQL script you want to execute.

For example:

$ docker cp ./script.sql database:/tmp
$ docker exec -it database /bin/bash
$ psql -U admin -d shop < /tmp/script.sql

These commands will, in order:

  1. Copy the local file named [.inline-code]script.sql[.inline-code] into the [.inline-code]/tmp[.inline-code] directory of the container named [.inline-code]database[.inline-code].
  2. Start an interactive shell session by executing the [.inline-code]bash[.inline-code] command within the [.inline-code]database[.inline-code] container.
  3. Execute the script as the [.inline-code]admin[.inline-code] user against the database named [.inline-code]shop[.inline-code].

If you want to learn more about these commands, you can learn our articles on how to copy files to a Docker container, how to run Bash in Docker, and how to run a SQL file with PSQL.