How to install and setup the Incus Web UI – Mi blog lah!
Incus is a manager for virtual machines (VM) and system containers. There is also an Incus support forum.
Typically you would use the incus
command-line interface (CLI) client to get access to the Incus manager and perform the tasks for the full life-cycle of the virtual machines and system containers.
In this post we see how to install and setup the Incus Web UI. Just like the incus
CLI tool that gets access to the REST API of the Incus manager (through a Unix socket or HTTPS), the Incus Web UI does the same over HTTPS. I assume that you have already installed and setup Incus.
Table of Contents
Installing the Incus Web UI package
The Incus Web UI package is incus-ui-canonical
. We install it. By installing the package, we can enable Incus to serve the necessary Web pages (from /opt/incus/ui
) so that we can connect with our browser and manage Incus itself.
sudo apt install -y incus-ui-canonical
Preparing Incus to serve the Web UI
By default Incus is not listening to a Web port so that we can access directly through the browser. We need to enable first Incus to activate access to the Web browser. By default there is no configuration with incus config show
.
debian@myincus:~$ incus config show
config: {}
debian@myincus:~$
We activate the Incus Web server, selecting the port number 8443. You are free to select another one, if you need to. We set core.https_address
to :8443
. This information appears in the incus config
output.
debian@myincus:~$ incus config set core.https_address :8443
debian@myincus:~$ incus config show
config:
core.https_address: :8443
debian@myincus:~$
Let’s verify that Incus is now listening to port 8443. Yes, it does. On all interfaces (because of the *
).
debian@myincus:~$ sudo apt install -y lsof
...
debian@myincus:~$ sudo lsof -i :8443
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
incusd 8338 root 8u IPv6 29751 0t0 TCP *:8443 (LISTEN)
debian@myincus:~$
This is HTTPS, where are the certificate and the server key (private key)?
debian@myincus:~$ sudo ls -l /var/lib/incus/server.key /var/lib/incus/server.crt
-rw-r--r-- 1 root root 753 Mar 28 18:54 /var/lib/incus/server.crt
-rw------- 1 root root 288 Mar 28 18:54 /var/lib/incus/server.key
debian@myincus:~$ sudo openssl x509 -in /var/lib/incus/server.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
22:05:f1:14:f2:82:43:68:44:5e:1c:42:4c:28:5b:5c
Signature Algorithm: ecdsa-with-SHA384
Issuer: O = Linux Containers, CN = root@myincus
Validity
Not Before: Mar 28 18:54:17 2024 GMT
Not After : Mar 26 18:54:17 2034 GMT
Subject: O = Linux Containers, CN = root@myincus
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:fb:cd:b6:b2:25:55:68:a5:33:75:48:4c:b0:7a:
2f:e9:c0:16:af:6f:b2:36:f9:19:6e:b0:86:bf:d1:
9f:07:16:b1:26:8b:75:36:f2:fc:02:38:c7:fa:25:
39:01:6c:bb:48:a9:4f:57:0d:af:e1:0f:a3:cf:b1:
7c:a2:d9:46:77:e7:94:c7:00:1a:d0:5f:5f:93:d8:
11:39:8d:16:0e:d0:62:98:81:93:da:ec:b8:70:24:
f2:c4:da:91:0f:f8:8e
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Alternative Name:
DNS:myincus, IP Address:127.0.0.1, IP Address:0:0:0:0:0:0:0:1
Signature Algorithm: ecdsa-with-SHA384
Signature Value:
30:64:02:30:15:f4:fa:7b:d6:52:79:d4:c9:27:b9:d6:6c:90:
f7:0e:13:83:15:ac:af:cd:c5:f2:48:08:99:7f:7b:94:55:06:
81:95:80:5f:0a:21:17:82:61:ac:5a:b6:5f:b8:49:b3:02:30:
62:a3:92:66:da:ce:7c:01:49:7e:38:16:c6:16:b3:cb:aa:3d:
1d:3f:63:12:93:e8:a1:0b:55:f0:80:99:d5:80:8a:a3:a6:2e:
3d:68:90:a6:dc:55:29:0b:36:80:36:72
debian@myincus:~$
Note that this is a self-signed certificate. Chrome, Firefox and other browsers will complain; you can still accept to continue but it will show a broken padlock at the address bar. If you wish, you can replace these with proper certificates so that the padlock is intact. To do so, once you replace the server key and the server certificate with actual values, restart Incus. If, however, you are running an Incus cluster, you must use lxc cluster update-certificate
instead to update them. Note that a common alternative to dealing with Incus certificates, is to use a reverse-proxy; you get the reverse-proxy to use a proper certificate and leave Incus as is.
At this point Incus is configured. We can continue with the next step where we get the client (our browser) to be authenticated to the server.
Getting the browser to authenticate to the server
Visit the URL of your Incus server with your browser. At first you will likely confronted with a message that the server certificate is not accepted (Warning: Potential Security Risk Ahead). Click to Accept and continue. Then, you are presented with the following screen that asks you to login. You are authenticated to the Incus server through user certificates. You are prompted here to do just that. Your browser will create
- a user certificate to be installed into Incus (
incus-ui.crt
) - the same user certificate with a private key that will be setup in your browser(s) (
incus-ui.pfx
).
Click on Create a new certificate.
Now click on Generate to get your browser to generate the private key and the certificate.
You are asked whether you want to protect the certificate with a password. In our case we click on Skip because we do not want to encrypt the private key with a password. By clicking on Skip, the private key is still generated but it is not getting encrypted.
At this point the browser generated incus-ui.crt
, which is the user certificate to install in Incus. In the following we added the user certificate to Incus.
debian@myincus:~$ incus config trust list
+------+------+-------------+-------------+-------------+
| NAME | TYPE | DESCRIPTION | FINGERPRINT | EXPIRY DATE |
+------+------+-------------+-------------+-------------+
debian@myincus:~$ incus config trust add-certificate incus-ui.crt
debian@myincus:~$ incus config trust list
+--------------+--------+-------------+--------------+----------------------+
| NAME | TYPE | DESCRIPTION | FINGERPRINT | EXPIRY DATE |
+--------------+--------+-------------+--------------+----------------------+
| incus-ui.crt | client | | b89b80eb4c89 | 2026/12/23 21:08 UTC |
+--------------+--------+-------------+--------------+----------------------+
debian@myincus:~$
The page above has instructions on how to add the user certificate to Firefox, Chrome, Edge and macOS. For example, for the case of Firefox, type the following to the address bar and press Enter. Alternatively, go to Settings→Privacy & Security→Certificates. There, click on View Certificates… and select the Your Certificates tab. Finally, click to Import… the incus-ui.pfx
certificate file.
about:preferences#privacy
When you add the incus-ui.pfx
user certificate in Firefox, it will appear as in the following screenshot.
Subsequently, switch back to the Firefox tab with the Incus UI page and you are shown the following prompt to get your browser to send the user certificate to the Incus manager in order to get authenticated, and be able to manage Incus through the Web. Click on OK.
Finally, you are able to manage Incus over the Web with Incus UI. The Web page loads up and you can perform all tasks that you can do with the incus
command-line client.
Using the Incus UI
We click on Create Instance to create a first instance. We select from the list which image to use, then click to Create and start.
While the instance is created, you are updated with the different steps that take place. In the end, the instance is successfully launched.
Conclusion
With Incus UI you are able to go through all the workflow of managing Incus instances through your Web browser. Incus UI has been implemented as a stateless Web application, which means that no information are stored on the browser. For example, the browser does not maintain a database with the created instances; the state is maintained on Incus.
There are a few more UI Web applications for Incus, including lxops
. At some point in the future I expect to cover them as well.
Tips and Tricks
How to make the Incus port accessible to localhost only
The address has the format of <ip address>:<port>. You can specify localhost (127.0.0.1) for the part of the IP address. By doing so, Incus will only bind to localhost and listen to local connections only.
debian@myincus:~$ incus config show
config:
core.https_address: :8443
debian@myincus:~$ incus config set core.https_address 127.0.0.1:8443
debian@myincus:~$ incus config show
config:
core.https_address: 127.0.0.1:8443
debian@myincus:~$ sudo lsof -i :8443
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
incusd 8338 root 8u IPv4 30315 0t0 TCP localhost:8443 (LISTEN)
debian@myincus:~$
What’s in incus-ui.crt
and incus-ui.pfx
?
You can use openssl
to decode both files. This is an RSA 2048-bit certificate using the SHA-1 hash function.
$ openssl x509 -in incus-ui.crt -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
01:12:00:11:07:65:00:03:00:10:00:41:00:04:09:11
Signature Algorithm: sha1WithRSAEncryption
Issuer: C = AU, ST = Some-State, O = Incus UI 10.10.10.98 (Browser Generated)
Validity
Not Before: Mar 28 21:08:58 2024 GMT
Not After : Dec 23 21:08:58 2026 GMT
Subject: C = AU, ST = Some-State, O = Incus UI 10.10.10.98 (Browser Generated)
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ce:f8:1d:67:e1:a3:f5:1a:16:b6:26:63:8f:32:
42:99:0d:af:86:8b:18:49:1a:4b:8e:ab:68:e1:04:
ba:24:dd:e6:27:d5:df:7a:13:cf:16:b3:33:28:89:
e0:ab:c8:dc:c1:2a:0a:de:ed:26:3a:77:74:dd:42:
1c:e2:22:fc:a5:a5:68:c1:c9:3b:4d:12:15:27:ae:
c6:50:ec:dc:f1:0a:ba:00:0c:83:d0:0d:0f:81:90:
4e:30:43:cb:45:bf:e2:e9:17:39:40:3b:95:8b:8b:
18:e9:59:51:fc:9a:7a:80:e4:73:b3:54:bd:ff:1c:
7c:81:75:16:e3:6f:3a:56:9b:0f:a3:73:55:45:03:
d8:fb:f3:34:4c:60:4f:f2:67:9f:66:ea:29:29:78:
6c:66:05:d6:7d:96:cd:0f:2b:4b:9c:71:2c:09:6f:
e2:b4:23:d0:5d:d0:fe:b0:6a:b1:58:5e:d7:b5:47:
9e:aa:47:34:f8:7d:e1:ed:fe:bf:97:3d:99:49:42:
af:e2:e5:b3:c5:1e:58:b1:98:01:db:8f:25:9f:f8:
d9:03:02:06:f9:99:0a:3a:a1:70:9d:fe:64:0d:c2:
d8:cc:f0:1c:53:e4:31:4c:78:12:c2:fd:72:23:6a:
f4:7e:41:f9:d5:df:6b:ad:2c:52:29:d0:7f:eb:65:
64:0f
Exponent: 65537 (0x10001)
Signature Algorithm: sha1WithRSAEncryption
Signature Value:
28:b3:5c:48:64:8c:23:82:dd:e2:05:6a:9d:18:dd:43:f4:07:
e6:be:1e:80:b7:f9:0c:0f:3d:cd:b8:bd:7b:55:7e:36:6d:74:
24:d5:69:b2:24:51:3a:2d:c5:95:68:b5:dc:27:d5:83:d9:bc:
cb:d0:fd:55:24:63:7d:c6:65:9b:f1:b3:9d:f7:b4:4e:ba:83:
eb:bf:f5:d0:f6:95:2d:7b:90:4e:d3:89:ac:f0:87:e6:fa:9d:
f6:ea:c2:42:f2:15:17:74:5c:e4:3c:ed:1a:42:3c:e7:04:aa:
65:42:3e:75:5c:24:8e:52:85:0d:4b:b2:e2:ec:fa:57:4a:68:
35:4b:8f:3c:13:fc:15:09:80:5a:b1:c8:e0:22:f5:69:25:4b:
46:8b:e0:b9:e1:3a:f5:0c:40:d2:c3:75:9c:79:9a:aa:68:9b:
21:36:ed:67:cb:6d:fc:bc:f0:0b:5a:2b:1a:4c:73:67:c5:79:
b6:27:b9:58:d0:c7:ea:84:21:bf:f4:7c:44:11:d7:88:ab:1d:
e4:53:c9:10:cd:e6:b8:5a:7a:92:73:a8:1e:fe:1c:2e:dc:e8:
7e:3d:e9:a2:6d:26:5a:09:40:a1:3e:51:40:8b:da:57:37:9a:
8d:0e:d8:cf:c1:0a:b1:0b:95:53:05:41:29:39:af:93:9b:aa:
10:af:a1:6c
$
For the incus-ui.pfx
file, we first convert to the PEM format, then print the contents. The PFX file contains the certificate (the same that was added earlier to Incus) along with the private key.
$ openssl pkcs12 -in incus-ui.pfx -out incus-ui.pem -noenc
Enter Import Password:
$ cat incus-ui.pem
Bag Attributes
localKeyID: 3A 23 25 F7 56 4D 71 B8 FB FD 72 90 2D A1 F3 B8 2F 01 5E 92
friendlyName: Incus-UI
subject=C = AU, ST = Some-State, O = Incus UI 10.10.10.98 (Browser Generated)
issuer=C = AU, ST = Some-State, O = Incus UI 10.10.10.98 (Browser Generated)
-----BEGIN CERTIFICATE-----
MIIDMjCCAhqgAwIBAgIQARIAEQdlAAMAEABBAAQJETANBgkqhkiG9w0BAQUFADBV
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTExMC8GA1UEChMoSW5j
dXMgVUkgMTAuMTAuMTAuOTggKEJyb3dzZXIgR2VuZXJhdGVkKTAeFw0yNDAzMjgy
MTA4NThaFw0yNjEyMjMyMTA4NThaMFUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
b21lLVN0YXRlMTEwLwYDVQQKEyhJbmN1cyBVSSAxMC4xMC4xMC45OCAoQnJvd3Nl
ciBHZW5lcmF0ZWQpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzvgd
Z+Gj9RoWtiZjjzJCmQ2vhosYSRpLjqto4QS6JN3mJ9XfehPPFrMzKIngq8jcwSoK
3u0mOnd03UIc4iL8paVowck7TRIVJ67GUOzc8Qq6AAyD0A0PgZBOMEPLRb/i6Rc5
QDuVi4sY6VlR/Jp6gORzs1S9/xx8gXUW4286VpsPo3NVRQPY+/M0TGBP8mefZuop
KXhsZgXWfZbNDytLnHEsCW/itCPQXdD+sGqxWF7XtUeeqkc0+H3h7f6/lz2ZSUKv
4uWzxR5YsZgB248ln/jZAwIG+ZkKOqFwnf5kDcLYzPAcU+QxTHgSwv1yI2r0fkH5
1d9rrSxSKdB/62VkDwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQAos1xIZIwjgt3i
BWqdGN1D9Afmvh6At/kMDz3NuL17VX42bXQk1WmyJFE6LcWVaLXcJ9WD2bzL0P1V
JGN9xmWb8bOd97ROuoPrv/XQ9pUte5BO04ms8Ifm+p326sJC8hUXdFzkPO0aQjzn
BKplQj51XCSOUoUNS7Li7PpXSmg1S488E/wVCYBascjgIvVpJUtGi+C54Tr1DEDS
w3WceZqqaJshNu1ny238vPALWisaTHNnxXm2J7lY0MfqhCG/9HxEEdeIqx3kU8kQ
zea4WnqSc6ge/hwu3Oh+PemibSZaCUChPlFAi9pXN5qNDtjPwQqxC5VTBUEpOa+T
m6oQr6Fs
-----END CERTIFICATE-----
Bag Attributes
localKeyID: 3A 23 25 F7 56 4D 71 B8 FB FD 72 90 2D A1 F3 B8 2F 01 5E 92
friendlyName: Incus-UI
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDO+B1n4aP1Gha2
JmOPMkKZDa+GixhJGkuOq2jhBLok3eYn1d96E88WszMoieCryNzBKgre7SY6d3Td
QhziIvylpWjByTtNEhUnrsZQ7NzxCroADIPQDQ+BkE4wQ8tFv+LpFzlAO5WLixjp
WVH8mnqA5HOzVL3/HHyBdRbjbzpWmw+jc1VFA9j78zRMYE/yZ59m6ikpeGxmBdZ9
ls0PK0uccSwJb+K0I9Bd0P6warFYXte1R56qRzT4feHt/r+XPZlJQq/i5bPFHlix
mAHbjyWf+NkDAgb5mQo6oXCd/mQNwtjM8BxT5DFMeBLC/XIjavR+QfnV32utLFIp
0H/rZWQPAgMBAAECggEBAMm1N/tpBgC291F4YmlJg2xk0R8f6oA8V0zpMyKyF7Qc
atWB8/Wm3pnx9bbZgRQKg1LiZYvTtgEfMM7+QuYFURMi/NB4DQpUyDdPd0mhPsbQ
WVH8mnqA5HOzVL3/HHyBdRbjbzpWmw+jc1VFA9j78zRMYE/yZ59m6ikpeGxmBdZ9
+uKyZ4U4/TORu2tadg9frtUl1HhkY1zGAxOyJUbCOVIbZF2iQt5zMZt4XLFhKgwh
jtDklc3dFIDigUZzpMgdLExLWi6CGT++cjJGpseM+QOAubSoCmT6eIs8qi9KpQhk
aZYBerWqBxswkmNGK4Zh+5gFvdW7EmEp128hATgYZGECgYEA7ckh3qL4Jg6FQA8+
UeEoaT2CvDI89HMJfFN2NvU1ZklqP9aDnPvMjui/h/8HtDeb+5FWFZHF1B9laJp3
HnGGt+98/aO9skdFQDiszclDNIHdpSqcD2LWkKz84QTWqTTkRAxJpgnW91oURtyh
WVH8mnqA5HOzVL3/HHyBdRbjbzpWmw+jc1VFA9j78zRMYE/yZ59m6ikpeGxmBdZ9
JSltWZtYemYzPTpZysocyRs5mD8CgYEA3tKviDreIR+TKT3FQoevyicXuwSn6ocH
2RTgJQF+Qyj+1ykQhwRQUD+axZGls5g2JgT+2gFIdUcAR9CN22rxLRbnIj645yGP
Ka4dVhNAZnz/olWgs4onoO0CnOGXAkVdyiBe9H/D1dkj5bqAfY1eov6khPMOyrDF
EXGi0e6uInbddI/sHUAAIIqJ4+knqwJIgxlzA9GFuzzt4oRLGMsoaClLYFCsrekJ
SF/w7DvhoDQo+JIrHuGX4hLgFLWOgp2WMWhbvgZ0P1PWcJukZ/jx7rJmkwKBgGa5
7x75NMtEiU3sInMnpw2ltDUOUnO3SRD1pNiqtZE05zg+wFXe0UAN8sa+/QutUtl4
WVH8mnqA5HOzVL3/HHyBdRbjbzpWmw+jc1VFA9j78zRMYE/yZ59m6ikpeGxmBdZ9
WB4dlVAsKZ7yMVRFG2dUNb7997TnLd9jXDcArSIS4q/uliXvvZFdc2TsQ/hSDolP
HzfNZ3XBo+EXeIFpmYW/rA13GQytLl5oDC28WaEhAoGBAL6acBqMflXUoWWVHZR7
0vNcJjtRTC13SGRoAKR/tT2kUqloz60bgWeVtggkFWTpPGgm6lmSuYvTnPeoHYDf
vLibVFGasTk8Y7Aji0V7rF4O
-----END PRIVATE KEY-----
$
Troubleshooting
Error: Unable to connect
You tried to access the IP address of the Incus server as (for example) https://192.168.1.10/
while you should have specified the IP address as well. The URL should look like https://192.168.1.10:8443/
.
Error: Client sent an HTTP request to an HTTPS server
You tried to connect to the Incus server at an address (for example) http://192.168.1.10:8443/
but you omitted the s
in https
. Use https://192.168.1.10:8443/
instead.
Warning: Potential Security Risk Ahead
You are accessing the Incus server through the HTTPS address for the first time and the certificate has not been signed by a certification authority.
Click on Advanced and select to Accept the risk and Continue. If you want to avoid this error message, you need to provide a server certificate that is accepted by your browser.