LogoLogo
  • Welcome to Release
  • Getting started
    • Quickstart
    • Create an account
    • Prepare to use Release
    • Create an application
      • Create custom application
      • Create from template
      • Servers vs runnables
    • Create an environment
  • Guides and examples
    • Domains and DNS
      • Manage domains
      • DNS and nameservers
        • Configure GoDaddy
        • Configure Cloudflare
        • Configure Namecheap
        • Other DNS hosts
      • Routing traffic
    • Example applications
      • Full stack voting app
      • Flask and RDS counter app
      • Static site with Gatsby
      • Golang with Postgres and Nginx
      • WordPress with MySQL
      • Spring and PostgreSQL
      • Terraform and Flask
      • OpenTelemetry demo
      • Load balancer with hostname
      • Static JavaScript service
      • SSH bastion access to services
      • ngrok and OAuth for private tunnels
      • Using OAuth Proxy
      • Hybrid Docker and static site
      • App Imports: Connecting two applications
      • Example library
    • Running instances
      • Cron jobs
      • Jobs
      • Using Helm charts
      • Using terminal
      • Viewing logs
      • Troubleshooting
        • ImagePullBackoff error
        • CrashLoopBackoff error
        • Exit codes
        • OOM: out of memory
    • Advanced guides
      • Containers guide
      • Application guide
      • Kubernetes guide
      • Create a cluster
      • Upgrade a cluster
      • Managing node groups
      • Patch node groups
      • Hostnames and rules
      • Serve traffic on multiple ports
      • Configure access to your K8s cluster
      • Designing for multiple environments
      • Microservices architecture
      • Monitoring your clusters
      • Performance tuning
      • Visibility and monitoring
      • Working with data
        • Container-based data
        • Seeding and migration
        • Cloud-provided data
        • Golden images
        • Third party
      • Pausing Instant Datasets
        • Application pausing schedules
        • Pause/resume environments
      • Infrastructure as code
        • Terraform
  • Reference documentation
    • Account settings
      • Account info
      • Managing users
      • Build settings
        • Build arguments
        • Build SSH keys
      • Add integrations
      • View clusters and cloud integrations
      • Add datasets
      • Environment handles
    • Workflows in Release
      • Stages of workflows
      • Serial deployments
      • Parallel deployments
      • Rolling deployments
      • Rainbow deployments
    • Networking
      • Network architecture (AWS)
      • Network architecture (GCP)
      • Ingresses
      • IP addresses
      • Cloud-provided services
      • Third-party services
    • Release environment versioning
    • Application settings
      • Application Template
        • Schema definition
      • Default environment variables
      • GitHub
      • Pull requests
      • GitOps
      • Just-in-time file mounts
      • Primary App Link
      • Create application FAQ
      • App-level build arguments
      • Parameters
      • Workspaces
    • End-to-end testing
    • Environment settings
      • Environment configuration
      • Environment variables
        • Environment variable mappings
        • Secrets vaults
        • Using Secrets with GitOps
        • Kubernetes Secrets as environment variables
        • Managing legacy Release Secrets
    • Environment expiration
    • Environment presets
    • Instant datasets on AWS
    • Instant datasets on GCP
    • Instant dataset tasks
      • Tonic Cloud
      • Tonic On-Premise
    • Cloud resources
    • Static service deployment
    • Helm
      • Getting started
      • Version-controlled Helm charts
      • Open-source charts
      • Building Docker images
      • Ingress and networking
      • Configuration
    • GitOps
    • The .release.yaml file
    • Docker Compose conversion support
    • Reference examples
      • Adding and removing services
      • Managing service resources
      • Adding database containers to the Application Template
      • Stock Off-The-Shelf Examples
    • Release API
      • Account Authentication
      • Environments API
        • Create
        • Get
        • Setup
        • Patch
      • User Authentication
      • Environment Presets API
        • Get Environment Preset List
        • Get Environment Preset
        • Put Environment Preset
  • Background concepts
    • How Release works
  • Frequently asked questions
    • Release FAQ
    • AWS FAQ
    • Docker FAQ
    • JavaScript FAQ
  • Integrations
    • Integrations overview
      • Artifactory integration
      • Cloud integrations (AWS)
        • AWS guides
        • Grant access to AWS resources
        • AWS how to increase EIP quota
        • Control your EKS fleet with systems manager
        • Managing STS access
        • AWS Permissions Boundaries
        • Private ECR Repositories
        • Using an Existing AWS VPC
        • Using an Existing EKS Cluster
      • Docker Hub integration
      • LaunchDarkly integration
      • Private registries
      • Slack integration
      • Cloud integrations (GCP)
        • GCP Permissions Boundary
      • Datadog Agent
      • Doppler Secrets Manager
      • AWS Secrets Management
    • Source control integrations
      • GitHub
        • Pull request comments
        • Pull request labels
        • GitHub deployments
        • GitHub statuses
        • Remove GitHub integration
      • Bitbucket
      • GitLab
    • Monitoring and logging add-ons
      • Datadog
      • New Relic
      • ELK (Elasticsearch, Logstash, and Kibana)
  • Release Delivery
    • Create new customer integration
    • Delivery guide
    • Release to customer account access controls
    • Delivery FAQs
  • Release Instant Datasets
    • Introduction
    • Quickstart
    • Security
      • AWS Instant Dataset security
    • FAQ
    • API
  • CLI
    • Getting started
    • Installation
    • Configuration
    • CLI usage example
    • Remote development environments
    • Command reference
      • release accounts
        • release accounts list
        • release accounts select
      • release ai
        • release ai chat
        • release ai config-delete
        • release ai config-init
        • release ai config-select
        • release ai config-upsert
      • release apps
        • release apps list
        • release apps select
      • release auth
        • release auth login
        • release auth logout
      • release builds
        • release builds create
      • release clusters
        • release clusters exec
        • release clusters kubeconfig
        • release clusters shell
      • release datasets
        • release datasets list
        • release datasets refresh
      • release deploys
        • release deploys create
        • release deploys list
      • release development
        • release development logs
        • release development start
      • release environments
        • release environments config-get
        • release environments config-set
        • release environments create
        • release environments delete
        • release environments get
        • release environments list
        • release environments vars-get
      • release gitops
        • release gitops init
        • release gitops validate
      • release instances
        • release instances exec
        • release instances logs
        • release instances terminal
  • Release.ai
    • Release.ai Introduction
    • Getting Started
    • Release.ai Templates
    • Template Configuration Basics
    • Using GPU Resources
    • Custom Workflows
    • Fine Tuning LlamaX
    • Serving Inference
