# 🇬🇧 OpenFaas is also a PaaS - Part 2: Vert-x and GitLab
Yesterday, I explained how to use OpenFaaS as a PaaS to deploy an ExpressJS web application or micro-services, and it's here: OpenFaas is also a PaaS - Part 1.
Today, I want to do the same thing, but with a Kotlin Vert-x application, and I will manage the build and the deployment with GitLab. I use my own GitLab instance, my own runner and my own (unsecure) Docker registry, but it's easy to reproduce in your own environment (Last, year I wrot a blog post to explain the setup of OpenFaas and a Docker registry: First contact with OpenFaaS).
👋 Remarks:
- if you need help on the GitLab part, ping me
- your GitLab runner should embed Java JDK, OpenFaaS CLI and Docker client
- even if you don't use GitLab, you can use the first part of this blog post
# Create the Vert-x web application
- I will use Kotlin
# Generate the Vert-x project
Vert-x website provides nice starter kits, so somewhere on your laptop, type these commands
curl -G https://start.vertx.io/starter.zip \
-d "groupId=garden.bots" \
-d "artifactId=hey-people" \
-d "vertxVersion=4.0.0-milestone3" \
-d "vertxDependencies=vertx-web" \
-d "language=kotlin" \
-d "jdkVersion=1.8" \
-d "buildTool=maven" \
--output hey-people.zip
unzip hey-people.zip -d hey-people
# Add the OpenFaas part
I plan to use GitLab CI to build and deploy my web application. I will deploy it to OpenFaaS in a PaaS way, so I only need (in my case) the dockerfile template from the OpenFaaS templates store:
# Dockerfile template
this command will only download the dockerfile template of OpenFaas
cd hey-people
mkdir template
curl https://codeload.github.com/openfaas/templates/tar.gz/master \
| tar -C template -xz --strip=2 templates-master/template/dockerfile
# Dockerfile
Then, next we need a Dockerfile to dockerize our Vert-x application:
cat > Dockerfile <<EOF
FROM azul/zulu-openjdk-alpine:latest
ENV WEB_APP_JAR="hey-people-1.0.0-SNAPSHOT-fat.jar"
COPY target/\${WEB_APP_JAR} .
RUN touch /tmp/.lock
# --- run the application
CMD java -jar \$WEB_APP_JAR
EOF
Remark: as I use
cat
to generate my files, don't forget to escape$
like that\$
# Deployment file description
The OpenFaaS CLI need a description file with the needed information about how and where to deploy:
cat > config.deploy.yml <<EOF
version: 1.0
provider:
name: openfaas
gateway: ${OPENFAAS_URL}
functions:
\${PROJECT_NAME}:
lang: dockerfile
handler: ./
image: \${DOCKER_REGISTRY}/\${PROJECT_NAME}:latest
EOF
# Some changes in the source code
We are going to change the source code of the main verticle: src/main/kotlin/garden/bots/hey_people/MainVerticle.kt
(it's not mandatory, but I wanted to show how to use the Vert-x router)
cd hey-people # if you are not in the project directory
cat > src/main/kotlin/garden/bots/hey_people/MainVerticle.kt <<EOF
package garden.bots.hey_people
import io.vertx.core.AbstractVerticle
import io.vertx.core.Promise
import io.vertx.core.json.JsonObject
import io.vertx.ext.web.Router
import io.vertx.ext.web.handler.BodyHandler
class MainVerticle : AbstractVerticle() {
override fun start(startPromise: Promise<Void>) {
val router = Router.router(vertx)
router.route().handler(BodyHandler.create())
router.get("/hello").handler { context ->
context.response().putHeader("content-type", "application/json;charset=UTF-8")
.end(
JsonObject().put("message", "👋 Hello World 🌍").encodePrettily()
)
}
router.get("/").handler { context ->
context.response().putHeader("content-type", "text/html;charset=UTF-8")
.end("<h1>👋 Hello World 🌍</h1>")
}
// Don't forget: an OpenFaaS service is always listening on 8080
val httpPort = System.getenv("PORT")?.toInt() ?: 8080
vertx
.createHttpServer()
.requestHandler(router)
.listen(httpPort) { http ->
if (http.succeeded()) {
startPromise.complete()
println("HTTP server started on port 8080")
} else {
startPromise.fail(http.cause())
}
}
}
}
EOF
Now, we are ready to test a first deployment
# First deployment (without GitLab)
We are not going to use GitLab for the first deployment. We are just going to that "by hands":
# Build the jar file
cd hey-people # if you are not in the project directory
# build the jar file
chmod +x mvnw
./mvnw clean package
# Build the web application image, push it and deploy it
we export these variables to be used by the OpenFaaS CLI
export OPENFAAS_URL=http://openfaas.test:8080
export OPENFASS_TOKEN=e073022e120dd3c3f72baaa5a0728fcc27d392ff6b68d6099f6dc2ea05b0a0ba
export PROJECT_NAME="hey-people"
export DOCKER_REGISTRY="registry.test:5000"
echo -n ${OPENFASS_TOKEN} |faas-cli login --username=admin --password-stdin
faas-cli build -f config.deploy.yml
faas-cli push -f config.deploy.yml
faas-cli deploy -f config.deploy.yml
# you can check
faas-cli logs hey-people
Now, you can reach:
- the web app: http://openfaas.test:8080/function/hey-people (opens new window)
- the service: http://openfaas.test:8080/function/hey-people/hello (opens new window)
So, if you want to develop micro-services with Vert-x (and I think it's the best Java library to do that - but it's another topic), you can see that's easy, and OpenFaaS is the perfect PaaS to host them.
Now, it's time to put our project on GitLab and manage deploymenst with GitLab CI/CD.
# GitLab part
First we will update the config.deploy.yml
file like this:
cat > config.deploy.yml <<EOF
version: 1.0
provider:
name: openfaas
gateway: ${OPENFAAS_URL}
functions:
\${CI_PROJECT_NAME}-\${CI_COMMIT_REF_SLUG}:
lang: dockerfile
handler: ./
image: \${DOCKER_REGISTRY}/\${CI_PROJECT_NAME}-\${CI_COMMIT_REF_SLUG}:latest
EOF
Then, we need to add a .gitlab-ci.yml
file to our project to describe the deployment stages and jobs:
we just reproduce the command of the previous part. But with this
.gitlab-ci.yml
, you will be able to deploy even the review/preview version of your web application from a feature branch (https://docs.gitlab.com/ee/ci/review_apps/ (opens new window)).
stages:
- 📦build
- 🐳package
- 🚀deploy
- 🦄deploy
🌍service_build:
stage: 📦build
only:
- master
- merge_requests
script: |
chmod +x mvnw
./mvnw clean package
faas-cli build -f config.deploy.yml
🌏service_push:
stage: 🐳package
only:
- master
- merge_requests
script: |
faas-cli push -f config.deploy.yml
🌎service_deploy:
stage: 🚀deploy
environment:
name: production/${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
url: ${OPENFAAS_URL}/function/${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}/
only:
- master
script: |
export OPENFAAS_URL=${OPENFAAS_URL}
echo -n ${OPENFASS_TOKEN} | \
faas-cli login --username=admin --password-stdin
faas-cli deploy -f config.deploy.yml
🚧preview_service_deploy:
stage: 🦄deploy
environment:
name: preview/${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
url: ${OPENFAAS_URL}/function/${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}/
on_stop: 🗑stop_preview_service
only:
- merge_requests
script: |
export OPENFAAS_URL=${OPENFAAS_URL}
echo -n ${OPENFASS_TOKEN} | \
faas-cli login --username=admin --password-stdin
faas-cli deploy -f config.deploy.yml
🗑stop_preview_service:
stage: 🦄deploy
only:
- merge_requests
when: manual
environment:
name: preview/${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
action: stop
script: |
faas-cli remove -f config.deploy.yml
🗑stop_service:
stage: 🚀deploy
only:
- master
when: manual
environment:
name: production/${CI_PROJECT_NAME}-${CI_COMMIT_REF_SLUG}
action: stop
script: |
faas-cli remove -f config.deploy.yml
# Add your project to your GitLab instance
- You need to create an empty project named
hey-people
on your GitLab instance - Then add this environment variables in the CI/CD settings:
DOCKER_REGISTRY
with for example, this value (this is mine):registry.test:5000
OPENFAAS_URL
with for example, this value (this is mine):http://openfaas.test:8080
OPENFASS_TOKEN
with :your_openfaas_token
- add this line
build
to the.gitignore
file
cd hey-people
git init
git remote add origin git@gitlab.bots.garden:<YOUR_GITLAB_HANDLE>/hey-people.git
git add .
git commit -m "🎉 Initial commit"
git push -u origin master
Then a new pipeline should start:
And you should to be able to access to your webapp from here: http://openfaas.test:8080/function/hey-people-master/ (opens new window) and your service from http://openfaas.test:8080/function/hey-people-master/hello (opens new window)
That's all folks 😃
My next blog posts should be about:
- How to deploy Golo (opens new window) web application to OpenFaaS
- How to deploy Quarkus (opens new window) web application to OpenFaaS
- And, (but I need more time), something about K3S (opens new window)
Last Articles
- 🇫🇷 Type Result en Kotlin | 2020-10-31 | Kotlin
- 🇫🇷 Type Result en Kotlin | 2020-10-31 | Kotlin
- 🇬🇧 Every GitLab Page deserves a real CI/CD | 2020-07-23 | GitLab CI
- 🇫🇷 Lit-Element, commencer doucement | 2020-07-20 | WebComponent
- 🇬🇧 Build quickly and host easily your Docker images with GitLab and GitLab CI | 2020-06-02 | GitLab CI
- 🇬🇧 Deploy quickly on Clever Cloud with GitLab CI | 2020-05-31 | GitLab CI
- 🇫🇷 Borg Collective, mes jouets pour apprendre Knative | 2020-05-30 | Knative
- 🇬🇧 Borg Collective, Toys to learn Knative | 2020-05-30 | Knative
- 🇫🇷 M5Stack, une petit device IOT bien sympathique, programmable en Python | 2020-05-09 | IOT
- 🇫🇷 Knative, l'outil qui rend Kubernetes sympathique | 2020-05-02 | kubernetes