0

I have a node.js app that I want to set up as a service that gets started on bootup.

I can do that using systemctl by creating a script in /etc/systemd/system/TestApp.service .

The problem is that I want this app to be run inside a screen, so I can attach to it by logging into the system and issue command like screen -r -D TestApp

But doing so causes sysmtemctl to fail and the app does not start.

Here is the script that I have created:

[Unit]
Description=Script to start TestApp website on bootup

[Service]
ExecStart=/usr/bin/screen -S TestApp "/usr/bin/node  /opt/NodeApps/TestApp/mainApp.js"

[Install]
WantedBy=multi-user.target

and here is the status of systemctl along with the error it throws:

sudo systemctl status TestApp.service 
TestApp.service - Script to start TestApp website on bootup
   Loaded: loaded (/etc/systemd/system/TestApp.service; disabled; vendor preset: enabled)
   Active: failed (Result: exit-code) since Sun 2020-09-13 09:35:21 UTC; 30s ago
 Main PID: 13012 (code=exited, status=1/FAILURE)

Sep 13 09:35:21 sp-webserver systemd[1]: Started Script to start TestApp website on bootup.
Sep 13 09:35:21 sp-webserver screen[13012]: Must be connected to a terminal.
Sep 13 09:35:21 sp-webserver systemd[1]: TestApp.service: Main process exited, code=exited, status=1/FAILURE
Sep 13 09:35:21 sp-webserver systemd[1]: TestApp.service: Failed with result 'exit-code'.

Please advice on how best to set this up so it runs inside a screen upon boot up.

4
  • Why do you need screen? If you need interactivity with the service, consider making the node service expose a socket, and provide a cli tool to communicate through it. Sep 14 '20 at 22:11
  • For now I have a few reasons for using screen: - I log important events to console which get lost in the sea of logs I have accessible via logs available on webserver. Ability to stop and start the app via ctrl + C . Eventually, I'll enhance functionality of my apps to allow filtering logs, allow restarts at will and then I can get used to the idea of no screens.
    – Curious101
    Sep 14 '20 at 23:32
  • You can already start and stop it using systemctl and you can lookup your logs in journalctl Sep 14 '20 at 23:58
  • Those are fair points. I guess my development cycle has been quite long for these apps, and I've been using screen to run the apps and come back to them during development to test them repeatedly. I wanted to keep this option open in my prod environment. I need to let go of that habit.
    – Curious101
    Sep 15 '20 at 0:20
0

I ended up troubleshooting and fixing the issue myself. Here is the solution :

create file /etc/systemd/system/TestApp.service

[Unit]
Description=Script to start TestApp website on bootup

# Listed below are three [Service] sections, we need only one of them. These three list our three different ways we can do this.
All three sections will start the processes as non root user 'testuser'. If we want them to start the processes as root, then we'd say User=root OR User="root" (not sure which one)

# The service section without the use of screen.
[Service]
WorkingDirectory=/opt/NodeApps/TestApp
ExecStart=/usr/bin/node /opt/NodeApps/TestApp/mainApp.js
Restart=always
RestartSec=3
User=testuser

# The service section with the use of screen as separate process, i.e. node will start inside screen, but  top will show screen and node as separate processes
[Service]
Type=forking
WorkingDirectory=/opt/NodeApps/TestApp
ExecStartPre=/usr/bin/screen -dmS TestApp
ExecStart=/usr/bin/node /opt/NodeApps/TestApp/mainApp.js
Restart=always
RestartSec=3
User=testuser

# The service section with the use of screen i.e. node will start inside screen, and top will show screen  as a process (node does not get a separate pid) 
[Service]
Type=forking
WorkingDirectory=/opt/NodeApps/TestApp
ExecStart=/usr/bin/screen -dmS TestApp /usr/bin/node /opt/NodeApps/TestApp/mainApp.js
Restart=always
RestartSec=3
User=testuser

[Install]
WantedBy=multi-user.target 

Once this file is saved, do the following:

  1. take ownership of this file. ( sudo chown )
  2. set permissions to be 644 so it is not executable ( chmod 644 )

Test it with commands like:

sudo systemctl start TestApp.service
sudo systemctl stop TestApp.service
sudo systemctl status TestApp.service

Once satisfied, enable it like this, so it gets executed at boot up:

sudo systemctl enable TestApp.service

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.