Welcome to this new edition of One Framework a Day keeps the Boredom Away. In this series I will show you how to deploy a particular framework on Clever Cloud every day until I want to go back to boredom. Today it’s about Ratpack.
In each post of this series we’ll see how to deploy a particular framework on Clever Cloud. Today we are taking a look at Ratpack.
If you want to tag along, make sure you have git, a Clever Cloud account and that you have installed our CLI Clever-Tools.
What is Ratpack?
- Ratpack is a set of Java libraries for building modern HTTP applications.
- It provides just enough for writing practical, high performance, apps.
- It is built on Java 8, Netty and reactive principles.
I am personally a big Ratpack fan for its simplicity. If you want to try it there are many projects already on Github. I have chosen to test one from Dan Woods. He wrote the book Learning Ratpack. I encourage you to read it if you like what you see here.
He started a performance test project: s1p-high-perf-microservices. It’s a microservice that includes a connection to Postgres. So let’s look at how to deploy it.
Setup
Fist step is to clone the project:git clone https://github.com/danveloper/s1p-high-perf-microservices/
Open it with your favorite editor. You will see it’s a gradle based project, which is one of the build tool supported by Clever Cloud. Open the DBConfig class. You will see it declares the configuraiton prefix ‘db’. Let’s assume it’s to configure PostgreSQL. Now open application.yml
. This is where the configuration is stored in this project. So this is where we configure the DB connection. Let’s create our database. You can either log to the console, use the API or use the CLI like this: clever addon create postgresql-addon --plan dev --region eu ratpackPG
Here I have created a Postgre instance with the dev plan in the eu region called ratpackPG. If you run clever addon
you will see it on the list. You can also see it in the console. A database is an add-on and as such can be linked to an application. Here linking ratpackPG
means that the configuration environment variables provided by the add-on will be injected in the linked application. We have two things left to do.
- Create the application:
clever create --type gradle ratpackTest --region par
- Link the add-on:
clever service link-addon ratpackPG
If you are following closely you’ll notice that region names are different for add-ons and applications. This has to do with our will to keep our Add-ons API compatible with Heroku.
Anyway now you have an application. And if you take a look at its environment variable with clever env
, you should see relevant variables like POSTGRESQL_ADDON_DB
, POSTGRESQL_ADDON_HOST
, etc… There are different ways to use them in our project.
We can edit application.yml
so it looks like this:
db:
username: ${POSTGRESQL_ADDON_USER}
password: ${POSTGRESQL_ADDON_PASSWORD}
database: ${POSTGRESQL_ADDON_DB}
poolSize: 4
hostname: ${POSTGRESQL_ADDON_HOST}
port: ${POSTGRESQL_ADDON_PORT}
Using the ${}
allows us to use existing environment variables and assigned them directly to our properties. That’s because this Ratpack project includes Spring and uses it to manage part of its configuration. If you do this you can easily reuse that same code base for different applications for staging, preprod, etc…
We can also directly setup new environment variables that will be picked up by Ratpack. Take a look at their documentation on the matter. To setup variables with the CLI it works like this:
clever env set RATPACK_PORT 8080
clever env set db_database ${POSTGRESQL_ADDON_DB}
clever env set db_hostname ${POSTGRESQL_ADDON_HOST}
clever env set db_password ${POSTGRESQL_ADDON_PASSWORD}
clever env set db_port ${POSTGRESQL_ADDON_PORT}
clever env set db_username ${POSTGRESQL_ADDON_USER}
clever env set db_poolSize 4
Since the application is doing the following SQL query:
public Observable<Product> getProducts() {
return pool.queryRows("select * from product").map(row -> {
Long id = row.getLong("product_id");
String name = row.getString("name");
String description = row.getString("description");
Boolean available = row.getBoolean("is_available");
BigDecimal price = row.getBigDecimal("price");
return new Product(id, name, description, available, price);
}).doOnError(Throwable::printStackTrace);
}
We need to load data in there. Let’s create a data.sql
file with this content:
CREATE TABLE public.product (
product_id bigint,
name text,
description text,
is_available boolean,
price double precision
);
INSERT INTO product(product_id, name, description, is_available, price)
VALUES (1, 'product name','product description', true, 20.00);
Or run:
touch data.sql
echo "CREATE TABLE public.product (product_id bigint, name text, description text, is_available boolean, price double precision); INSERT INTO product(product_id, name, description, is_available, price) VALUES (1, 'product name','product description', true, 20.00);" > data.sql
To insert it in the DB, you can do something like psql -h baug3gcfk7kx1ui-postgresql.services.clever-cloud.com -p 5432 -U ukh3kcp2me9oc1rqtw7i -d baug3gcfk7kx1ui < data.sql
. You will be prompted for the password. This command is available in the ‘add-on information’ page of your Postgres instance in the console.
You can also retrieve all the variables from the CLI by typing clever env
. If you are an awk fan here’s a one liner: psql `clever env | awk -F = '/POSTGRESQL_ADDON_URI/ { print $2}'` < data.sql
Deploy
You have a configured application and add-on. Time to figure out how to run it. If you run gradle tasks
you will get the list of gradle goals you can run. One of them is run
, which is exactly what we want to do. To configure this, you need to create a clevercloud
folder at the root of your project and inside it create a gradle.json
file with the following content:
{
"deploy": {
"goal": "run"
}
}
What is left to do is to commit your pending change:
git add clevercloud/gradle.json src/main/resources/application.yml
git commit -m"add clever cloud specifics"
And then deploy your project: clever deploy
Once the deployment is done type clever open
to open the application in your default browser.
If you are satisfied there’s a couple of other things you can do like adding a custom domain name with clever domain yourcustomdomain.com
. scale up clever scale --flavor <flavor>
or out clever scale --min-instances <min-instances> --max-instances <max-instances>
, even setup automatic scale out clever scale --min-instances <min-instances> --max-instances <max-instances>
. How cool is that?