Comment on page
Spring and PostgreSQL
In this tutorial, we'll learn how to deploy a Java application on Release, using the Spring application framework with PostgreSQL as its database.
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.yamlto a template for new environments, then we'll explore how we can change the Release application slightly to follow best practices.
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:
│ ├── src
│ │ └── ... (Java app source)
│ ├── Dockerfile
│ └── pom.xml
│ └── password.txt
db, correspond to the two services defined in
Let's look at the two services in more detail.
You'll notice that the
backendfolder contains a Dockerfile, which, combined with the
build: backenddirective from
docker-compose.yaml, indicates that a Docker image needs to be built for the
backendservice before starting a container.
The service joins the
spring-postgresnetwork, and forwards port
8080on the host to port
8080on the container.
This service has one environmental variable,
POSTGRES_DB, which will be used as the PostgreSQL database name.
backend/srcfolder, you'll find the source code and other resources for the Java application. Of special interest is the
backend/src/main/resources/application.propertiesfile, where Spring boot looks for settings such as database connection strings.
This service needs a volume to save data in, has two environment variables (
POSTGRES_PASSWORD_FILE), and exposes the container port
dbfolder contains only one file,
password.txt, which the
dbservice can access as
We won't run this application locally for this tutorial, but if we were to run
docker-compose upfrom the root of this folder, we would expect Docker to go through the following steps:
backend/Dockerfileand pull dependencies from a Docker registry.
- 2.Build a
backendDocker image based on the steps in
backend/Dockerfile, and store the image locally.
- 3.Pull the
postgresimage from a Docker registry and store it locally.
- 4.Start a
backendcontainer by running the
backendimage built in step 2.
- 5.Start a
dbcontainer by running the
postgresimage retrieved in step 3.
- 6.Create a network called
spring-postgresand connect both running containers to this network.
Now that we have an idea of how Docker Compose would run this application, let's see how to add the application to Release.
Create an application
Enter a unique name for your application, and pick the forked repository you created earlier, then click Next step.
Enter a name and pick your repository
- 1.Pick Analyze the repository, so Release can create services from
- 2.Select the branch from your repository you'd like to track in this application.
- 3.Select the
- 4.Click Start analysis.
Pick your services
Release will read your Docker Compose file, and list the services found:
Pick your services showing analysis result
Click Next step.
Release will generate a template based on the services from your
Generate an application template
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.
The first change makes sure the
dbservice always starts before the
The Spring app we're installing runs database initialization scripts on startup. If there's no database to initialize, the
backendservice will fail to start.
The section of the template we want to edit is under
workflows.patch. Instead of running setup steps in parallel, we want them to follow a set order.
workflows.patchto look like this:
- name: setup
- name: patch
order_from, then list the tasks in the order we want Release to execute them:
Release does not currently convert
exposedirectives when importing services from Docker Compose. Add a
container_portfor each port in your Docker Compose file. Read more about ports in our template schema.
Add a container port to the
dbservice by adding the lines below:
- name: db
+ - type: container_port
+ port: '5432'
This change exposes port
5432on the database container to the private network between your services.
After editing the template, click Next step.
docker-compose.yamlfile from our repo lists the environment variables needed for each service. Both services use
POSTGRES_DB, and the
dbservice has one extra variable,
There's no database password environment variable in the
docker-compose.yaml, so we'll need to find out how the
backendservice knows the database password.
The Spring Boot application reads the database password from the
In our example application, this file has a database password setting,
spring.datasource.password, that looks like this:
The line above means that Spring will try to read the database password from the
POSTGRES_PASSWORDenvironment variable, but will use the hard-coded value
db-wrz2zif the variable
POSTGRES_PASSWORDdoes not exist.
We can see that
db-wrz2zmatches the password from
db/password.txtin our repository.
Instead of using this hard-coded password, we can set the
You'll notice that both the
backendservices can read this same environment variable to get the database password.
Let's set it to a random string, like
Set your environment variables
Edit the YAML environment variables in Release to look like this:
- key: POSTGRES_DB
- key: POSTGRES_PASSWORD
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
You'll notice that we marked
POSTGRES_PASSWORDas secret. This means that
POSTGRES_PASSWORDwill 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.
This application does not use any build arguments, so we can click Next step.
Click Save and deploy to create your application.
Release will now pull your repository and run
docker buildto build a Docker image of your
backendservice, before setting up and deploying your two services,
After the build, setup, and deployment workflow completes, navigate to your new environment and click on the URL for the backend service.
Service hosted URL
This request runs the
controllers.HomeController.showHomeJava function on the
backendservice, which reads a value from the PostgreSQL database running on the
dbservice, and returns the string
Hello from Docker!.
Hello from Docker!
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.