Managing Emacs Server as Systemd Service
18 Jun 2021Table of Contents
Using Emacs Server Without Systemd
I live in Emacs entirely apart from using browser for googling. Having an Emacs server running on the background makes Emacs available all the time. So I won't worry about closing it accidental.
It is not hard to do that, just run
in command line to start the Emacs server. It will load user configuration file as usual. Then run
to open an Emacs GUI instance that uses the Emacs server. That's how I have been doing for a while.
An better approach is using systemd. It is the services manager of Linux. Whenever my Debian 11 laptop boot up, systemd would start a bunch of services in parallel, for example, Networking manager connects WIFI, Bluetooth connects wireless keyboard so everything would be ready after I login. And I want Emacs to be ready as well.
I can achieve that by simply having an shell script automatically running after login. But there are benefits of using systemd. It has bunch of sub-commands for managing services, for example, checking logs, status etc.
It's a nice tool to have, I can use it for example Jupyter Notebook server.
That's why I pulled the trigger and spent 2 hours in implementing and testing it. Here's the technical bit.
How to Implement As Systemd Service
In order to use systemd to manage Emacs server, I firstly need a configuration file (which is called unit file). Debian Wiki provides a short description of the syntax and parameter of unit file.
I found an simple one in Emacs Wiki. It looks like this
[Unit] Description=Emacs text editor Documentation=info:emacs man:emacs(1) https://gnu.org/software/emacs/ [Service] Type=forking ExecStart=/usr/bin/emacs --daemon ExecStop=/usr/bin/emacsclient --eval "(kill-emacs)" Environment=SSH_AUTH_SOCK=%t/keyring/ssh Restart=on-failure [Install] WantedBy=default.target
The important parameters are
- ExecStart
- It tells systemd what to do when starting Emacs
service, in this case it runs /usr/bin/emacs --daemon
command.
- ExecStop
- it tells systemd what to do when shutting down Emacs
service, in this case it runs /usr/bin/emacsclient --eval
"(kill-emacs)"
command.
If you are using an Emacs built in a difference directory, you have to change /usr/bin/emacs to wherever your Emacs is located.
Then save the configuration file as ~.config/systemd/user/emacs.service/.
After that run
so systemd would copy the configuration file into central places and it would start Emacs service at boot time.
To run Emacs service right now, use
This is what I see in my console
emacs.service - Emacs text editor Loaded: loaded (/home/yitang/.config/systemd/user/emacs.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2021-06-14 09:12:26 BST; 24h ago Docs: info:emacs man:emacs(1) https://gnu.org/software/emacs/ Main PID: 5222 (emacs) Tasks: 5 (limit: 19027) Memory: 154.7M CPU: 3min 25.049s CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/emacs.service ├─ 5222 /usr/bin/emacs --daemon └─16086 /usr/bin/aspell -a -m -d en_GB -p /home/yitang/git/.emacs.d/local/ispell-dict --encoding=utf-8 Jun 14 09:11:57 7270 emacs[5222]: No event to add Jun 14 09:11:57 7270 emacs[5222]: Package dash-functional is obsolete; use dash 2.18.0 instead Jun 14 09:12:01 7270 emacs[5222]: Loading /home/yitang/git/.emacs.d/config/org-mode.el (source)...done Jun 14 09:12:01 7270 emacs[5222]: Loading /home/yitang/git/.emacs.d/config/refile.el (source)... Jun 14 09:12:01 7270 emacs[5222]: Loading /home/yitang/git/.emacs.d/config/refile.el (source)...done Jun 14 09:12:01 7270 emacs[5222]: Loading /home/yitang/git/.emacs.d/config/scripting.el (source)... Jun 14 09:12:26 7270 emacs[5222]: Loading /home/yitang/git/.emacs.d/config/scripting.el (source)...done Jun 14 09:12:26 7270 emacs[5222]: Loading /home/yitang/git/.emacs.d/load_config.el (source)...done Jun 14 09:12:26 7270 emacs[5222]: Starting Emacs daemon. Jun 14 09:12:26 7270 systemd[4589]: Started Emacs text editor.
Enhance User Experience
For far, I have the following two tweaks to make the usage of systemd more pleasant.
sudo Privilege
The Emacs server is started using my own account, so it doesn't have the sudo privilege. In order to edit files that requires sudo permission, simple open the file in Emacs, or in command line with
then type M-x sudo
inside Emacs, type the sudo password. If the
password is correct, I can edit and save the file as sudo user.
Environment Variables
The customised shell configuration in .bashrc are loaded when opening an interactive shell session. So the Emacs server managed by systemd would not have the environment variables, alias, functions or whatever defined in .bashrc.
This stackoverflow post provides the rationale and how to tweak the unit file so systemd would load .bashrc.
This problem can solved a lot easier on the Emacs side, by using exec-path-from-shell package. It will ensure the environment variables inside Emacs are the same as in the user's interactive shell.
Simply put the following in your .emacs would do the trick.
Start Emacs Server Before Login?
The systemd services under my account would only start after I login. Because I have tons of Emacs configuration, I still have to wait few seconds before Emacs server is ready. So it would be awesome to have the Emacs server starting to load before I login.
This doesn't seems to be simple to implement, because technically, it would require the Emacs server to be defined on system level, but it will load files in my personal home drive without me being logged in. It might be still okay since I'm the sole user of my laptop, but I have to tweak the permissions and would probably end up with non-secure permission setting.
So I leave this idea here.