How to create a PWA with a local server that starts on demand using systemd
on
Linux.
The steps below are very rough and would need to be automated during app
installation. These notes are geared for Arch/Manjaro Linux. Your path to systemd-socket-proxyd
might be different.
(Something similar can be done with macOS' launchd
service. Windows has
nothing for this except for some really complicated .NET-centric services that
aren't enabled by default, called WPAS or Windows Process Activation Service.)
To run this experiment:
- Build a simple node http server that listens on port
48101
.- It should serve a basic HTML file from the root url on
localhost
. - It does not have to serve a full PWA manifest for any of this to work, but that's just what I'm working towards.
- It should serve a basic HTML file from the root url on
- Copy the
*.service
and.socket
files from this directory into your local~/.config/systemd/user/
directory (create that directory if necessary).- Edit them and fix any paths in them, such as the path to
node
and your node app. - What these files do is explained in the next section after the commands.
- Edit them and fix any paths in them, such as the path to
Now run the following commands. None of these should need sudo
:
systemctl --user daemon-reload
systemctl --user enable myapp-proxy.socket
systemctl --user start myapp-proxy.socket
The myapp-proxy.socket
unit is now listening on port 48100
or any port that
is different from what your node server listens on...
- First visit http://localhost:48101 to confirm no site is running.
- Now visit http://localhost:48100.
- This causes the
myapp-proxy.socket
unit to activate themyapp-proxy.service
unit (by virtue of the shared file name). - The
myapp-proxy.socket
unit accepts the request and passes the active socket file descriptor tomyapp-proxy.service
. - The
myapp-proxy.service
causes the configuredmyapp.service
dependency to be started first and then usessystemd-socket-proxyd
to proxy all packets from it's given socket over tomyapp.service
!
- This causes the
You can install the site at http://localhost:48100 as a PWA if you wish, from
Chrome More tools -> Create shortcut...
and check "Open as window".
Now when you start the PWA, the backend service is also started on the first request.
systemctl --user stop myapp.service
systemctl --user stop myapp-proxy.service
$ Warning: Stopping myapp-proxy.service, but it can still be activated by:
myapp-proxy.socket
systemctl --user stop myapp-proxy.socket
systemctl --user stop myapp-proxy.socket
systemctl --user disable myapp-proxy.socket
trash ~/.config/systemd/user/myapp*
systemctl --user daemon-reload
I don't think macOS
launchd
has a built-in proxy likesystemd-socket-proxyd
, so you'd have to bring your own. However, since there's nothing at all for Windows I would probably build something in Golang that would work in both places.Alternatively, on Windows at least, I might not need socket activation at all since I can probably capture the PWA shortcut to get it's CLI parameters after install, then replace that shortcut with my own utility that starts a hidden, shared node app server before launching the PWA frontend...