Skip to content

Commit 900e234

Browse files
authored
Merge pull request #119 from redhat-developer-demos/openshift-sandbox
Add Openshift Sandbox as a deployment target
2 parents 0cc2a2a + 58737fd commit 900e234

6 files changed

Lines changed: 161 additions & 45 deletions

File tree

29.8 KB
Loading
221 KB
Loading

documentation/modules/ROOT/pages/dev-services.adoc

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
= Dev Services
22

3-
Quarkus supports the automatic provisioning of unconfigured services in *development and test* mode.
3+
Quarkus supports the automatic provisioning of unconfigured services in *dev and test* mode.
44
We refer to this capability as Dev Services. From a developer's perspective this means that if you include an extension and don't configure it then Quarkus will automatically start the relevant service (usually using https://www.testcontainers.org/[Testcontainers] behind the scenes) and wire up your application to use this service, even pre-configuring access credentials.
55

66
NOTE: Dev Services will only be enabled in dev/test mode, so it will not affect the application running in production. If you want to disable all Dev Services you can use the quarkus.devservices.enabled=false config property, or you can simply configure the service in which case it will result in the Dev Service being disabled automatically.
@@ -11,7 +11,7 @@ More on zero config setup of datasources can be found https://quarkus.io/guides/
1111

1212
== Replace Database Extensions
1313

14-
Instead of the built-in h2 database, we're now going to use an external database. Swapping out from one database provider to another is fairly trivial with Quarkus. We just remove the h2 extension and add the postgresql extension instead:
14+
Instead of the built-in h2 database, we're now going to use an external database. Swapping out from one database provider to another is fairly trivial with Quarkus. In our case we just need to remove the h2 extension and add the postgresql extension instead:
1515

1616

1717
[tabs]
@@ -42,9 +42,9 @@ quarkus extension add quarkus-jdbc-postgresql
4242

4343
== Update configuration
4444

45-
We'll also need to update the configuration and change h2 to postgresql:
45+
Update the configuration and change h2 to postgresql by updating the application.properties:
4646

47-
TIP: Technically you don't need to add the db-kind property since there is only one jdbc driver in this case. We added it for clarity's sake.
47+
TIP: You technically don't need to add the db-kind property since there is only one jdbc driver in our application. We added it for clarity's sake.
4848

4949
[#quarkuspdb-update-props]
5050
[.console-input]
@@ -58,22 +58,17 @@ quarkus.hibernate-orm.database.generation=drop-and-create
5858
----
5959

6060

61-
62-
63-
You will now see that Quarkus has reloaded and started up a Postgresql database dev service:
61+
Notice in the logs how Quarkus has reloaded and started up a Postgresql database dev service:
6462

6563
[.console-output]
6664
[source,text]
6765
----
68-
69-
--
70-
Checking Podman Environment
7166
2023-03-16 08:06:56,882 INFO [io.qua.dat.dep.dev.DevServicesDatasourceProcessor] (build-13) Dev Services for the default datasource (postgresql) started - container ID is c7c9a6ccf029
7267
----
7368

7469
== Verify Postgresql testcontainer is running
7570

76-
You can now also verify/access the dev services container via Podman:
71+
Let's verify in Docker/Podman that the dev services container is running. You should see 2 containers, one testcontainers/ryuk container which orchestrates the dev services, and another postgres container which is running the database and which is automatically wired into our Quarkus dev mode:
7772

7873
[.console-input]
7974
[source,bash,subs="+macros,+attributes"]
@@ -84,7 +79,7 @@ docker ps
8479
[.mt-4.center]
8580
image::Dev_Services_Podman_ps.png[Dev Services Container,800,100,align="left"]
8681

87-
You can check to see that the fruit endpoint is still working, but in this case the data is coming from the postgresql database.
82+
Call the fruit endpoint again. The data is now coming from the postgresql database container.
8883

8984
[.console-input]
9085
[source,bash,subs="+macros,+attributes"]
@@ -109,6 +104,70 @@ curl localhost:8080/fruit?season=Spring
109104
]
110105
----
111106

107+
== Run Unit Tests with TestContainers
108+
109+
Let's stop dev mode for now to verify that the Postgres container also stops when we're done with dev mode by sending a `CTRL+C` in the terminal and checking again with docker ps. Notice that the postgres container has disappeared as expected.
110+
111+
[.console-input]
112+
[source,bash,subs="+macros,+attributes"]
113+
----
114+
docker ps
115+
----
116+
117+
[.mt-4.center]
118+
image::Dev_Services_Stopped.png[Dev Services Stopped,800,100,align="left"]
119+
120+
Run the tests:
121+
122+
[tabs%sync]
123+
====
124+
Maven::
125+
+
126+
--
127+
[.console-input]
128+
[source,bash,subs="+macros,+attributes"]
129+
----
130+
mvn test
131+
----
132+
133+
--
134+
Quarkus CLI::
135+
+
136+
--
137+
[.console-input]
138+
[source,bash,subs="+macros,+attributes"]
139+
----
140+
quarkus test
141+
----
142+
143+
Reminder: Once the tests have run, send `CTRL+C` since Quarkus CLI starts tests in continuous mode.
144+
--
145+
====
146+
147+
Notice in the logs that Quarkus and TestContainers work in unison to spin up the Postgres container again, run the tests, and then tear down the container again once done.
148+
149+
[.console-output]
150+
[source,text]
151+
----
152+
[INFO] -------------------------------------------------------
153+
[INFO] T E S T S
154+
[INFO] -------------------------------------------------------
155+
[INFO] Running com.redhat.developers.GreetingResourceTest
156+
2023-07-04 17:40:04,096 INFO [org.tes.doc.DockerClientProviderStrategy] (build-23) Found Docker environment with Environment variables, system properties and defaults. Resolved dockerHost=unix:///run/user/1000/podman/podman.sock
157+
2023-07-04 17:40:04,100 INFO [org.tes.DockerClientFactory] (build-23) Docker host IP address is localhost
158+
2023-07-04 17:40:04,235 INFO [org.tes.DockerClientFactory] (build-23) Connected to docker:
159+
Server Version: 4.5.1
160+
API Version: 1.41
161+
Operating System: fedora
162+
Total Memory: 31787 MB
163+
2023-07-04 17:40:04,254 INFO [org.tes.uti.ImageNameSubstitutor] (build-23) Image name substitution will be performed by: DefaultImageNameSubstitutor (composite of 'ConfigurationFileImageNameSubstitutor' and 'PrefixingImageNameSubstitutor')
164+
2023-07-04 17:40:04,257 INFO [org.tes.DockerClientFactory] (build-23) Checking the system...
165+
2023-07-04 17:40:04,258 INFO [org.tes.DockerClientFactory] (build-23) ✔︎ Docker server version should be at least 1.6.0
166+
2023-07-04 17:40:05,038 INFO [tc.doc.io/postgres:14] (build-23) Creating container for image: docker.io/postgres:14
167+
----
168+
169+
170+
112171

113172
== [Optional] Re-deploy to Kubernetes
114173

@@ -132,9 +191,9 @@ NOTE: We added a %prod. prefix to some of the properties. This prefix makes it
132191

133192
=== Create a postgresql database
134193

135-
There are several ways to deploy a Postgresql Database to Kubernetes. If you're using Openshift, you could create one easily through the UI (Developer Perspective > +Add > Database > PostgreSQL). Just make sure your database name, username and password match up with what you have configured in your application.properties or secrets.
194+
There are several ways to deploy a Postgresql Database to Kubernetes. If you're using Openshift, you could create one easily through the UI (Developer Perspective > +Add > Database > PostgreSQL). Make sure your database name, username and password match up with what you have configured in your application.properties or secrets.
136195

137-
You can also create the following Kubernetes manifest for a simple ephemeral instance:
196+
Alternatively you can also create the following Kubernetes manifest for a simple ephemeral instance:
138197

139198
[.console-input]
140199
[source,bash,subs="+macros,+attributes"]

documentation/modules/ROOT/pages/kubernetes.adoc

Lines changed: 77 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
= Deploying to Kubernetes
22

3-
IMPORTANT: You will need a public container registry to store your image. If you don't have an account, we recommend you to create a free account at http://quay.io[window=_blank].
3+
[.mt-4.right]
4+
image::openshift_sandbox.png[Openshift Sandbox,250,250,align="right",link="https://developers.redhat.com/developer-sandbox"]
5+
6+
In this chapter we will push our newly built application to Kubernetes. If you don't have a Kubernetes instance at your disposal, you can create a free Openshift Sandbox instance on https://developers.redhat.com/developer-sandbox[developers.redhat.com/sandbox].
7+
8+
9+
10+
IMPORTANT: You will need a public container registry to store your image. If you don't have an account, we recommend to create a free account at http://quay.io[window=_blank].
411

512
Our examples will be using the `quay.io` container registry and the `myrepo` organization, but you should change it to match your configuration.
613

714
== Adding the Kubernetes and Jib extensions
815

9-
You need a container registry that is accessible from your Kubernetes cluster to deploy the application container image in it.
10-
1116
In this chapter we'll be using the Quarkus Kubernetes Extension to create the Kubernetes deployment file, and the Quarkus Jib Extension to create and push the container image to your container registry without the need of a local podman/docker instance.
1217

1318
Let's add the required extensions:
@@ -54,12 +59,13 @@ quarkus.container-image.registry=quay.io#<1>
5459
quarkus.container-image.group=myrepo#<2>
5560
quarkus.container-image.name=tutorial-app#<3>
5661
quarkus.container-image.tag=1.0-SNAPSHOT#<4>
57-
quarkus.kubernetes.service-type=load-balancer
62+
quarkus.kubernetes.service-type=load-balancer<5>
5863
----
5964
<1> Registry where image is pushed. By default this is Docker Hub.
6065
<2> Group name of the container image.
6166
<3> Container name. By default is the `artifactId` element of `pom.xml`.
6267
<4> Tag of the container image. By default is the `version` element of `pom.xml`.
68+
<5> Create an external ip for the service.
6369

6470
IMPORTANT: Change `quay.io` to your container registry and `myrepo` to your organization.
6571
If you don't, your push *will* fail.
@@ -74,7 +80,7 @@ In order to push the container image, you need to authenticate to your container
7480
docker login quay.io
7581
----
7682

77-
Now create and push your container image using jib:
83+
Now we're going to create the artifact, build a container and push it to our registry in one go using jib.
7884

7985
[tabs]
8086
====
@@ -84,7 +90,7 @@ Maven::
8490
[.console-input]
8591
[source,bash,subs="+macros,+attributes"]
8692
----
87-
mvn clean package -DskipTests -Dquarkus.container-image.push=true
93+
mvn clean package -DskipTests -Dquarkus.container-image.push=true -Dquarkus.container-image.builder=jib
8894
----
8995
9096
--
@@ -94,11 +100,13 @@ Quarkus CLI::
94100
[.console-input]
95101
[source,bash,subs="+macros,+attributes"]
96102
----
97-
quarkus image push --also-build --no-tests
103+
quarkus image build jib --no-tests -Dquarkus.container-image.push=true
98104
----
99105
--
100106
====
101107

108+
NOTE: You can also use Docker/Podman to build & push. To do so, just omit 'jib' from the command.
109+
102110
[.console-output]
103111
[source,text]
104112
----
@@ -115,15 +123,35 @@ quarkus image push --also-build --no-tests
115123
[INFO] ------------------------------------------------------------------------
116124
----
117125

126+
127+
118128
== Deploy your application to your Kubernetes cluster
119129

120-
When a Kubernetes extension is present in the classpath, a Kubernetes deployment file is scaffolded for you during the package phase.
130+
When a Kubernetes extension is present in the classpath, Quarkus will scaffold a Kubernetes deployment file in your target folder during the package phase. We can apply it to deploy the application to our Kubernetes cluster:
131+
132+
NOTE: You will need the https://kubernetes.io/docs/tasks/tools/[kubectl] or oc cli tool installed locally for the apply command below. https://developers.redhat.com/blog/2021/04/21/access-your-developer-sandbox-for-red-hat-openshift-from-the-command-line#[Here are instructions] to install the oc tool and log in to your Openshift Sandbox.
121133

134+
[tabs]
135+
====
136+
kubectl::
137+
+
138+
--
122139
[.console-input]
123140
[source,bash]
124141
----
125142
kubectl apply -f target/kubernetes/kubernetes.yml
126143
----
144+
--
145+
oc::
146+
+
147+
--
148+
[.console-input]
149+
[source,bash]
150+
----
151+
oc apply -f target/kubernetes/kubernetes.yml
152+
----
153+
--
154+
====
127155

128156
[.console-output]
129157
[source,text]
@@ -133,52 +161,63 @@ service/tutorial-app created
133161
deployment.apps/tutorial-app created
134162
----
135163

136-
You might need to wait for some seconds until your application is up and running.
164+
[TIP]
165+
=====
166+
With the Quarkus CLI tool deploying is even easier. Instead of the above `kubectl apply` command, you can simply run `quarkus deploy` to deploy the application to your cluster:
167+
[.console-input]
168+
[source,bash,subs="+macros,+attributes"]
169+
----
170+
quarkus deploy
171+
----
172+
=====
173+
174+
You might need to wait a few seconds until your application is up and running. Once it is, let's get the url to test:
175+
137176

138177
[tabs]
139178
====
140-
Minikube::
179+
Openshift Sandbox / Kubernetes on AWS::
141180
+
142181
--
182+
If using a hosted Kubernetes cluster like OpenShift (Sandbox) on AWS then use curl and the EXTERNAL-IP address with port `8080` or get it using `kubectl`:
183+
143184
:tmp-service-exposed: tutorial-app
144185
145-
[#{section-k8s}-ip-port-minikube]
186+
[#{section-k8s}-ip-port-service]
146187
[.console-input]
147188
[source,bash,subs="+macros,+attributes"]
148189
----
149-
IP=$(minikube ip)
150-
PORT=$(kubectl get service/{tmp-service-exposed} -o jsonpath="{.spec.ports[*].nodePort}")
190+
IP=$(kubectl get service {tmp-service-exposed} -o jsonpath="{.status.loadBalancer.ingress[0].hostname}")
191+
PORT=$(kubectl get service {tmp-service-exposed} -o jsonpath="{.spec.ports[0].port}")
151192
echo $IP:$PORT
152193
----
153194
--
154-
Hosted::
195+
Minikube::
155196
+
156197
--
157-
If using a hosted Kubernetes cluster like OpenShift then use curl and the EXTERNAL-IP address with port `8080` or get it using `kubectl`:
158-
159198
:tmp-service-exposed: tutorial-app
160199
161-
[#{section-k8s}-ip-port-openshift]
200+
[#{section-k8s}-ip-port-minikube]
162201
[.console-input]
163202
[source,bash,subs="+macros,+attributes"]
164203
----
165-
IP=$(kubectl get service {tmp-service-exposed} -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
166-
PORT=$(kubectl get service {tmp-service-exposed} -o jsonpath="{.spec.ports[*].port}")
204+
IP=$(minikube ip)
205+
PORT=$(kubectl get service/{tmp-service-exposed} -o jsonpath="{.spec.ports[*].nodePort}")
167206
echo $IP:$PORT
168207
----
169208
--
170-
Hosted on AWS::
209+
Hosted::
171210
+
172211
--
173212
If using a hosted Kubernetes cluster like OpenShift then use curl and the EXTERNAL-IP address with port `8080` or get it using `kubectl`:
174213
175214
:tmp-service-exposed: tutorial-app
176215
177-
[#{section-k8s}-ip-port-service]
216+
[#{section-k8s}-ip-port-openshift]
178217
[.console-input]
179218
[source,bash,subs="+macros,+attributes"]
180219
----
181-
IP=$(kubectl get service {tmp-service-exposed} -o jsonpath="{.status.loadBalancer.ingress[0].hostname}")
220+
IP=$(kubectl get service {tmp-service-exposed} -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
182221
PORT=$(kubectl get service {tmp-service-exposed} -o jsonpath="{.spec.ports[*].port}")
183222
echo $IP:$PORT
184223
----
@@ -200,4 +239,19 @@ curl $IP:$PORT/hello
200239
Hello y'all!
201240
----
202241

203-
TIP: You can build, push and deploy the container image by running: `./mvnw clean package -Dquarkus.kubernetes.deploy=true`
242+
[sidebar]
243+
--
244+
TIP: If you're using Openshift (Sandbox) and would like to create a url you can share to the outside world, you can create it like so:
245+
[.console-input]
246+
[source,bash,subs="+macros,+attributes"]
247+
----
248+
oc create route edge --service=tutorial-app
249+
url=$(oc get route tutorial-app -o jsonpath='{.spec.host}')
250+
curl https://$url/hello
251+
----
252+
[.console-output]
253+
[source,text]
254+
----
255+
Hello y'all!
256+
----
257+
--

documentation/modules/ROOT/pages/rest-client.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Maven::
3737
[.console-input]
3838
[source,bash,subs="+macros,+attributes"]
3939
----
40-
mvn quarkus:add-extension -Dextensions=quarkus-rest-client
40+
mvn quarkus:add-extension -Dextensions=quarkus-rest-client-reactive,quarkus-rest-client-reactive-jsonb
4141
----
4242
4343
--
@@ -47,7 +47,7 @@ Quarkus CLI::
4747
[.console-input]
4848
[source,bash,subs="+macros,+attributes"]
4949
----
50-
quarkus extension add quarkus-rest-client
50+
quarkus extension add rest-client-reactive rest-client-reactive-jsonb
5151
----
5252
--
5353
====

0 commit comments

Comments
 (0)