= Deploy OpenEMS Backend on Debian Linux
:sectnums:
:sectnumlevels: 4
:toclevels: 4
:experimental:
:keywords: AsciiDoc
:source-highlighter: highlight.js
:icons: font
:imagesdir: ../../../assets/images

This chapter explains how OpenEMS Backend can be deployed on a Debian Linux server. Similar techniques will work for other operating systems as well.

== Prepare operating system environment

NOTE: It is recommended to run every service on a server with limited permissions. This example runs OpenEMS Backend with user "root" which is a bad idea for a production server!  

=== Check JAVA version

Ensure that a JRE version 21 or later is installed. We recommend using `temurin-21-jre`

For detailed installation instructions, visit https://adoptium.net/de/installation/linux/[Adoptium Installation Guide].

NOTE: If you are using an *ARM32* device, download https://openems.io/download/temurin-21-jre-armhf_21.0.6+2.deb[temurin-21-jre-armhf_21.0.6+2.deb] directly from OpenEMS.

=== Create an application directory

Create the directory */opt/openems-backend*. This is going to be the place, where we put the JAR file.

Execute `mkdir /opt/openems-backend`.

=== Create a config directory

Create the directory */opt/openems-backend/config.d*. This is going to be the place, where all the bundle configurations are held.

Execute `mkdir /opt/openems-backend/config.d`.

=== Create a systemd service definition

The systemd 'Service Manager' manages system processes in a Debian Linux. We will create a systemd service definition file, so that systemd takes care of managing (starting/restarting/...) the OpenEMS Backend service.

. Create and open the service definition file.
+
Execute `nano /etc/systemd/system/openems-backend.service`

. Paste the following content:
+
[source,ini]
----
[Unit]
Description=OpenEMS <1>
After=network.target <2>

[Service]
User=root <3>
Group=root
Type=simple <4>
WorkingDirectory=/opt/openems-backend
ExecStart=/usr/bin/java -XX:+ExitOnOutOfMemoryError -Dfelix.cm.dir=/opt/openems-backend/config.d -Djava.util.concurrent.ForkJoinPool.common.parallelism=100 -jar /opt/openems-backend/openems-backend.jar <5>
SuccessExitStatus=143 <6>
Restart=always <7>
RestartSec=10 <8>

[Install]
WantedBy=multi-user.target
----
<1> The name of the service.
<2> The service is allowed to start after network is available (e.g. to be able to access devices via ethernet connection)
<3> It is run as user 'root' to have access to all devices. It is recommended to change this for productive systems.
<4> OpenEMS Backend uses a "simple" process fork.
<5> The start command. It uses the Java JRE, sets the config directory to `/opt/openems-backend/config.d`, sets a parallelism value for ForkJoinPool - this depends on the number of OpenEMS Edge devices you expect to connect - and runs the jar file at `/opt/openems-backend/openems-backend.jar`
<6> In contrast to what systemd expects, Java exits with status 143 on success.
<7> Systemd _always_ tries to restart OpenEMS Backend once it was quit.
<8> Systemd waits _10_ seconds till the next restart.

. Press btn:[Ctrl] + btn:[x] to exit and btn:[y] to save the file.

. Activate the service definition:
+
Execute `systemctl daemon-reload`

== Start OpenEMS Backend

To update the OpenEMS JAR file at the target device, it is required to copy the JAR file from your build directory to `/opt/openems-backend/openems-backend.jar` on the server. Afterwards it is required to restart the systemd service

. (Re)start OpenEMS systemd service.
+
Execute `systemctl restart openems-backend --no-block; journalctl -lfu openems-backend`
+
The command restarts the service (_systemctl restart openems-backend_) while not waiting for the OpenEMS startup notification (_--no-block_). Then it directly prints the OpenEMS system log (_journalctl -lfu openems-backend_).
