Package a Spring Boot App as RPM

Goals Package a Spring Boot Service as RPM Package Configure systemd integration Add install/uninstall hooks to create users, directories etc. Maven Setup <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.2</version> <relativePath/> </parent> <groupId>com.hascode</groupId> <artifactId>sample-app</artifactId> <version>1.0.0-SNAPSHOT</version> <name>sample-app</name> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> (1) <groupId>de.dentrassi.maven</groupId> <artifactId>rpm</artifactId> <version>1.5.0</version> <executions> <execution> <goals> <goal>rpm</goal> </goals> </execution> </executions> <configuration> <packageName>sample-app</packageName> <skipSigning>true</skipSigning> <group>Application/Misc</group> <requires> <require>java-11-openjdk-headless</require> (2) </requires> <entries> <entry> (3) <name>/opt/sample-app</name> <directory>true</directory> <user>root</user> <group>root</group> <mode>0755</mode> </entry> <entry> (4) <name>/opt/sample-app/log</name> <directory>true</directory> <user>sample-app</user> <group>sample-app</group> <mode>0750</mode> </entry> <entry> (5) <name>/opt/sample-app/sample-app.jar</name> <file>${project.build.directory}/${project.build.finalName}.jar</file> <user>root</user> <group>root</group> <mode>0644</mode> </entry> <entry> (6) <name>/usr/lib/systemd/system/sample-app.service</name> <file>${project.basedir}/src/main/dist/sample-app.service</file> <mode>0644</mode> </entry> </entries> <beforeInstallation> (7) <file>${project.basedir}/src/main/dist/preinstall.sh</file> </beforeInstallation> <afterInstallation> <file>${project.basedir}/src/main/dist/postinstall.sh</file> </afterInstallation> <beforeRemoval> <file>${project.basedir}/src/main/dist/preuninstall.sh</file> </beforeRemoval> <license>All rights reserved</license> </configuration> </plugin> </plugins> </build> </project> ...

May 14, 2021 · 3 min · 567 words · Micha Kops

Prettier Code Formatter Configuration

Goals Setup Prettier for different environments / IDEs Run Prettier via git hooks Install Prettier Install via npm npm install --save-dev --save-exact prettier Add empty configuration file echo {}> .prettierrc.json Create Prettier ignore file .prettierignore: # Ignore artifacts: build coverage Format all project files with Prettier: npx prettier --write . Git Hooks Adding the following lines to the project’s package-json makes ESLint and Prettier run before each commit: { "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "**/*": "prettier --write --ignore-unknown" } } ...

May 14, 2021 · 1 min · 90 words · Micha Kops

Setting up a Kubernetes Master Node

Goals Setup a kubernetes master node on a Linux machine Setup Initialize the cluster on the master node sudo kubeadm init --pod-network-cidr=10.244.0.0/16 This might take a few minutes …​ afterward we set up our local kubeconfig: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config Verify the Cluster Setup Shows that the cluster is responding and kubectl working: kubectl version

May 14, 2021 · 1 min · 65 words · Micha Kops

Synology NAS sync from Linux with rsync over SSH

Goals Configure the NAS to accept SSH and Rsync connections Enable SSH with pub-Key Deploy pub key Synchronize files with rsync Prerequisites We assume, that the Synology NAS basic configuration has been applied and that a shared directory is ready to be our sync target. We will be synchronizing the directory /tmp/samples to the NAS directory /volumes/samples. Synology NAS Setup First of all we need to enable some services on our NAS. ...

May 14, 2021 · 3 min · 436 words · Micha Kops

WordPress Docker Setup

Goals Run WordPress via Docker / Docker-Compose Increase the Upload Filesize Limit Create Docker Compose Configuration Create a docker-compose.yml: version: '3.1' services: wordpress: image: wordpress restart: always ports: - 8080:80 environment: WORDPRESS_DB_HOST: db WORDPRESS_DB_USER: exampleuser WORDPRESS_DB_PASSWORD: examplepass WORDPRESS_DB_NAME: exampledb volumes: - wordpress:/var/www/html db: image: mysql:5.7 restart: always environment: MYSQL_DATABASE: exampledb MYSQL_USER: exampleuser MYSQL_PASSWORD: examplepass MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - db:/var/lib/mysql volumes: wordpress: db: Run Docker Compose / Start Containers docker-compose up WARNING: Found orphan containers (wordpress-docker_phpmyadmin_1) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up. Starting wordpress-docker_db_1 ... done Starting wordpress-docker_wordpress_1 ... done Attaching to wordpress-docker_db_1, wordpress-docker_wordpress_1 [..] db_1 | 2021-04-03T18:58:17.247963Z 0 [Note] mysqld: ready for connections. db_1 | Version: '5.7.33' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) ...

May 14, 2021 · 1 min · 204 words · Micha Kops

Python Data Science Snippets

This article needs update! Jupyter Installation pip in venv mkdir newdir && cd newdir python -m venv .venv (1) source .venv/bin/activate (2) pip install jupyter numpy pandas sqlalchemy (3) pip freeze > requirements.txt (4) python -m jupyter lab (5) deactivate (6) 1 create a new virtual environment 2 activate the environment 3 install several libraries into the activated environment 4 create a list with all dependencies install for sharing or reinstallation later 5 start jupyter 6 having finished we might want to exit the virtual environment ...

July 8, 2020 · 2 min · 244 words · Micha Kops

Terminal Based Progress Bar for Java Applications

Recently I needed to add a progress bar to a Java based terminal/console application and I used a specific library that I’d like to demonstrate in the following snippet. Figure 1. Terminal based Progress Bar for Java Dependencies Using Maven, we just need to add the following dependency: pom.xml <dependency> <groupId>me.tongfei</groupId> <artifactId>progressbar</artifactId> <version>0.7.3</version> </dependency> Sample Application The application shows how to set up the progress bar and how to advance its status by-one, by a given amount or to a specific number. ...

March 31, 2019 · 2 min · 242 words · Micha Kops

Annotation based Kubernetes and Openshift Manifests for Java Applications with ap4k

Writing our manifest files for Kubernetes / Openshift often forces us to edit xml, json and yml files by hand. A new library, ap4k allows to specify metadata for these manifest files directly in our Java code using annotations. In the following short example I am going to demonstrate how to generate manifest files using Maven and ap4k. Figure 1. ap4k Tutorial Dependencies Using Maven we just need to add the following one dependency to our project’s pom.xml ...

February 28, 2019 · 5 min · 898 words · Micha Kops

Using Throwaway Containers for Integration Testing with Java, JUnit 5 and Testcontainers.

A lot of boilerplate code is written when developers need to test their applications with different connected systems like databases, stream platforms and other collaborators. Docker allows to handle those dependencies but there is still some glue code required to bind the container’s lifecycle and the configuration to the concrete integration test. Testcontainers is a testing library that offers lightweight throwaway instances of anything able to run in a Docker container, with bindings to configure the specific containers and also provides wrappers to manage our own custom containers. ...

January 30, 2019 · 6 min · 1110 words · Micha Kops

Next Steps to Pattern Matching in Java with Java 12 and Switch Expressions aka JEP 325

It is interesting to see how the Java language evolves over time. One thing that I have always missed is pattern matching in a way similar to languages like Scala. Now there are different JDK Enhancement Proposals (JEP) aiming at bringing us a little bit closer to pattern matching, especially JEP 325 aka Switch Expressions that are included in the current Java 12 preview or JEP 305 aka Pattern Matching for instanceof. ...

December 30, 2018 · 4 min · 715 words · Micha Kops