This guide walks you step by step until you get Wiki.js published as a service on the Edge that can be accessed on the Internet.
Make sure that all of the mandatory prerequisites have been met before progressing further.
Name | Source | Description |
---|---|---|
<CONTAINER_NAME> | User input | The name of the Linux container where the app will be run. |
<DB_PASSWORD> | User input | The password for logging in with the wiki PostgreSQL user. |
<IP_ADDRESS__CONTAINER> | Generated | The IPv4 address of the contaier run by the server on the Edge. |
<IP_ADDRESS__EDGE_SERVER_VPN> | Generated | The IPv4 address of the Server on The Edge in the VPN. |
<ROOT_PWD__CONTAINER> | User input | The password of the root user in the container. |
<IP_ADDRESS_INET_GW> | Linux VPS Admin Panel | The static and public IPv4 address of the Internet Gateway. |
<WIKIJS_WEBSITE_DOMAIN> | User input | The host for the A record created with your domain registrar, e.g. wiki.myowndomain.net . |
Run the following commands on your server on the Edge.
incus launch images:debian/bookworm/cloud <CONTAINER_NAME>
incus exec <CONTAINER_NAME> bash
It is often the case that changing the MTU is required in order for TLS to work correctly. Please, note that this setting is non persistent and it will be lost when the container will be rebooted next time.
ip link set dev eth0 mtu 1000
apt update && apt upgrade && apt install fish
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
passwd
Set a password for the root user and make a (mental) note of it. It will be denoted with a variable <ROOT_PWD__CONTAINER>.
From here on the root user will use fish
as default shell.
chsh -s /usr/bin/fish
Let's create the wiki
user and set a system password for it.
useradd -m -s /usr/bin/fish wiki
passwd wiki
The ability to establish SSH connections from the server on the Edge to the container is key for the upcoming Ansible automation. There is an Ansible connection driver for Linux containers with limited capabilities. The default Ansible connection driver through SSH is much more robust and powerful.
You can perform this step now or in future, when you make up your mind to give the automated solutions for system and application maintanence a try.
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
apt update && apt install openssh-server
vi /etc/ssh/sshd_config
Add the following line to the file.
PermitRootLogin yes
systemctl enable ssh
systemctl start ssh
systemctl restart ssh
Run the following commands on your server on the Edge.
Run ssh-keygen
only if you haven't generated SSH private and public keys on the server on the Edge. Otherwise use the already existing pair.
ssh-keygen
incus ls | grep <CONTAINER_NAME>
Make a note of the IPV4 value <IP_ADDRESS__CONTAINER>.
ssh-copy-id root@<IP_ADDRESS__CONTAINER>
Pass the password for the root
user in the container as prompted.
From here on SSH connection as the
root
user will be possible from the server on the Edge to the container. Containers are not visible and accessible to any other network devices.
Run the following commands on your server on the Edge.
incus exec <CONTAINER_NAME> fish
Let's harden the setup of the ssh server running in the container by disabling the password for logging in with root
.
vi /etc/ssh/sshd_config
Delete the line PermitRootLogin yes
.
Append the line PermitRootLogin prohibit-password
.
systemctl restart ssh
You should have a fully functional Linux container named
<CONTAINER_NAME>
that has also a non-administrative userwiki
. In addition, the server on the Edge listens for SSH connections with theroot
user. You know all login credentials.
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
apt update && apt install curl
su wiki
cd ~
curl -sL https://git.io/fisher | source && fisher install jorgebucaran/fisher
Installs the fish plugin manager
.
fisher install jorgebucaran/nvm.fish
Installs node version manager (nvm).
nvm install lts/gallium
Installs and sets 16.x.y LTS version of node.js. Later versions are not supported yet.
set --universal nvm_default_version v16.20.1
Use the specific version of your node.js Gallium LTS.
Verify that the stage has been completed successfully by running the following command on a server on the Edge. It is supposed to dump
v16.20.1
.
node --version
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc|sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
apt update && apt install postgresql-15
In order to enable data checksums we need to delete the existing cluster and initialize it again.
rm -rf /var/lib/postgresql/15/main
mkdir /var/lib/postgresql/15/main
chown postgres:postgres /var/lib/postgresql/15/main
chmod 700 /var/lib/postgresql/15/main
sudo -u postgres /usr/lib/postgresql/15/bin/initdb \
-D /var/lib/postgresql/15/main/ \
--locale=C.UTF-8 --encoding=UTF8 --data-checksums
systemctl enable postgresql@15-main.service
systemctl start postgresql@15-main.service
Verify that the stage has been completed successfully by running the following command in the container. Its output should indicate that the service is running.
systemctl status postgresql@15-main.service
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
Take a not of the password for the database user. It will be denoted with a variable <DB_PASSWORD>.
sudo -u postgres createuser wiki --interactive --pwprompt
Take a note of the password <DB_PASSWORD>.
sudo -u postgres createdb wiki -O wiki --encoding='utf-8'
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
apt update && apt install wget
cd /opt
wget https://github.com/Requarks/wiki/releases/latest/download/wiki-js.tar.gz
mkdir wiki
tar -xvf wiki-js.tar.gz -C wiki
cp wiki/config.sample.yml wiki/config.yml
chown -R wiki:wiki wiki
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
vi /etc/systemd/system/wiki.service
Add the following content to /etc/systemd/system/wiki.service
. Make sure that all paths match the setup in your container.
[Unit]
Description=Wiki.js
After=network.target
[Service]
Type=simple
# The path is a bit ugly because of nvm
ExecStart=/home/wiki/.local/share/nvm/v16.20.1/bin/node server
Restart=always
User=wiki
Environment=NODE_ENV=production
WorkingDirectory=/opt/wiki
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable wiki
systemctl start wiki
You should be able to run a successful HTTP request against the wiki.js server from within the container.
curl http://localhost:3000
The stable version of Wiki.js does not offer generation of sitemap.xml
out of the box. This is very unfortunate with regard to SEO optimization and boosting traffic from search engines. There is a 3rd party sitemap generator, which just works. We are going to benefit from it.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
cd /opt
git clone https://github.com/hostwiki/wikijs-sitemap
cd wikijs-sitemap
Edit the existing .env
configuration file.
vi .env
Do not forget to substitute the variables enclosed in <...>
with their real values matching your setup.
DB_TYPE=postgres
DB_HOST=localhost
DB_PORT=5432
DB_USER=wiki
DB_PASS=<DB_PASSWORD>
DB_NAME=wiki
DB_SSL=false
PORT=3012
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
vi /etc/systemd/system/wiki-sitemap.service
Add the following content to /etc/systemd/system/wiki-sitemap.service
. Make sure that all paths match the setup in your container.
[Unit]
Description=Wiki.js Sitemap Service
After=network.target
[Service]
Type=simple
# The path is a bit ugly because of nvm
ExecStart=/home/wiki/.local/share/nvm/v16.20.1/bin/node server
Restart=always
User=wiki
Environment=NODE_ENV=production
WorkingDirectory=/opt/wikijs-sitemap
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable wiki-sitemap
systemctl start wiki-sitemap
You should be able to run a successful HTTP request against the wiki.js sitemap server from within the container. It should return the sitemap for your wiki.js instance.
curl http://localhost:3012/sitemap.xml
In order to complete this stage you need to perform the following commands in the container run by the server on the Edge.
If you are not already within the container, run the following command on your server on the Edge to log in as
root
.
incus exec <CONTAINER_NAME> fish
mkdir /opt/wiki-ssl
chown -R wiki:wiki /opt/wiki-ssl`
openssl req -x509 -newkey rsa:4096 -days 365 -keyout /opt/wiki-ssl/wikikey.pem -pubkey -out /opt/wiki-ssl/wikicrt.pem
vi /opt/wiki/config.yml
Enable SSL by making sure that the SSL configuration looks like this and that all of the paths are correct in your container.
ssl:
enabled: true
port: 3443
ptovider: custom
format: pem
key: /opt/wiki-ssl/wikikey.pem
cert: /opt/wiki-ssl/wikicrt.pem
# null or the passphrase that you used while generating self signed certificates
passphrase: null
systemctl restart wiki
Now the wiki.js server should be accessible within the container.
curl --insecure https://localhost:3443
In a terminal on on the server on the Edge run the following command to forward incoming HTTPS connections on port 3443
of the server to port 3443
on the container.
incus config device add <CONTAINER_NAME> http-le-3443 proxy listen=tcp:0.0.0.0:3443 connect=tcp:127.0.0.1:3443
From here on the wiki.js server should be accessible from the server and any other device in the same network.
curl --insecure https://localhost:3443
In a terminal on on the server on the Edge run the following command to forward incoming HTTP connections on port 3012
of the server to port 3012
on the container. This way sitemap generation will be transparent to any Internet crawlers.
incus config device add <CONTAINER_NAME> http-le-3012 proxy listen=tcp:0.0.0.0:3012 connect=tcp:127.0.0.1:3012
From here on the wiki.js sitemap should be accessible from the server and any other device in the same network.
curl http://localhost:3012/sitemap.xml
Make sure that you have created an A domain record for <WIKIJS_WEBSITE_DOMAIN> with your domain registrar and you have waited for this record to become active.
If you use a domain name and that's not picked up by the domain name servers yet, Caddy will not be able to serve HTTPS requests because of Let's Encrypt (An SSL certificate authority) failing to verify the validity (ownership over) of the domain.
ssh mycelium@<IP_ADDRESS__INET_GW>
sudo su -
Add the following to /etc/caddy/Caddyfile
.
The connection between the load balancer and the sitemap generator will be unencrypted over plain HTTP. This is because the sitemap generator is quite simple and does not support TLS. This is a risk but communication between the Internet Gateway and the Server on the Edge goes through an encrypted VPN, so hopefully it's not a huge risk.
Do not forget to substitute the variables enclosed in <...>
with the real values matching your setup.
<WIKIJS_WEBSITE_DOMAIN> {
reverse_proxy http://<IP_ADDRESS__EDGE_SERVER_VPN>:3012/sitemap.xml
reverse_proxy https://<IP_ADDRESS__EDGE_SERVER_VPN>:3443
}
systemctl reload caddy
If everything is configured well, you should be able to access the wiki through its domain name by using a web browser by typing
https://<WIKIJS_WEBSITE_DOMAIN>
in the address bar.