Why is the time in the NR log not local time?

I don't think multi-user.target guarantees a connection. Actually I am not convinced about the method used in the new service script either. I need to carry out some tests.

Feel free to improve it . Thanks !

I am hoping to, but it is tricky when multiple distributions (some old) have to be supported. time-sync.target looks interesting, but more research is required.

i think I did look at some of those but they all ended up needing users to set up various files and other complications - whereas just checking the log to see if it had been synchronised and then looping if not seemed easier to me :slight_smile:

Yes. I see what you mean.

It doesn't but other commentary indicates that if the time could be updated, it will have been by this stage. That means that time will be correct if the network was available but Node-RED startup won't hang if the Internet isn't available.

I think if you are relying on the time sync happening before node-red starts then that is exactly what has to be done, wait for the time sync before node-red starts.

1 Like

Not really, I was offering a possible alternative to Dave's wait for timesync which, as he points out, would completely prevent Node-RED from starting if the Internet wasn't available. By waiting for multi-user, you get a 1/2-way house, you will get timesync if available but won't have to wait too long if it isn't.

Least that was my understanding from other threads. Not tested it myself.

This is another option, not a complete answer. Whether it is any good depends on your circumstances and what is most important for you.

Hi all, quick update on this. I've discovered the following very useful command:

systemd-analyze plot > something.svg

Outputs an SVG image of the entire startup chain which lets you fine-tune your service files.

So if you really need to wait for the time-sync to have updated, you will want this in your service file in the [Unit] section:

After=time-sync.target

multi-user.target is the last but one step and the current default service file makes Node-RED happen BEFORE that step which is sensible.

In my own service files, I make node-red wait for the network.target but I also add the following:

Wants=mosquitto.service influxdb.service

Just to be sure that they are running before Node-RED starts.

All of this means that even on my home server (not a Pi), it will be nearly 30s before Node-RED starts after a reboot. Total startup time is around 68s.

@dceejay, I think that means that you can simplify your service file. Indeed, making Node-RED startup dependent on network.target is sufficient (timesync happens before then) which is, I guess, why I've never had a problem. Though if the network doesn't start, neither will Node-RED - that's fine for me since it wouldn't be much use to me without the network.

1 Like

PR always welcome.

If time permits. I don't use your script I'm afraid so testing would be minimal at best. I am updating the alternate-node-red-installer repo though. It needed a couple of updates anyway.

Ok. Well maybe explicit change this to that in here would do as a start.

I'll post something in a bit. Just reviewing some other settings.

Is there a specific reason the service is set to Nice=5?

I don't think that does quite what you think. I have just tried adding
After=time-sync.target
to the nodered script and on boot I see, in syslog,

Dec 29 16:41:20 pi004 Node-RED[271]: 29 Dec 16:41:20 - [info]
Dec 29 16:41:20 pi004 Node-RED[271]: Welcome to Node-RED
Dec 29 16:41:20 pi004 Node-RED[271]: ===================
Dec 29 16:41:20 pi004 Node-RED[271]: 29 Dec 16:41:20 - [info] Node-RED version: v1.2.3
Dec 29 16:41:20 pi004 Node-RED[271]: 29 Dec 16:41:20 - [info] Node.js  version: v10.16.0
Dec 29 16:41:20 pi004 Node-RED[271]: 29 Dec 16:41:20 - [info] Linux 4.19.42+ arm LE
Dec 29 16:41:25 pi004 Node-RED[271]: 29 Dec 16:41:25 - [info] Loading palette nodes
Dec 29 16:41:39 pi004 systemd-timesyncd[195]: Synchronized to time server 185.57.191.229:123 (2.debian.pool.ntp.org).
Dec 29 16:41:39 pi004 systemd[1]: Time has been changed
Dec 29 16:41:39 pi004 systemd[1]: apt-daily.timer: Adding 2h 13min 43.815605s random time.
Dec 29 16:41:39 pi004 systemd[1]: apt-daily-upgrade.timer: Adding 50min 16.306837s random time.
Dec 29 16:41:55 pi004 Node-RED[271]: 29 Dec 16:41:55 - [info] Settings file  : /home/me/.node-red/settings.js

Note that the time is synced after node-red is started. If I get the status of time-sync.target I see

$ sudo systemctl status time-sync.target
ā— time-sync.target - System Time Synchronized
   Loaded: loaded (/lib/systemd/system/time-sync.target; static; vendor preset: enabled)
   Active: active since Tue 2020-12-29 16:40:58 GMT; 5min ago
     Docs: man:systemd.special(7)

Dec 29 16:40:58 pi004 systemd[1]: Reached target System Time Synchronized.

Which says it synced at 16:40:58, and when I look at the time, which is right at the start of boot, I see

