Using DynamoDB Container Image for local environment testing.
As you notice in my previous tutorials using the Timer Service application, I used to connect directly to DynamoDB on AWS for the local testing environment. This article will use a DynamoDB container image for local environment testing. Also, we need to modify our Timer Service Quarkus configuration file to use this container image instead of going directly to AWS.
So far, we have 2 projects using the Timer Service application explained in the following articles:
- Reactive Timer Microservice with Java Quartz, DynamoDB, and Quarkus.
- Building a Cloud-Native App using Angular/Ionic with Amplify and Java/Quarkus with Copilot ECS.
The first one is about the initial version of our Timer Service using Quarkus and Quartz. It doesn't have a frontend app as the second article has. The other changes I was doing are more about deployment procedures to AWS, but the code base of the Timer Service itself is the same. However, in my future articles, when we talk about the Timer Service, I will be referencing the MicroApp version because we must use the entire application based on the front and backend.
Maybe you want to use other frontend frameworks or libraries such as React for your apps, so I will provide you a public Timer Service Docker Image of the microservice that you can pull from my Docker Hub account. So, you can always use the Timer Service's latest version of the backend microservice for your initiatives. The MicroApp project also builds and runs the Timer Service container as a backend service, so if you want to use the fullstack app, consider using this project instead.
To complete this guide, you'll need:
- Git.
- An AWS account.
- Amplify CLI.
- Docker and Docker Compose.
- IntelliJ or Eclipse IDE.
IMPORTANT: I'm using the mac M1 chip, and I've experienced some issues building and running the Docker images, so I created an additional Dockerfile for the ARM64 microprocessor architecture. I will use this new file for this tutorial, but you can use the old Docketfile if your microprocessor architecture is the traditional one.
Timer Service — The Backend MicroService
I've created a new docker file called "Dockerfile.arm64" for the ARM64 architecture. This Dockerfile uses the "java17-arm64" version for the builder stage layer:
For the runner Dockerfile, we have a problem because the original "quarkus-micro-image" doesn't have an ARM64 version. But, the RedHat "ubi-minimal" docker image has one. If we run the following command, we can see a version for the ARM64 platform:
# docker manifest inspect registry.access.redhat.com/ubi8/ubi-minimal
So, we need to use the SHA identifier of the ARM version in our new Dockerfile:
Now, we need to add the DynamoDB container image to our "docker-compose.yml" file:
Then, it's time to modify our "application.properties" file to use our local DynamoDB container image:
As you can see, I used the "%dev" parameter to indicate that this property must be enabled when we use the "dev" Quarkus profile, that in our case is our local development environment.
We can activate the "dev" profile using the "QUARKUS_PROFILE" environment variable, but this time we can use the "docker-compose.yml" file to start our Timer Service container in our local environment:
Now, we can build the Timer Service image, but this time, we can use the "docker-compose" command:
# docker-compose build
It's time to run the entire local environment with the "docker-compose" command:
# docker-compose up
We should see something like this:
Finally, we can use the Postman to access our Timer Service through our Nginx proxy server:
As you can see, there are no tasks created at the moment. So let's create one:
When the task's time comes, you will see something like this in your terminal window:
NOTE: As usual, you can clone the source code of the Timer Service located in my GitHub account repository.
Timer Service — The FullStack MicroApp
The changes in the backend for the Timer Service are the same as the ones mentioned in the previous section. So please take in mind that in this section, we're talking about the frontend, but don't forget that the backend is the same as the one deployed before.
Firstly, there is no reason to build a container for the frontend app. Ionic and Amplify can build and deploy the needed components locally and on the cloud. So, adding a container for the frontend app adds an overhead that isn't necessary because the CLI tools make our frontend development easier. We only need the backend stuff deployed locally, and that's why Docker Compose is helpful. The other important reason is that we don't need to pay for the used resources on the ECS and DynamoDB services while developing locally.
Let's initialize the Amplify project as usual and deploy the Cognito Auth module to your AWS account. This is the only resource that we must need on the cloud because at the time that I'm writing these lines; there's not an official docker image that deploys the AWS Cognito service.
# cd frontend/angular-timer-service-ionic
# npm i
# amplify init
Then, configure and deploy the auth module:
# amplify add auth
Push the changes to AWS using Amplify:
# amplify push
Navigate to the project's root directory and deploy the backend services using Docker Compose as we did before:
NOTE: If you have already deployed the containers of the previous section, you must delete de containers before running the compose command. You can accomplish this using the "docker container prune" command.
# docker-compose up
Use the Postman tool to verify that you can access the Timer Service backend. Also, verify the logs printed in the terminal console:
Modify the "environment.ts" file to use our local API endpoint, which is our Nginx proxy web server deployed with the docker-compose file:
Also, modify the "timerZone" property value with yours.
Now, it's time to build and deploy the Ionic project locally to validate that all our configuration is working as expected. So open a new terminal tab, navigate to the Ionic/Angular project and execute:
# ionic build
# ionic serve
It opens a new browser tab with the Timer Service app as usual:
So create your user and then log in to the app to access the home page:
As you can see, there are no tasks created yet, so let's try and create one:
This task will be executed at 1:30 pm. So when the times come, you must see new logs in the terminal console as usual:
And that's it!!! Now you can deploy your projects locally with tools that help you save money by not using AWS resources every time for your development.
NOTE: As usual, you can clone the source code of the Timer Service MicroApp located in my GitHub account repository.
I hope this tutorial will be helpful to you, and I will see you in my next post.