Skip to content

Commit 914dbc5

Browse files
authored
Merge pull request #200179 from edburns/quarkus-crud-howto
Add Quarkus CRUD on App Service with Postgres tutorial
2 parents a5dccbb + ca593bc commit 914dbc5

File tree

4 files changed

+299
-0
lines changed

4 files changed

+299
-0
lines changed
244 KB
Loading
261 KB
Loading

articles/app-service/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@
5858
href: tutorial-python-postgresql-app.md
5959
- name: Java with Spring Data
6060
href: tutorial-java-spring-cosmosdb.md
61+
- name: Quarkus with Postgres
62+
href: tutorial-java-quarkus-postgresql-app.md
6163
- name: Custom containers
6264
items:
6365
- name: Deploy from ACR
Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
---
2+
title: 'Tutorial: Linux Java app with Quarkus and PostgreSQL'
3+
description: Learn how to get a data-driven Linux Quarkus app working in Azure App Service, with connection to a PostgreSQL running in Azure.
4+
author: denvermb
5+
ms.author: dbrittain
6+
ms.devlang: java
7+
ms.topic: tutorial
8+
ms.date: 5/27/2022
9+
ms.custom: mvc
10+
---
11+
12+
# Tutorial: Build a Quarkus web app with Azure App Service on Linux and PostgreSQL
13+
14+
This tutorial walks you through the process of building, configuring, deploying, and scaling Java web apps on Azure.
15+
When you are finished, you will have a [Quarkus](https://quarkus.io) application storing data in [PostgreSQL](/azure/postgresql) database running on [Azure App Service on Linux](overview.md).
16+
17+
![Screenshot of Quarkus application storing data in PostgreSQL.](./media/tutorial-java-quarkus-postgresql/quarkus-crud-running-locally.png)
18+
19+
In this tutorial, you learn how to:
20+
21+
> [!div class="checklist"]
22+
> * Create a App Service on Azure
23+
> * Create a PostgreSQL database on Azure
24+
> * Deploy the sample app to Azure App Service
25+
> * Connect a sample app to the database
26+
> * Stream diagnostic logs from App Service
27+
> * Add additional instances to scale out the sample app
28+
29+
[!INCLUDE [quickstarts-free-trial-note](../../includes/quickstarts-free-trial-note.md)]
30+
31+
## Prerequisites
32+
33+
* [Azure CLI](/cli/azure/overview), installed on your own computer.
34+
* [Git](https://git-scm.com/)
35+
* [Java JDK](/azure/developer/java/fundamentals/java-support-on-azure)
36+
* [Maven](https://maven.apache.org)
37+
38+
## Clone the sample app and prepare the repo
39+
40+
This tutorial uses a sample Fruits list app with a web UI that calls a Quarkus REST API backed by [Azure Database for PostgreSQL](/azure/postgresql). The code for the app is available [on GitHub](https://github.com/quarkusio/quarkus-quickstarts/tree/main/hibernate-orm-panache-quickstart). To learn more about writing Java apps using Quarkus and PostgreSQL, see the [Quarkus Hibernate ORM with Panache Guide](https://quarkus.io/guides/hibernate-orm-panache) and the [Quarkus Datasource Guide](https://quarkus.io/guides/datasource).
41+
42+
43+
Run the following commands in your terminal to clone the sample repo and set up the sample app environment.
44+
45+
```bash
46+
git clone https://github.com/quarkusio/quarkus-quickstarts
47+
cd quarkus-quickstarts/hibernate-orm-panache-quickstart
48+
```
49+
50+
## Create an App Service on Azure
51+
52+
1. Sign in to your Azure CLI, and optionally set your subscription if you have more than one connected to your sign-in credentials.
53+
54+
```azurecli
55+
az login
56+
az account set -s <your-subscription-id>
57+
```
58+
59+
2. Create an Azure Resource Group, noting the resource group name (referred to with `$RESOURCE_GROUP` later on)
60+
61+
```azurecli
62+
az group create \
63+
--name <a-resource-group-name> \
64+
--location <a-resource-group-region>
65+
```
66+
3. Create an App Service Plan. The App Service Plan is the compute container, it determines your cores, memory, price, and scale.
67+
68+
```azurecli
69+
az appservice plan create \
70+
--name "quarkus-tutorial-app-service-plan" \
71+
--resource-group $RESOURCE_GROUP \
72+
--sku B2 \
73+
--is-linux
74+
```
75+
4. Create an app service within the App Service Plan.
76+
77+
```azurecli
78+
WEBAPP_NAME=<a unique name>
79+
az webapp create \
80+
--name $WEBAPP_NAME \
81+
--resource-group $RESOURCE_GROUP \
82+
--runtime "JAVA|11-java11" \
83+
--plan "quarkus-tutorial-app-service-plan"
84+
```
85+
> [!IMPORTANT]
86+
> The `WEBAPP_NAME` must be **unique across all Azure**. A good pattern is to use a combination of your company name or initials of your name along with a good webapp name, for example `johndoe-quarkus-app`.
87+
88+
## Create an Azure PostgreSQL Database
89+
90+
Follow these steps to create an Azure PostgreSQL database in your subscription. The Quarkus Fruits app will connect to this database and store its data when running, persisting the application state no matter where you run the application.
91+
92+
1. Create the database service.
93+
94+
```azurecli
95+
DB_SERVER_NAME='msdocs-quarkus-postgres-webapp-db'
96+
ADMIN_USERNAME='demoadmin'
97+
ADMIN_PASSWORD='<admin-password>'
98+
99+
az postgres server create \
100+
--resource-group $RESOURCE_GROUP \
101+
--name $DB_SERVER_NAME \
102+
--location $LOCATION \
103+
--admin-user $DB_USERNAME \
104+
--admin-password $DB_PASSWORD \
105+
--sku-name GP_Gen5_2
106+
```
107+
108+
The following parameters are used in the above Azure CLI command:
109+
110+
* *resource-group* &rarr; Use the same resource group name in which you created the web app, for example `msdocs-quarkus-postgres-webapp-rg`.
111+
* *name* &rarr; The PostgreSQL database server name. This name must be **unique across all Azure** (the server endpoint becomes `https://<name>.postgres.database.azure.com`). Allowed characters are `A`-`Z`, `0`-`9`, and `-`. A good pattern is to use a combination of your company name and server identifier. (`msdocs-quarkus-postgres-webapp-db`)
112+
* *location* &rarr; Use the same location used for the web app.
113+
* *admin-user* &rarr; Username for the administrator account. It can't be `azure_superuser`, `admin`, `administrator`, `root`, `guest`, or `public`. For example, `demoadmin` is okay.
114+
* *admin-password* Password of the administrator user. It must contain 8 to 128 characters from three of the following categories: English uppercase letters, English lowercase letters, numbers, and non-alphanumeric characters.
115+
116+
> [!IMPORTANT]
117+
> When creating usernames or passwords **do not** use the `$` character. Later you create environment variables with these values where the `$` character has special meaning within the Linux container used to run Java apps.
118+
119+
* *public-access* &rarr; `None` which sets the server in public access mode with no firewall rules. Rules will be created in a later step.
120+
* *sku-name* &rarr; The name of the pricing tier and compute configuration, for example `GP_Gen5_2`. For more information, see [Azure Database for PostgreSQL pricing](https://azure.microsoft.com/pricing/details/postgresql/server/).
121+
122+
2. Configure the firewall rules on your server by using the [az postgres server firewall-rule create](/cli/azure/postgres/flexible-server/firewall-rule) command to give your local environment access to connect to the server.
123+
124+
```azurecli
125+
az postgres server firewall-rule create \
126+
--resource-group $RESOURCE_GROUP_NAME \
127+
--server-name $DB_SERVER_NAME \
128+
--name AllowMyIP \
129+
--start-ip-address <your IP> \
130+
--end-ip-address <your IP>
131+
```
132+
133+
Also, once your application runs on App Service, you'll need to give it access as well. run the following command to allow access to the database from services within Azure:
134+
135+
```azurecli
136+
az postgres server firewall-rule create \
137+
--resource-group $RESOURCE_GROUP_NAME \
138+
--server-name $DB_SERVER_NAME \
139+
--name AllowAllWindowsAzureIps \
140+
--start-ip-address 0.0.0.0 \
141+
--end-ip-address 0.0.0.0
142+
```
143+
3. Create a database named `fruits` within the Postgres service with this command:
144+
145+
```azurecli
146+
az postgres db create \
147+
--resource-group $RESOURCE_GROUP \
148+
--server-name $DB_SERVER_NAME \
149+
--name fruits
150+
```
151+
152+
## Configure the Quarkus app properties
153+
154+
Quarkus configuration is located in the `src/main/resources/application.properties` file. Open this file in your editor, and observe several default properties. The properties prefixed with `%prod` are only used when the application is built and deployed, for example when deployed to Azure App Service. When the application runs locally, `%prod` properties are ignored. Similarly, `%dev` properties are used in Quarkus' Live Coding / Dev mode, and `%test` properties are used during continuous testing.
155+
156+
Delete the existing content in `application.properties` and replace with the following to configure our database for dev, test, and production modes:
157+
158+
```properties
159+
quarkus.package.type=uber-jar
160+
%dev.quarkus.datasource.db-kind=h2
161+
%dev.quarkus.datasource.jdbc.url=jdbc:h2:mem:fruits
162+
163+
%test.quarkus.datasource.db-kind=h2
164+
%test.quarkus.datasource.jdbc.url=jdbc:h2:mem:fruits
165+
166+
%prod.quarkus.datasource.db-kind=postgresql
167+
%prod.quarkus.datasource.jdbc.url=jdbc:postgresql://${DBHOST}.postgres.database.azure.com:5432/${DBNAME}?user=${DBUSER}@${DBHOST}&password=${DBPASS}
168+
%prod.quarkus.hibernate-orm.sql-load-script=import.sql
169+
170+
quarkus.hibernate-orm.database.generation=drop-and-create
171+
```
172+
173+
> [!IMPORTANT]
174+
> Be sure to keep the dollar signs and braces intact when copying and pasting the above for the variables `${DBHOST}`, `${DBNAME}`, `${DBUSER}`, and `${DBPASS}`. We'll set the actual values later in our environment so that we don't expose them hard-coded in the properties file, and so that we can change them without having to re-deploy the app.
175+
176+
## Run the sample app locally
177+
178+
Use Maven to run the sample.
179+
180+
```bash
181+
mvn quarkus:dev
182+
```
183+
184+
This will build the app, run its unit tests, and then start the application in developer live coding. You should see:
185+
186+
```output
187+
__ ____ __ _____ ___ __ ____ ______
188+
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
189+
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
190+
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
191+
INFO [io.quarkus] (Quarkus Main Thread) hibernate-orm-panache-quickstart 1.0.0-SNAPSHOT on JVM (powered by Quarkus x.x.x.Final) started in x.xxxs. Listening on: http://localhost:8080
192+
193+
INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
194+
INFO [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, hibernate-orm-panache, jdbc-h2, jdbc-postgresql, narayana-jta, resteasy-reactive, resteasy-reactive-jackson, smallrye-context-propagation, vertx]
195+
```
196+
197+
You can access Quarkus app locally by typing the `w` character into the console, or using this link once the app is started: `http://localhost:8080/`.
198+
199+
![Screenshot of Quarkus application storing data in PostgreSQL.](./media/tutorial-java-quarkus-postgresql/quarkus-crud-running-locally.png)
200+
201+
If you see exceptions in the output, double-check that the configuration values for `%dev` are correct.
202+
203+
> [!TIP]
204+
> You can enable continuous testing by typing `r` into the terminal. This will continously run tests as you develop the application. You can also use Quarkus' *Live Coding* to see changes to your Java or `pom.xml` immediately. Simlply edit code and reload the browser.
205+
206+
When you're done testing locally, shut down the application with `CTRL-C` or type `q` in the terminal.
207+
208+
## Configure App Service for Database
209+
210+
Our Quarkus app is expecting various environment variables to configure the database. Add these to the App Service environment with the following command:
211+
212+
```azurecli
213+
az webapp config appsettings set \
214+
-g $RESOURCE_GROUP \
215+
-n $WEBAPP_NAME \
216+
--settings \
217+
'DBHOST=$DB_SERVER_NAME' \
218+
'DBNAME=fruits' \
219+
'DBUSER=$ADMIN_USERNAME' \
220+
'DBPASS=$ADMIN_PASSWORD' \
221+
'PORT=8080' \
222+
'WEBSITES_PORT=8080'
223+
```
224+
> [!NOTE]
225+
> The use of single quotes (`'`) to surround the settings is required if your password has special characters.
226+
227+
Be sure to replace the values for `$RESOURCE_GROUP`, `$WEBAPP_NAME`, `$DB_SERVER_NAME`, `$ADMIN_USERNAME`, and `$ADMIN_PASSWORD` with the relevant values from previous steps.
228+
229+
## Deploy to App Service on Linux
230+
231+
Build the production JAR file using the following command:
232+
233+
```azurecli
234+
mvn clean package
235+
```
236+
237+
The final result will be a JAR file in the `target/` subfolder.
238+
239+
To deploy applications to Azure App Service, developers can use the [Maven Plugin for App Service](/learn/modules/publish-web-app-with-maven-plugin-for-azure-app-service/), [VSCode Extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azureappservice), or the Azure CLI to deploy apps. Use the following command to deploy our app to the App Service:
240+
241+
```azurecli
242+
az webapp deploy \
243+
--resource-group $RESOURCE_GROUP \
244+
--name $WEBAPP_NAME \
245+
--src-path target/*.jar --type jar
246+
```
247+
248+
You can then access the application using the following command:
249+
250+
```azurecli
251+
az webapp browse \
252+
--resource-group $RESOURCE_GROUP \
253+
--name $WEBAPP_NAME
254+
```
255+
256+
> [!TIP]
257+
> You can also manually open the location in your browser at `http://<webapp-name>.azurewebsites.net`. It may take a minute or so to upload the app and restart the App Service.
258+
259+
You should see the app running with the remote URL in the address bar:
260+
261+
![Screenshot of Quarkus application storing data in PostgreSQL running remotely.](./media/tutorial-java-quarkus-postgresql/quarkus-crud-running-remotely.png)
262+
263+
If you see errors, use the following section to access the log file from the running app:
264+
265+
## Stream diagnostic logs
266+
267+
[!INCLUDE [Access diagnostic logs](../../includes/app-service-web-logs-access-no-h.md)]
268+
269+
## Scale out the app
270+
271+
Scale out the application by adding another worker:
272+
273+
```azurecli
274+
az appservice plan update --number-of-workers 2 \
275+
--name quarkus-tutorial-app-service-plan \
276+
--resource-group $RESOURCE_GROUP
277+
```
278+
279+
## Clean up resources
280+
281+
If you don't need these resources for another tutorial (see [Next steps](#next-steps)), you can delete them by running the following command in the Cloud Shell or on your local terminal:
282+
```azurecli
283+
az group delete --name $RESOURCE_GROUP --yes
284+
```
285+
286+
## Next steps
287+
288+
[Azure for Java Developers](/java/azure/)
289+
[Quarkus](https://quarkus.io),
290+
[Getting Started with Quarkus](https://quarkus.io/get-started/),
291+
and
292+
[App Service Linux](overview.md).
293+
294+
Learn more about running Java apps on App Service on Linux in the developer guide.
295+
296+
> [!div class="nextstepaction"]
297+
> [Java in App Service Linux dev guide](configure-language-java.md?pivots=platform-linux)

0 commit comments

Comments
 (0)