Dec 29 16:40:59 pi004 kernel: [    0.000000] Booting Linux on physical CPU 0x0
Dec 29 16:40:58 pi004 fake-hwclock[69]: Tue 29 Dec 16:40:49 UTC 2020
Dec 29 16:40:59 pi004 systemd-fsck[97]: e2fsck 1.43.4 (31-Jan-2017)

So I think the target is getting completed by the sync to the fake hardware clock, rather than the network time sync, which isn't very helpful.

1 Like

OK, so looking at man systemd-timesyncd.service I can see that the initial sync does indeed resync the last synchronised time with the internal Linux clock if no realtime clock module is present.

What I see from:

home@home:~/$ timedatectl show-timesync
FallbackNTPServers=0.debian.pool.ntp.org 1.debian.pool.ntp.org 2.debian.pool.ntp.org 3.debian.pool.ntp.org
ServerName=2.debian.pool.ntp.org
ServerAddress=185.57.191.229
RootDistanceMaxUSec=5s
PollIntervalMinUSec=32s
PollIntervalMaxUSec=34min 8s
PollIntervalUSec=34min 8s
NTPMessage={ Leap=0, Version=4, Mode=4, Stratum=1, Precision=-25, RootDelay=0, RootDispersion=0, Reference=GPS, OriginateTimestamp=Tue 2020-12-29 16:44:02 GMT, ReceiveTimestamp=Tue 2020-12-29 16:44:02 GMT, TransmitTimestamp=Tue 2020-12-29 16:44:02 GMT, DestinationTimestamp=Tue 2020-12-29 16:44:02 GMT, Ignored=no PacketCount=93, Jitter=4.361ms }
Frequency=-214461

Is that the minimum update frequency of the SNTP service is 32s. Indeed, my journal confirms this:

home@home:~/$ sudo /bin/journalctl -b -u systemd-timesyncd
-- Logs begin at Sun 2020-12-27 15:14:03 GMT, end at Tue 2020-12-29 17:16:48 GMT. --
Dec 27 15:14:04 home systemd[1]: Starting Network Time Synchronization...
Dec 27 15:14:04 home systemd[1]: Started Network Time Synchronization.
Dec 27 15:14:35 home systemd-timesyncd[307]: Synchronized to time server for the first time 185.57.191.229:123 (2.debian.pool.ntp.org).

Which means that the first actual query of the NTP remote is 32(ish) seconds after the initial sync. On my system that is around 42 seconds after boot start.

So it seems (as I should have assumed in the first place! :blush:) that our own dear @dceejay is, as usual, correct and, equally as usual, I am wrong. Sorry Dave.

I will leave the dependency on the network.target in my own service file though really only the Wants=mosquitto.service influxdb.service line is really needed for me.

In case anyone else if wanting an annotated service template, here is the latest that will be updated in the alternate installer shortly:

# A TEMPLATE systemd service file for running Node-RED
# CHANGE the settings before use.
#
# See https://github.com/TotallyInformation/alternate-node-red-installer
#     https://gist.github.com/Belphemur/3f6d3bf211b0e8a18d93
#     http://www.freedesktop.org/wiki/Software/systemd/
#
# This file must be linked into the /etc/systemd/system/multi-user.target.wants/ folder:
#    1) Rename this file to have a unique name (in case you want other instances running)
#    2) sudo /bin/systemctl enable /home/<user>/<folder>/system/<filename>.service
#    3) sudo systemctl daemon-reload
#
# After installing or changing this file:
#    1) sudo systemctl daemon-reload
#
# Start manually with `sudo /bin/systemctl start <filename>`
# View logs with `sudo journalctl -u <filename>` (e.g. `sudo journalctl -u node-red`)
# View service status with `sudo systemctl status <filename>`
#
# VERSION: 3

#----------------------------------------------------------------------------#
# SECURITY NOTE:                                                             #
# There are MANY additional settings that should be considered for this file #
# if running in a production environment and ESPECIALLY if it is possible to #
# access Node-RED over the INTERNET.                                         #
# SELinux, Sandboxing and other limiting flags should be considered. See     # 
# https://www.freedesktop.org/software/systemd/man/systemd.exec.html         #
# for more details.                                                          #
#----------------------------------------------------------------------------#

[Unit]
Description=Node-Red Home Automation service
Documentation=https://github.com/TotallyInformation/alternate-node-red-installer http://nodered.org/docs

# Use the `systemd-analyze plot > something.svg` (or similar) command to produce a full dependency
# visual that will let you sensibly adjust these settings for your system.
# @see https://serverfault.com/a/617864/119582

# NB: Use the `systemd-analyze` command to understand the order of 
# Syslog, and Networking must be active before starting - adjust to requirements
After=network.target
# Mosquitto (MQTT) & InfluxDB may be wanted - ADJUST to need
#Wants=mosquitto.service influxdb.service

[Service]
Type=simple

