# perlite Setup ![](0.svg) [Perlite](https://github.com/secure-77/Perlite) is an awesome project by [sec77](https://secure77.de/) to display your obsidian notes on the web, essentially an alternative to the paid Obsidian publish. ## **Initial Setup** You'll need nginx and php8.2 and some dependencies: [ 10.8.0.2/24 ] [ home ] [/srv] → apt install nginx php8.2-fpm php-mbstring php-yaml -y [ 10.8.0.2/24 ] [ home ] [/srv] → vim /etc/nginx/sites-available/perlite.nowhere.moe.conf Then we can git clone the project wherever, i put it in /srv/: [ 10.8.0.2/24 ] [ home ] [/srv/perlite] → git clone https://github.com/secure-77/Perlite [ 10.8.0.2/24 ] [ home ] [/srv/] → chown -R www-data: /srv/Perlite [ 10.8.0.2/24 ] [ home ] [/srv/] → cd Perlite Now from here you will need the following nginx config: [ 10.8.0.2/24 ] [ home ] [/srv/Perlite] → cat /etc/nginx/sites-available/perlite.nowhere.moe.conf server { #apt install apache2-utils -y #htpasswd -c /etc/nginx/auth/default.htpasswd nothing auth_basic "Password protection"; auth_basic_user_file /etc/nginx/auth/default.htpasswd; server_name perlite.nowhere.moe; root /srv/Perlite/perlite/; index index.php index.html index.htm; location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; } location ~ /\.ht { deny all; } location ~* ^/(.*)/.obsidian/appearance.json$ { allow all; } location ~* ^/(.*)/.obsidian/(.*)/theme.css$ { allow all; } #added for this specific setup, thanks sec77! location ~* ^/.obsidian/(.*)/theme.css$ { allow all; } location ~ \.(git|github|obsidian|trash) { deny all; } location ~ \.(md|json)$ { deny all; } } For now it's just on port 80, and with a basicauth because i want it to be in maintenance mode for now, then we go into the perlite folder: [ 10.8.0.2/24 ] [ home ] [/srv] → cd Perlite [ 10.8.0.2/24 ] [ home ] [/srv/Perlite] → ls -lash total 72K 4.0K drwxr-xr-x 7 root root 4.0K Dec 7 22:20 . 4.0K drwxr-xr-x 7 root root 4.0K Dec 7 22:20 .. 4.0K drwxr-xr-x 8 root root 4.0K Dec 7 22:20 .git 4.0K -rw-r--r-- 1 root root 66 Dec 7 22:20 .gitattributes 4.0K drwxr-xr-x 3 root root 4.0K Dec 7 22:20 .github 4.0K -rw-r--r-- 1 root root 118 Dec 7 22:20 .gitignore 8.0K -rw-r--r-- 1 root root 4.4K Dec 7 22:20 Changelog.md 4.0K drwxr-xr-x 7 root root 4.0K Dec 7 22:20 Demo 4.0K -rw-r--r-- 1 root root 2.0K Dec 7 22:20 Docker.md 4.0K -rw-r--r-- 1 root root 1.1K Dec 7 22:20 LICENSE 8.0K -rw-r--r-- 1 root root 6.7K Dec 7 22:20 README.md 4.0K -rw-r--r-- 1 root root 182 Dec 7 22:20 SECURITY.md 4.0K -rw-r--r-- 1 root root 565 Dec 7 22:20 docker-compose-dev.yml 4.0K -rw-r--r-- 1 root root 522 Dec 7 22:20 docker-compose.yml 4.0K drwxr-xr-x 5 root root 4.0K Dec 7 22:21 perlite 4.0K drwxr-xr-x 3 root root 4.0K Dec 7 22:20 web [ 10.8.0.2/24 ] [ home ] [/srv/Perlite] → cd perlite [ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite] → ls -lash total 216K 4.0K drwxr-xr-x 5 root root 4.0K Dec 7 22:21 . 4.0K drwxr-xr-x 7 root root 4.0K Dec 7 22:20 .. 4.0K drwxr-xr-x 2 root root 4.0K Dec 7 22:20 .js 4.0K drwxr-xr-x 4 root root 4.0K Dec 7 22:20 .styles 4.0K -rw-r--r-- 1 root root 508 Dec 7 22:20 Dockerfile 4.0K -rw-r--r-- 1 root root 151 Dec 7 22:20 Dockerfile.dev 4.0K drwxr-xr-x 6 root root 4.0K Dec 7 22:21 **Obsidian** 44K -rw-r--r-- 1 root root 42K Dec 7 22:20 Parsedown.php 12K -rw-r--r-- 1 root root 11K Dec 7 22:20 PerliteParsedown.php 8.0K -rw-r--r-- 1 root root 4.3K Dec 7 22:20 content.php 16K -rw-r--r-- 1 root root 16K Dec 7 22:20 favicon.ico 12K -rw-r--r-- 1 root root 12K Dec 7 22:21 helper.php 56K -rw-r--r-- 1 root root 54K Dec 7 22:20 index.php 20K -rw-r--r-- 1 root root 17K Dec 7 22:20 logo.svg 20K -rw-r--r-- 1 root root 17K Dec 7 22:20 perlite.svg This is where the root of the website will be. In here you can put your vault as a sub-folder, here i put mine as the "Obsidian" folder as you can see above. Before you put it there, you will need to do a few things. First of all you need the Obsidian plugin "Metadata Extractor" to get the generated **metadata.json** file, along with the enabled "write JSON files automatically when Obsidian Launches" option: ![](1.png) [ 10.8.0.2/24 ] [ home ] [Perlite/perlite/Obsidian] → ls -lash total 260K 4.0K drwxr-xr-x 6 root root 4.0K Dec 7 22:21 . 4.0K drwxr-xr-x 5 root root 4.0K Dec 7 22:21 .. 4.0K drwxr-xr-x 8 root root 4.0K Dec 7 22:21 .git 4.0K drwxr-xr-x 4 root root 4.0K Dec 7 22:21 .obsidian 4.0K drwxr-xr-x 15 root root 4.0K Dec 7 22:21 HTB 0 -rw-r--r-- 1 root root 0 Dec 7 22:21 README.md 4.0K drwxr-xr-x 3 root root 4.0K Dec 7 22:21 Sysadmin 228K -rw-r--r-- 1 root root 225K Dec 7 22:21 **metadata.json** 4.0K -rwxr-xr-x 1 root root 85 Dec 7 22:21 pull.sh 4.0K -rwxr-xr-x 1 root root 207 Dec 7 22:21 push.sh Then you need to have the **New link format** option set to **relative path to file** (it's in the **Files & Links** menu in obsidian settings: ![](2.png) For further tweaking, please look at sec77's documentation [here](https://github.com/secure-77/Perlite/) From here you should already see your website as follows: [ 10.8.0.2/24 ] [ home ] [Perlite/perlite/Obsidian] → systemctl restart php8.2-fpm nginx ![](3.png) (big thanks to sec77 for showing me the fix here), If your theme doesn't load or if the vault doesnt show up, you can manually set the root directory of the vault in the helper.php file: 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite] → cat helper.php| grep rootDir //$rootDir = getenv('NOTES_PATH'); $rootDir = **'Obsidian'** ; $vaultName = $rootDir; [...] Here you see i setup mine to the relative path 'Obsidian' which points to the subdirectory in **/srv/Perlite/perlite/Obsidian/**. And there you go! ![](4.png) ## **TLS Setup** If you want it setup with TLS just use acme.sh: [ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite] → acme.sh --issue --standalone -d perlite.nowhere.moe -k 4096 [Wed Dec 7 22:59:59 CET 2022] Using CA: https://acme-v02.api.letsencrypt.org/directory [Wed Dec 7 22:59:59 CET 2022] Standalone mode. [Wed Dec 7 22:59:59 CET 2022] Creating domain key [Wed Dec 7 23:00:00 CET 2022] The domain key is here: /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.key [Wed Dec 7 23:00:00 CET 2022] Single domain='perlite.nowhere.moe' [Wed Dec 7 23:00:00 CET 2022] Getting domain auth token for each domain [Wed Dec 7 23:00:03 CET 2022] Getting webroot for domain='perlite.nowhere.moe' [Wed Dec 7 23:00:04 CET 2022] Verifying: perlite.nowhere.moe [Wed Dec 7 23:00:04 CET 2022] Standalone mode server [Wed Dec 7 23:00:06 CET 2022] Pending, The CA is processing your order, please just wait. (1/30) [Wed Dec 7 23:00:09 CET 2022] Success [...] [Wed Dec 7 23:00:12 CET 2022] Your cert is in: /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.cer [Wed Dec 7 23:00:12 CET 2022] Your cert key is in: /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.key [Wed Dec 7 23:00:12 CET 2022] The intermediate CA cert is in: /root/.acme.sh/perlite.nowhere.moe/ca.cer [Wed Dec 7 23:00:12 CET 2022] And the full chain certs is there: /root/.acme.sh/perlite.nowhere.moe/fullchain.cer and then for the nginx config with TLS I use the following: [ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite] → cat /etc/nginx/sites-available/perlite.nowhere.moe.conf server { listen 80; listen [::]:80; server_name perlite.nowhere.moe; return 301 https://$server_name$request_uri; } server { ######## TOR CHANGES ######## listen 4443; listen [::]:4443; server_name perlite.nihilisxacas2ntt3kb2nzfjp4nu5enratyehvahllblxgq2tqpsrnid.onion; add_header Onion-Location "http://perlite.nihilisxacas2ntt3kb2nzfjp4nu5enratyehvahllblxgq2tqpsrnid.onion$request_uri" always; ######## TOR CHANGES ######## listen 443 ssl http2; listen [::]:443 ssl http2; server_name perlite.nowhere.moe; ssl_certificate /root/.acme.sh/perlite.nowhere.moe/fullchain.cer; ssl_trusted_certificate /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.cer; ssl_certificate_key /root/.acme.sh/perlite.nowhere.moe/perlite.nowhere.moe.key; ssl_protocols TLSv1.3 TLSv1.2; ssl_ciphers 'TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-AES-128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256'; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; ssl_ecdh_curve auto; ssl_stapling on; ssl_stapling_verify on; resolver 80.67.188.188 80.67.169.40 valid=300s; resolver_timeout 10s; add_header X-XSS-Protection "1; mode=block"; #Cross-site scripting add_header X-Frame-Options "SAMEORIGIN" always; #clickjacking add_header X-Content-Type-Options nosniff; #MIME-type sniffing add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"; root /srv/Perlite/perlite/; index index.php index.html index.htm; location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; } location ~ /\.ht { deny all; } location ~* ^/(.*)/.obsidian/appearance.json$ { allow all; } location ~* ^/(.*)/.obsidian/(.*)/theme.css$ { allow all; } #added for this specific setup, thanks sec77! location ~* ^/.obsidian/(.*)/theme.css$ { allow all; } location ~ \.(git|github|obsidian|trash) { deny all; } location ~ \.(md|json)$ { deny all; } } [ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite] → nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful [ 10.8.0.2/24 ] [ home ] [/srv/Perlite/perlite] → systemctl restart nginx ![](5.png) And there you go! We have been able to publish our obsidian notes on the web from our a VPS.