Skip to main content
Redhat Developers  Logo
  • Products

    Featured

    • Red Hat Enterprise Linux
      Red Hat Enterprise Linux Icon
    • Red Hat OpenShift AI
      Red Hat OpenShift AI
    • Red Hat Enterprise Linux AI
      Linux icon inside of a brain
    • Image mode for Red Hat Enterprise Linux
      RHEL image mode
    • Red Hat OpenShift
      Openshift icon
    • Red Hat Ansible Automation Platform
      Ansible icon
    • Red Hat Developer Hub
      Developer Hub
    • View All Red Hat Products
    • Linux

      • Red Hat Enterprise Linux
      • Image mode for Red Hat Enterprise Linux
      • Red Hat Universal Base Images (UBI)
    • Java runtimes & frameworks

      • JBoss Enterprise Application Platform
      • Red Hat build of OpenJDK
    • Kubernetes

      • Red Hat OpenShift
      • Microsoft Azure Red Hat OpenShift
      • Red Hat OpenShift Virtualization
      • Red Hat OpenShift Lightspeed
    • Integration & App Connectivity

      • Red Hat Build of Apache Camel
      • Red Hat Service Interconnect
      • Red Hat Connectivity Link
    • AI/ML

      • Red Hat OpenShift AI
      • Red Hat Enterprise Linux AI
    • Automation

      • Red Hat Ansible Automation Platform
      • Red Hat Ansible Lightspeed
    • Developer tools

      • Red Hat Trusted Software Supply Chain
      • Podman Desktop
      • Red Hat OpenShift Dev Spaces
    • Developer Sandbox

      Developer Sandbox
      Try Red Hat products and technologies without setup or configuration fees for 30 days with this shared Openshift and Kubernetes cluster.
    • Try at no cost
  • Technologies

    Featured

    • AI/ML
      AI/ML Icon
    • Linux
      Linux Icon
    • Kubernetes
      Cloud icon
    • Automation
      Automation Icon showing arrows moving in a circle around a gear
    • View All Technologies
    • Programming Languages & Frameworks

      • Java
      • Python
      • JavaScript
    • System Design & Architecture

      • Red Hat architecture and design patterns
      • Microservices
      • Event-Driven Architecture
      • Databases
    • Developer Productivity

      • Developer productivity
      • Developer Tools
      • GitOps
    • Secure Development & Architectures

      • Security
      • Secure coding
    • Platform Engineering

      • DevOps
      • DevSecOps
      • Ansible automation for applications and services
    • Automated Data Processing

      • AI/ML
      • Data Science
      • Apache Kafka on Kubernetes
      • View All Technologies
    • Start exploring in the Developer Sandbox for free

      sandbox graphic
      Try Red Hat's products and technologies without setup or configuration.
    • Try at no cost
  • Learn

    Featured

    • Kubernetes & Cloud Native
      Openshift icon
    • Linux
      Rhel icon
    • Automation
      Ansible cloud icon
    • Java
      Java icon
    • AI/ML
      AI/ML Icon
    • View All Learning Resources

    E-Books

    • GitOps Cookbook
    • Podman in Action
    • Kubernetes Operators
    • The Path to GitOps
    • View All E-books

    Cheat Sheets

    • Linux Commands
    • Bash Commands
    • Git
    • systemd Commands
    • View All Cheat Sheets

    Documentation

    • API Catalog
    • Product Documentation
    • Legacy Documentation
    • Red Hat Learning

      Learning image
      Boost your technical skills to expert-level with the help of interactive lessons offered by various Red Hat Learning programs.
    • Explore Red Hat Learning
  • Developer Sandbox

    Developer Sandbox

    • Access Red Hat’s products and technologies without setup or configuration, and start developing quicker than ever before with our new, no-cost sandbox environments.
    • Explore Developer Sandbox

    Featured Developer Sandbox activities

    • Get started with your Developer Sandbox
    • OpenShift virtualization and application modernization using the Developer Sandbox
    • Explore all Developer Sandbox activities

    Ready to start developing apps?

    • Try at no cost
  • Blog
  • Events
  • Videos