Powered by GitBook
On this page
  • Requirements
  • Fork the spring-postgres example repository
  • An overview of the application
  • The backend service
  • The db service
  • How Docker Compose runs this app
  • Create a new application on Release
  • Name your application and select your repository
  • Pick your services
  • Generate a template
  • Start db before backend
  • Expose a container port on db
  • Environment variables
  • Setting the PostgreSQL database password via an environment variable
  • Set your environment variables
  • Build arguments
  • Save and deploy
  • View the resulting application
  • Troubleshooting
  • Further reading

Was this helpful?

  1. Guides and examples
  2. Example applications

Spring and PostgreSQL

PreviousWordPress with MySQLNextTerraform and Flask

Last updated 2 years ago

Was this helpful?

In this tutorial, we'll learn how to deploy a Java application on Release, using the Spring application framework with PostgreSQL as its database.

We'll start with the spring-postgres example application from . To help you focus on Spring and PostgreSQL only, we've created a repository with just the folder copied from Awesome Compose.

Because Release supports creating applications using Docker Compose, we won't need to change anything in the example repository to add this application to Release.

We'll take a look at how Release converts the settings from the application's docker-compose.yaml to a template for new environments, then we'll explore how we can change the Release application slightly to follow best practices.

Requirements

Before getting started, and (GitHub, Bitbucket, or GitLab) account.

Fork the spring-postgres example repository

Fork the repository to a private or public repository in the version control service you integrated with your Release account.

An overview of the application

Let's take a look at the contents of the repository, and try to figure out how this application is installed and started.

The repository looks like this:

.
├── backend
│   ├── src
│   │   └── ... (Java app source)
│   ├── Dockerfile
│   └── pom.xml
├── db
│   └── password.txt
├── README.md
└── docker-compose.yaml

Two folders, backend and db, correspond to the two services defined in docker-compose.yaml:

services:
  backend:
    build: backend
    #...
  db:
    image: postgres
    #...
#...

Let's look at the two services in more detail.

The backend service

Excerpt from docker-compose.yaml:

backend:
  build: backend
  ports:
    - 8080:8080
  environment:
    - POSTGRES_DB=example
  networks:
    - spring-postgres

You'll notice that the backend folder contains a Dockerfile, which, combined with the build: backend directive from docker-compose.yaml, indicates that a Docker image needs to be built for the backend service before starting a container.

The service joins the spring-postgres network, and forwards port 8080 on the host to port 8080 on the container.

This service has one environmental variable, POSTGRES_DB, which will be used as the PostgreSQL database name.

In the backend/src folder, you'll find the source code and other resources for the Java application. Of special interest is the backend/src/main/resources/application.properties file, where Spring boot looks for settings such as database connection strings.

The db service

Excerpt from docker-compose.yaml:

db:
  image: postgres
  restart: always
  secrets:
    - db-password
  volumes:
    - db-data:/var/lib/postgresql/data
  networks:
    - spring-postgres
  environment:
    - POSTGRES_DB=example
    - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
  expose:
    - 5432

This service needs a volume to save data in, has two environment variables (POSTGRES_DB and POSTGRES_PASSWORD_FILE), and exposes the container port 5432 on the spring-postgres network.

The db folder contains only one file, password.txt, which the db service can access as /run/secrets/db-password at runtime.

How Docker Compose runs this app

We won't run this application locally for this tutorial, but if we were to run docker-compose up from the root of this folder, we would expect Docker to go through the following steps:

  1. Read backend/Dockerfile and pull dependencies from a Docker registry.

  2. Build a backend Docker image based on the steps in backend/Dockerfile, and store the image locally.

  3. Pull the postgres image from a Docker registry and store it locally.

  4. Start a backend container by running the backend image built in step 2.

  5. Start a db container by running the postgres image retrieved in step 3.

  6. Create a network called spring-postgres and connect both running containers to this network.