# User/Group that launches node-RED (it's advised to create a new user for Node-RED)
# You can do : sudo useradd node-red then change the User=pi to User=node-red
# If changing the user/group, make sure that ALL FILES and FOLDERS have the correct
# ownership before continuing.
User=pi
Group=pi

# -- Set any required environment variables - ADJUST these according to your installation --
#    Do not forget to change settings in ./data/envfile.ini as well
#    NOTE: No variable expansion is done.
#          Do not put credentials into environment variables - use LoadCredential or SetCredential

Environment="NODE_RED_EXE=/home/<user>/<root-folder-name>/node_modules/node-red/red.js"
Environment="NODE_RED_OPTIONS=--userDir /home/<user>/<root-folder-name>/data -v"

# Only when running on systems (like most Pi's) with 1GiB or less of RAM
# Comment out if you have plenty of RAM so that Node.js decides.
#Environment="NODE_OPTIONS=--max-old-space-size=128"
Environment="NODE_OPTIONS=--max-old-space-size=512"

# Un-comment if needing proxy to get external network
#Environment="HTTP_PROXY=http://myproxy.com:8080"
#Environment="NO_PROXY=.acme.co,.acme.co.uk"

# Or use an environment variables file, overrides the Environment settings
# makes it nice and easy to change without having to edit this file.
# Ignored if file does not exist. Entries in file overwrite those above.
# @See https://www.freedesktop.org/software/systemd/man/systemd.exec.html#EnvironmentFile=
EnvironmentFile=-/home/<user>/<root-folder-name>/data/envfile.ini

WorkingDirectory=/home/<user>/<root-folder-name>

# PID file
PIDFile=/home/<user>/<root-folder-name>/nrmain.pid

# Command that is started - for the alternate installer or other manually installed `npm install node-red`
# @see https://man7.org/linux/man-pages/man5/systemd.service.5.html#COMMAND_LINES for details
ExecStart=/usr/bin/node $NODE_OPTIONS $NODE_RED_EXE $NODE_RED_OPTIONS
# Command to start when using Dave's install script on a Pi
#ExecStart=/usr/bin/env node-red-pi $NODE_OPTIONS $NODE_RED_OPTIONS

# uncomment next line if you need to wait for time sync before starting
#ExecStartPre=/bin/bash -c '/bin/journalctl -b -u systemd-timesyncd | /bin/grep -q "systemd-timesyncd.* Synchronized to time server"'

# Guide the priority of the service - how "nice" it plays with other running tasks
# @see https://www.freedesktop.org/software/systemd/man/systemd.resource-control.html for additional settings
# including the ability to control swap use.
# Lower value is higher priority (-20 to 19, default=0)
#Nice=5

# Tag things in the log (goes to journal by default, access using the `journalctl` command)
SyslogIdentifier=Node-RED

# Make Node-RED restart if it fails
Restart=on-failure
RestartSec=20s  # Defaults to 100ms

# Node-RED needs a SIGINT to be notified to stop
KillSignal=SIGINT

# Prevent this service changing the OS or /etc
# @See https://www.freedesktop.org/software/systemd/man/systemd.exec.html#ProtectSystem=
ProtectSystem=full

[Install]
# Node-RED must be started before the following is triggered
WantedBy=multi-user.target

#EOF

<user> and <root-folder-name> will be replaced by the alternate installer if you run it.

And here is an example template for the env file which is optional:

# Systemd Environment variables file, overrides the Environment settings
# makes it nice and easy to change without having to edit this file.
# @See https://www.freedesktop.org/software/systemd/man/systemd.exec.html#EnvironmentFile=

# ** RESTART NODE-RED AFTER CHANGING THIS FILE **

# CHANGE ACCORDING TO THE SETTINGS IN ../system/node-red.service
NODE_RED_SERVICE=node-red

# WARNING: Use absolute file names here
#          Variable expansion is not permitted
#          Do not put credentials into environment variables - use LoadCredential or SetCredential

# SET IN ../system/node-red.service - you can override them here
#NODE_RED_OPTIONS=--userDir /home/<user>/<root-folder-name> -v
#NODE_OPTIONS=--max-old-space-size=128

# You can also change the rest of Node-RED's environment variables by setting them using node.js at the top
# of the settings.js file. Including the following:

# -- Overrides for settings.js -- #
#PORT=1880
httpAdminRoot=/red
httpStatic=/home/<user>/<root-folder-name>/public
httpNodeRoot=/

# What env type are we running?
NODE_ENV=Development
#NODE_ENV=Production

# Un-comment if needing proxy to get external network
#HTTP_PROXY=http://myproxy.com:8080
#NO_PROXY=.acme.co,.acme.co.uk

#EOF

Only rarely - but I'll take it on the few occasions it does occur ! :smug: :rocket:

1 Like