Make Jar Not War

31 views
Skip to first unread message

lon.va...@gmail.com

unread,
Jul 19, 2022, 5:03:03 PM7/19/22
to Bootique User Group
...is a saying that I swear I saw in Bootiques early website.  I adopt this philosophy and all of my apps are deployed as independent, runnable jars.  However, I'm not sure how every manages deployment, scaling in particular, without tools to do so.  

What do you guys use to deploy across servers/ports, add/delete instances, etc?

Thanks,

Lon

Andrus Adamchik

unread,
Jul 20, 2022, 5:41:23 AM7/20/22
to Bootique User Group
Hi Lon,

> On Jul 19, 2022, at 11:03 PM, lon.va...@gmail.com <lon.va...@gmail.com> wrote:
>
> ...is a saying that I swear I saw in Bootiques early website.

This was a SpringBoot slogan, but we do subscribe, and could've said that :)

> I adopt this philosophy and all of my apps are deployed as independent, runnable jars. However, I'm not sure how every manages deployment, scaling in particular, without tools to do so.
>
> What do you guys use to deploy across servers/ports, add/delete instances, etc?

There are tools available, just not "the tool". Jars give you the ability to run anywhere. But "anywhere" is a pretty broad spectrum these days, from Kubernetes, to various cloud providers (with or without containers), to on-prem or hosted virtualization solutions.

A general advice - use CI/CD for any deployment. The specifics will depend on the choices that you've made. Say, the apps are deployed in EC2 VMs on AWS and without containers. There may be two sets of CI/CD automation - (1) the infrastructure itself (setting up EC2 instances, load balancers, etc), (2) - apps deployment.

(1) Can be done by hand, but if you automate it with something like Terraform, you can easily do semi-automated scaling. And there are some AWS-specific fully-automated solutions that adapt to load like Elastic Beanstalk. In practice I never needed fully-automated scaling, so just adding (or removing) extra EC2s via Terraform would normally work.

(2) App deployment automation can be fairly trivial - just some bash scripts to scp the jar built by CI/CD to each server and start the app. We often use "one app / one VM approach", so the app would use the same port on multiple servers. This simplifies deployment configuration and auto-scaling. But collocating apps is also possible. Port is just another config parameter for the app.

Now, a few words specifically about Bootique apps. Configuration of an app can be quite complex. So what we often do is bundle environment-independent configuration YAML files with the app jars, and load them from classpath:

BQCoreModule.extend(b).addConfig("classpath:com/foo/my.yml");

But expose env-specific parts of the config to as env vars (sometimes service locations, almost always - credentials) [1]:

BQCoreModule.extend(b)
.declareVar("jdbc.mydb.jdbcUrl", "MY_DB_URL")
.declareVar("jdbc.mydb.username", "MY_DB_USERNAME")
.declareVar("jdbc.mydb.password", "MY_DB_PASSWORD");

The vars declared this way show up in the app self-help, so a devops engineer can easily see what each app needs:

java -jar my.jar -h
...
ENVIRONMENT
MY_DB_PASSWORD
MY_DB_URL
MY_DB_USERNAME

CI/CD engines usually provide a way to store named secrets, and expose them as vars in the pipeline. So your deployment script can "export" the vars above on each target server before starting the apps. If you want to be fully "cloud-native", you can configure your app to obtain the above configuration directly from the AWS Secrets Manager on startup [2].

So this is my best attempt at an overview of how BQ apps are deployed. Let me finish with a self-plug :) We provide paid devops services to help you navigate your choices and build all this automation. So feel free to contact me privately if you think you'll need external help.

Cheers,
Andrus

[1] https://bootique.io/docs/2.x/bootique-docs/#_configuration_via_environment_variables
[2] https://github.com/bootique/bootique-aws#aws-secret-manager-as-a-source-of-app-configuration





Reply all
Reply to author
Forward
0 new messages