Connect a Quarkus app to an external PostgreSQL database

January 9, 2024
Nikhil Mungale
Related topics:
DatabasesKubernetesMicroservices
Related products:
Red Hat build of QuarkusRed Hat OpenShift

Share:

    Pedal is a simple e-commerce application to sell bikes, manage employees, and control inventory. The Java application uses the Quarkus microservice framework and Spring to serve a web front end and a representational state transfer (REST) service. It also connects to a PostgreSQL database and SQL Server database.

    Hosting this Quarkus application’s PostgreSQL database externally provides several advantages, including automated backups, robust data persistence, extensive maintenance tools, and more straightforward scaling. Using external databases also reduces the operational burden on your application’s development team.

    This guide helps you integrate Pedal’s external PostgreSQL database with one of its Quarkus microservices deployed on Red Hat OpenShift.

    Overview of the external PostgreSQL setup

    When connecting an OpenShift application to an external database, consider the following:

    • Network latency: Your PostgreSQL database’s location could increase latency in your APIs. For example, if you run a service on OpenShift with the Azure cloud platform in West Central 2 and your on-premise PostgreSQL database is in Australia, your API latency will be significant.  
    • Network bandwidth: Like network latency, your connection’s bandwidth can vary depending on the database’s location. Low-bandwidth connections between your OpenShift service and the PostgreSQL database could impact how you structure database transactions within your code.
    • Firewall rules: Connecting an OpenShift service to an on-premise PostgreSQL database requires adjusting your firewall. To keep the database connections as secure as possible, only allow port forwarding from your OpenShift cluster’s node IPs.

    In this tutorial, assume that your on-premise PostgreSQL database is accessible through a public hostname like postgres.example.com.

    Access the external PostgreSQL database from OpenShift

    Before attempting to connect to the external PostgreSQL database, remember to check for any preexisting NetworkPolicy objects that could hinder communication between your OpenShift pods and the external service. Administrators may have set unmodifiable default network policies that might affect how your environment manages network traffic. After ensuring these policies do not obstruct your connection, you can enable communication using one of the two following methods.

    Method 1: Service object and type

    For one, you can use a Service object with the type ExternalName. OpenShift creates a CNAME record for a fully qualified domain name that the specification describes. This approach makes the external PostgreSQL database accessible through its host.

    The following example service object for Pedal’s external PostgreSQL database is located in a service.yml file:

    kind: "Service"
    
    apiVersion: "v1"
    
    metadata:
    
     name: "pedal-postgres-service"
    
    spec: 
    
     type: ExternalName
    
     externalName: postgres.example.com
    
    selector: {}

    Unlike most service object configurations, this one doesn’t require you to specify any port bindings. To create this service, run the following command:

    oc create -f service.yml

    Method 2: Endpoints and service objects

    Alternatively, you can create Endpoints and Service objects. OpenShift provides the Endpoints object to let services communicate with one or more IP addresses.

    Specifying multiple addresses makes your database connections more robust. For example, if one IP address becomes unavailable due to a networking issue, the application can still use the others.

    The Pedal project might have an Endpoints manifest like the following:

    kind: "Endpoints"
    
    apiVersion: "v1"
    
    metadata:
    
      name: "pedal-postgres-service" 
    
    subsets: 
    
    - addresses:
    
      - ip: "172.45.3.2"
    
        ports:
    
        - name: "postgres"
    
          port: 5432
    
      - ip: "172.45.3.3"
    
        ports:
    
        - name: "postgres"
    
          port: 5432
    
    [Click and drag to move]
    ​

    To communicate with these endpoints, the Pedal application requires a Service object corresponding to the Endpoints object’s name above. This object’s manifest might look like the following:

    kind: "Service"
    
      apiVersion: "v1"
    
      metadata:
    
        name: "pedal-postgres-service"
    
      spec:
    
        ports:
    
          -
    
            name: "postgres"
    
            protocol: "TCP"
    
            port: 5432
    
            targetPort: 5432 
    
            nodePort: 0
    
      selector: {}

    Since there are no pods exposed with this service, the selector object doesn’t require expansion. Note that the Service and Endpoints objects synchronize via their name, postgres.

    Run the following command to create these objects:

    oc apply -f endpoints.yml,service.yml

    Test communication

    For either networking setup, to verify that your pods can communicate with the external service hosted at pedal-postgres-service.<namespace>.svc.cluster.local, ping it from a running container in your cluster.

    Configure database credentials securely

    Safeguarding your PostgreSQL credentials is vital for maintaining your database’s overall security. The OpenShift Secret object type provides a straightforward means of credential management. 

    Additionally, if you use external secret management systems like HashiCorp Vault, OpenShift supports the ExternalSecret object, letting you integrate and expose secrets from external sources directly into your OpenShift environment. This integration is particularly beneficial for Vault users, as it provides a seamless way to manage and use externally stored secrets. For more information on using External Secrets with systems like Vault, refer to Red Hat’s guide on external secrets.

    To create a Secret object to securely hold Pedal’s database credentials, create a secret.yml file and add the following code:

    apiVersion: v1
    
    kind: Secret
    
    metadata:
    
     name: pedal-postgres-credentials
    
    data:
    
     POSTGRES_PASSWORD: QVZOU19mSkpTVDVPS2NlSWEwS29rdzBzCg==
    
     POSTGRES_USER: cG9zdGdyZXMtdXNlcgo=

    All the data object’s values must be Base64-encoded. For example, to quickly encode your database username, run the following command:

    $ echo "postgres-user" | base64
    
    cG9zdGdyZXMtdXNlcgo=

    Run the following command to create the manifest described above:

    $ oc apply -f secret.yml

    The Quarkus OpenShift extension provides configuration operations to access OpenShift Secrets in your Quarkus project. First, run the following command to install the OpenShift extension in your Quarkus project.

    $ quarkus extension add openshift

    Alternatively, you can add the quarkus-openshift component when you start a new project. From the Quarkus project setup website, simply search for “openshift” in the setup interface and select the corresponding checkbox to include the OpenShift extension. This way, you can easily incorporate OpenShift capabilities from the very beginning of your project development.

    Add the following line to your project’s application.properties file to ingest the secret:

    quarkus.openshift.env.secrets=pedal-postgres-credentials

    Once you build the Quarkus application, the command adds the following specifications to its OpenShift container definition:

    envFrom:
    
      - secretRef:
    
          name: pedal-postgres-credentials
    
          optional: false

    The POSTGRES_PASSWORD and POSTGRES_USER values are available to the application as environment variables at runtime.

    Configure Quarkus DataSource for an external PostgreSQL database

    Next, add the following lines to Pedal’s application.properties file to provide the correct external host, database user, and password:

    quarkus.datasource.customers.jdbc.url=jdbc:postgresql://[postgresql address]
    
    quarkus.datasource.customers.username=${POSTGRES_USER}
    
    quarkus.datasource.customers.password=${POSTGRES_PASSWORD}

    Note that the ${} syntax specifies environment variables.

    To use different data sources for the production and development Quarkus profiles, specify the property with a %dev or %prod prefix. For example, if your database host’s development profile is on localhost, adjust the application.properties file to look like the following:

    %prod.quarkus.datasource.customers.jdbc.url=jdbc:postgresql://[postgresql prod address]
    
    %dev.quarkus.datasource.customers.jdbc.url=jdbc:postgresql://[postgresql dev address]

    The MicroProfile Config API offers the flexibility to inject configuration values in your Java code from the application.properties file or programmatically access them. For example, add the following code to your Java class to inject the value of configuration.property defined in the application.properties file:

    import org.eclipse.microprofile.config.inject.ConfigProperty;
    
    …
    
    @ConfigProperty(name = "configuration.property")
    
    String value;

    Similarly, add the following code to your Java class to programmatically access the same configuration.property value:

    import org.eclipse.microprofile.config.ConfigProvider;
    
    …
    
    String value = ConfigProvider.getConfig().getValue("configuration.property", String.class);

    Establish the database connection

    Incorporate ORM

    Quarkus supports Hibernate ORM, an object-relational mapping (ORM) library to seamlessly translate Java objects into relational database models. Run the following command to install the Hibernate ORM in your Quarkus project.

    $ quarkus ext add hibernate-orm

    You should receive a response like the following:

    [SUCCESS] ✅  Extension io.quarkus:quarkus-hibernate-orm has been installed

    Simply use the @Entity annotation above the class name to define a class to map to a PostgreSQL model. For example, the following code uses the Hibernate ORM to define a Pedal customer:

    import jakarta.persistence.*;
    
    import java.util.Date;
    
    import io.quarkus.hibernate.orm.panache.PanacheEntity;
    
    @Entity
    
    @Table(name="service_user")
    
    public class Customer extends PanacheEntity {
    
       public Customer(){}
    
       private String fullname;
    
       private String username;
    
       private String email;
    
       private Date date_created;
    
       private String password;
    
       private String user_role;
    
    }

    The code uses Hibernate’s Panache library to simplify entity definitions. You don’t have to explicitly define the database model’s column names for classes that extend the PanacheEntity abstract class. Hibernate also helps initialize your PostgreSQL database when the application boots.

    To generate the tables that your Hibernate entities describe, set the following property in your application.properties file:

    quarkus.hibernate-orm.database.generation=create

    Note that for sequential application boots, this operation fails since the tables already exist.

    The generation property also supports the none, create, drop-and-create, drop, update, and validate values.

    When the application boots, Hibernate runs arbitrary SQL commands defined in src/main/resources/import.sql. This approach lets you quickly initialize your local development PostgreSQL database.

    Implement health checks

    To ensure that the Pedal application runs well, it’s important to verify that the database connection is healthy at runtime. The SmallRye Health Quarkus extension creates an endpoint at /q/health that reports the status of the database connection. Execute the following command to add this endpoint to your Quarkus project:

    $ quarkus extension add quarkus-smallrye-health

    The response should look like this:

    [SUCCESS] ✅  Extension io.quarkus:quarkus-smallrye-health has been installed

    Now, you can call the API while running the development Quarkus application using the code below.

    $ curl localhost:8080/q/health
    
    {
    
    "status": "UP",
    
    "checks": [
    
         {
    
             "name": "Database connections health check",
    
             "status": "UP",
    
             "data": {
    
                 "<default>": "UP"
    
             }
    
         }
    
    ]
    
    }

    Additionally, you can specify an alternative API path. Set the quarkus.smallrye-health.root-path property in the application.properties file. 

    Secure the connection

    If your database’s SSL certification is signed by a trusted certificate authority (CA), you can quickly enable Secure Sockets Layer and Transport Layer Security (SSL/TLS) for your database connection. Append ?sslmode=require to the end of the quarkus.datasource.jdbc.url property, like below:

    quarkus.datasource.customers.jdbc.url=jdbc:postgresql:[postgresql url]

    Test the connectivity

    To rebuild and deploy your Quarkus application rapidly, execute the following command:

    $ quarkus build -Dquarkus.kubernetes.deploy=true

    Quarkus version 3 offers a new, streamlined command as a more Quarkus-centric means of handling deployments. It’s also a simpler process than using the JVM -D options. To use this new feature, execute:

    $ quarkus deploy openshift

    Regardless of which method you use, you can then run the following command to confirm that the Pedal application’s pods have started:

    $ oc get pods

    You should receive results similar to this:

    pedal-32-dqn7r 1/1 Running 0 24m
    
    pedal-34-deploy 0/1 Error 0 18m

    To verify that the application works correctly with an external database, call the signup API with a new user’s data, like below:

    $ curl -I --location 'localhost:8080/signup' \
    
    --header 'Content-Type: application/json' \
    
    --data-raw '{
    
       "email": "[email protected]",
    
       "username": "user",
    
       "fullname": "user",
    
       "user_role": "customer",
    
       "password": "password"
    
    }'
    
    HTTP/1.1 200 OK

    Summary

    When networking an external PostgreSQL database for an OpenShift service, you have two standard options: using a Service object with an ExternalName type or creating Endpoints and Service objects.

    Then, use OpenShift secrets to secure your database credentials and protect your connections. Quarkus seamlessly integrates OpenShift secrets specified in the application.properties file.

    The Hibernate ORM quickly sets up database models defined in Java classes and initializes your PostgreSQL database. Plus, the Quarkus SmallRye Health extension adds a simple health check endpoint to validate your Quarkus application’s connectivity with the PostgreSQL database. To fortify this connection further, configure your Quarkus data source to use SSL for database connections.

    With these steps, you have a solid understanding of how to establish connectivity between your Quarkus application and an external PostgreSQL database. Next, learn more about developing with Quarkus in OpenShift.

    Related Posts

    • Connect to an external PostgreSQL database using SSL/TLS for Red Hat's single sign-on technology

    • Simplify secure connections to PostgreSQL databases with Node.js

    • Using Red Hat's single sign-on technology with external databases, Part 1: Install and configure SSO with MariaDB

    • Running Microsoft SQL Server on Red Hat OpenShift

    • Fine-grained authorization for Quarkus microservices

    • How to build a Quarkus app on RHEL using Microsoft SQL Server

    Recent Posts

    • LLM Compressor: Optimize LLMs for low-latency deployments

    • How to set up NVIDIA NIM on Red Hat OpenShift AI

    • Leveraging Ansible Event-Driven Automation for Automatic CPU Scaling in OpenShift Virtualization

    • Python packaging for RHEL 9 & 10 using pyproject RPM macros

    • Kafka Monthly Digest: April 2025

    What’s up next?

    In this activity, discover how you can go from initial app idea to code in as little as five minutes. You'll scaffold a Quarkus application, build a container image locally using Podman Desktop, and then see how to install, run, and test the application in the Developer Sandbox from the command line.

    Start learning
    Red Hat Developers logoLinkedInYouTubeTwitterFacebook

    Products

    • Red Hat Enterprise Linux
    • Red Hat OpenShift
    • Red Hat Ansible Automation Platform

    Build

    • Developer Sandbox
    • Developer Tools
    • Interactive Tutorials
    • API Catalog

    Quicklinks

    • Learning Resources
    • E-books
    • Cheat Sheets
    • Blog
    • Events
    • Newsletter

    Communicate

    • About us
    • Contact sales
    • Find a partner
    • Report a website issue
    • Site Status Dasard
    • Report a security problem

    RED HAT DEVELOPER

    Build here. Go anywhere.

    We serve the builders. The problem solvers who create careers with code.

    Join us if you’re a developer, software engineer, web designer, front-end designer, UX designer, computer scientist, architect, tester, product manager, project manager or team lead.

    Sign me up

    Red Hat legal and privacy links

    • About Red Hat
    • Jobs
    • Events
    • Locations
    • Contact Red Hat
    • Red Hat Blog
    • Inclusion at Red Hat
    • Cool Stuff Store
    • Red Hat Summit

    Red Hat legal and privacy links

    • Privacy statement
    • Terms of use
    • All policies and guidelines
    • Digital accessibility

    Report a website issue