Create a new application on Release

Now that we have an idea of how Docker Compose would run this application, let's see how to add the application to Release.

Log into Release, and create an application by clicking on Create new app.

Name your application and select your repository

Enter a unique name for your application, and pick the forked repository you created earlier, then click Next step.

Pick your services

  1. Pick Analyze the repository, so Release can create services from docker-compose.yaml.

  2. Select the branch from your repository you'd like to track in this application.

  3. Select the docker-compose.yaml file.

  4. Click Start analysis.

Release will read your Docker Compose file, and list the services found:

Click Next step.

Generate a template

Release will generate a template based on the services from your docker-compose.yaml file.

This template will be used to create new environments, and the defaults should work as expected for most Docker Compose applications.

For this example application, we'll need to make two changes to the template.

Start db before backend

The first change makes sure the db service always starts before the backend service.

The Spring app we're installing runs database initialization scripts on startup. If there's no database to initialize, the backend service will fail to start.

The section of the template we want to edit is under workflows.setup and workflows.patch. Instead of running setup steps in parallel, we want them to follow a set order.

Change workflows.setup and workflows.patch to look like this:

workflows:
- name: setup
  order_from:
    - services.db
    - services.backend
- name: patch
  order_from:
    - services.db
    - services.backend

Change parallelize to order_from, then list the tasks in the order we want Release to execute them: services.db, then services.backend.

Expose a container port on db

Add a container port to the db service by adding the lines below:

  services:
  - name: db
+   ports:
+   - type: container_port
+     port: '5432'

This change exposes port 5432 on the database container to the private network between your services.

After editing the template, click Next step.

Environment variables

The docker-compose.yaml file from our repo lists the environment variables needed for each service. Both services use POSTGRES_DB, and the db service has one extra variable, POSTGRES_PASSWORD_FILE.

Setting the PostgreSQL database password via an environment variable

There's no database password environment variable in the backend service from docker-compose.yaml, so we'll need to find out how the backend service knows the database password.

The Spring Boot application reads the database password from the backend/src/main/resources/application.properties file.

In our example application, this file has a database password setting, spring.datasource.password, that looks like this:

spring.datasource.password=${POSTGRES_PASSWORD:db-wrz2z}

The line above means that Spring will try to read the database password from the POSTGRES_PASSWORD environment variable, but will use the hard-coded value db-wrz2z if the variable POSTGRES_PASSWORD does not exist.

We can see that db-wrz2z matches the password from db/password.txt in our repository.

Instead of using this hard-coded password, we can set the POSTGRES_PASSWORD environment variable.

You'll notice that both the db and backend services can read this same environment variable to get the database password.

Let's set it to a random string, like xUnlL9U9J1Dh.

Set your environment variables

Edit the YAML environment variables in Release to look like this:

---
defaults:
  - key: POSTGRES_DB
    value: example
  - key: POSTGRES_PASSWORD
    value: UNwmSZpmo9Aj
    secret: true
services:
  backend: []
  db: []

Because both environment variables are used by both services, we don't need to specify them individually for each service. All services get all environment variables listed under the defaults section.

You'll notice that we marked POSTGRES_PASSWORD as secret. This means that POSTGRES_PASSWORD will be saved to an encrypted vault, and hidden from the Release interface after you save your changes.

Click Next step to save your environment variables.

Build arguments

This application does not use any build arguments, so we can click Next step.

Save and deploy

Click Save and deploy to create your application.

Release will now pull your repository and run docker build to build a Docker image of your backend service, before setting up and deploying your two services, db and backend.

View the resulting application

After the build, setup, and deployment workflow completes, navigate to your new environment and click on the URL for the backend service.

This request runs the controllers.HomeController.showHome Java function on the backend service, which reads a value from the PostgreSQL database running on the db service, and returns the string Hello from Docker!.

Troubleshooting

If you don't see the result above, you can view the logs for each service in your environment to see whether either service logged any errors.

To view a service's logs, navigate to your environment's details page, scroll down to the list of services, and click on logs.

Further reading

The db (short for database) service starts a container based on the docker image.

Release does not currently convert expose directives when importing services from Docker Compose. Add a container_port for each port in your Docker Compose file. Read more about in our template schema.

You can read more about in the template schema documentation.

The Docker image can read a password from a file specified in the POSTGRES_PASSWORD_FILE environment variable, or it can read the POSTGRES_PASSWORD environment variable directly.

Since Release supports adding , let's use a POSTGRES_PASSWORD environment variable instead of a password file.

If you would like to learn more about running Spring applications using Docker, view the guide from Spring.

Awesome Compose
spring-postgres
create a Release account
integrate your source control
spring-postgres
postgres
postgres
secrets as environment variables
Spring Boot with Docker
Create an application
Enter a name and pick your repository
Pick your services
Pick your services showing analysis result
Generate an application template
Set your environment variables
Service hosted URL
Hello from Docker!
Service logs
ports
workflow parallelization