Serve Local Web Application on Linux

This is record about how I manage local web-based application and wrap them with Electron. Why I choose Electron rather than just opening them in a browser is that separated applications provide more flexibility for WM.

Electron applications tiled in i3
Electron applications tiled in i3

Wrap a Web Service with Electron

nativefier is a tool to make any web page an electron application. However, local static files are not supported and hard to manage. So our goal is to host applications(static/server) in an organized way.

Host Static Files and Reverse Proxy

Of course I choose Nginx as a (host/reverse proxy). The server_name is in the form of {app_name.domain} and will be the entry of our applications used by nativefier. How the server_name is set will be discussed in the next section.

Static Files

1
2
3
4
5
6
7
8
server {
listen 80;
server_name aria-ng.lan;
location / {
root /home/username/local/share/static-apps/AriaNg/build/;
index index.html;
}
}

Server

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name resilio-sync.lan;
location / {
proxy_pass http://localhost:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

Override Local DNS

Remembering ports for services is really painful, right? What we want to do here is to resolve *.lan locally and let Nginx handle request. Unfortunately /etc/hosts doesn't support wildcard, so dnsmasq is used to modify DNS resolving.

Disable /etc/resolv.conf generation of NetworkManager

network manager: how to stop nm updating /etc/resolv.con

Add dns=none to /etc/NetworkManager/NetworkManager.conf

Setup DNS with dnsmasq

how to get dnsmasq private nameserver to work with networkmanager?

Install dnsmasq and add edit /etc/dnsmasq.conf:

  • set(uncomment) no-resolv to prevent reading /etc/resolv.conf
  • add address=/loc/127.0.0.1 to point *.loc to localhost

(be careful that local might be reserved so I use loc here)

  • add server=1.1.1.1 to provide DNSs for public domains

Restart dnsmasq.

Point dns resolving to 127.0.0.1 in /etc/resolv.conf

Add(uncomment) name_servers=127.0.0.1 in /etc/resolvconf.conf. Then run sudo resolvconf -u to generate /etc/resolv.conf

Make Electron Application and Generate .desktop files

After confirming our service can be accessed by *.lan, use nativefier to generate the folder of electron applications: nativefier app_name.lan

Now the application can launch with: ./app_name-linux-x64/app_name

A simple script here to generate and install the .desktop files:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/bin/bash
# Make .desktop file and install it to /usr/share/appliations
# for all electron apps generated by https://github.com/jiahaog/nativefier in current folder
# app source dir name convention: {app-name}-linux-x64
gen_and_install_desktop() {
rel_src_path=$1
exec_name=$(echo $rel_src_path | grep -oP '\w+(-\w+)*(?=-linux)')
app_name=$(echo $exec_name | sed 's/^./\U&/; s/-\(.\)/\U\1/')
abs_src_path=$(realpath $rel_src_path)
sudo tee /usr/share/applications/${exec_name}.desktop > /dev/null << EOF
[Desktop Entry]
Type=Application
Name=$app_name
Comment=Electron App of $app_name
Exec=${abs_src_path}/${exec_name}
Icon=${abs_src_path}/resources/app/icon.png
Categories=Electron;Application;
Terminal=false
EOF
}
for dir in $(find . -maxdepth 1 -type d -not -path '.'); do
gen_and_install_desktop $dir
done

Finally launch our applications with the launcher. Enjoy it :)