💾 Archived View for gemini.patatas.ca › posts › tootik-capsule-nginx.gmi captured on 2024-12-17 at 09:44:51. Gemini links have been rewritten to link to archived content

View Raw

More Information

-=-=-=-=-=-=-

2024-12-12

Hosting a tootik server and a gemini capsule on the same machine, with nginx

Recently spun up an instance of tootik, the ActivityPub server software that speaks the gemini protocol, on my Debian server.

tootik on GitHub

The official setup guide is great - however, as a bit of a noob still, it took me a bit of trial and error to get it working alongside the existing gemini capsule on my machine, so I figured I'd write up a quick guide for anyone else that wants to do something similar. This should work for any gemini server that allows you to choose the port it listens on. I'm currently using gmCapsule.

* * *

Steps to get everything working, assuming you've already installed a gemini server that hosts your capsule and want to add tootik:

Basic stuff: DNS & nginx

complete steps 1 & 2 from the tootik setup guide:

https://github.com/dimkr/tootik/blob/main/SETUP.md

Install nginx and certbot; you will probably also want the python3-certbot-nginx plugin.

In a terminal, go to /etc/nginx/sites-available and then run

sudo nano tootik

to create a super basic nginx config containing the following:

server {
        listen 80;
        server_name tootik.example.com;
}

Save this, then create a soft-link to this file by running:

sudo ln -s /etc/nginx/sites-available/tootik /etc/nginx/sites-enabled/tootik

check the nginx config:

sudo nginx -t

if everything is OK, then restart nginx and run certbot on your tootik domain:

sudo systemctl restart nginx

sudo certbot --nginx -d tootik.example.com

Forwarding the request headers

open up /etc/nginx/sites-available/tootik again. You should now have two separate server blocks, one listening port 80 (http) that now redirects to the other server block listening on port 443 (https).

Add the following *inside the port 443 server block*, replacing port 8080 with whatever internal port you want tootik to listen on for http. These lines ensure that the request headers are forwarded to the tootik instance, as described in the 'Running behind a reverse proxy' section of the setup guide:

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_pass_request_headers on;
        proxy_set_header Signature $http_signature;
        proxy_set_header Collection-Syncronization $http_collection_synchronization;
        proxy_http_version 1.1;	
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /inbox/$user {
		
        proxy_method POST;
        proxy_pass_request_headers on;
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Signature $http_signature;
        proxy_set_header Collection-Synchronization $http_collection_synchronization;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Host $host;
    }

Is some of this redundant? Maybe, I genuinely don't know. But it works :))

Next, complete steps 5 to 7 of the tootik setup guide. For step 8, make sure to refer once again to 'Running behind a reverse proxy' for instructions on running tootik from the command line. Then perform step 9.

Don't cross the gemini streams

This was the other part that had me scratching my head while setting things up. Nginx doesn't recognize gemini:// addresses, so it wasn't clear how I could get nginx to listen for all gemini traffic on external port 1965, and then reverse proxy traffic to both my gemini capsule, and the tootik server. Luckily, someone had provided a clue:

https://pastebin.com/QHWhAWyM

My understanding is that a 'stream' block added to /etc/nginx.conf allows arbitrary data (i.e., anything not using a protocol recognized by nginx e.g. http) to be proxied.

Anyway, working on the same logic as the pastebin example, I added the following lines to /etc/nginx.conf, right after the end of the http block.

stream {
 
    ###
    ### Setup
    ###
 
    # connection-limiting
    limit_conn_zone               $binary_remote_addr zone=addr:10m;
    limit_conn_log_level          warn;
    limit_conn                    addr 1;
 
    # logging
    log_format                    basic '$remote_addr $upstream_addr [$time_local] '
                                  '$protocol $status $bytes_sent $bytes_received '
                                  '$session_time';
    access_log                    syslog:server=unix:/dev/log basic;
    error_log                     stderr info;
    error_log                     /var/log/nginx/error.log warn;
 

    ### !!! change the following to your domains !!! ###

    # map SNI -> backend service
    map   $ssl_preread_server_name    $name {
          geminicapsule.example.com	  mycapsule;
      	  tootik.example.com      	  tootik;
    }
 
    ###
    ### Frontends
    ###
 
    # Gemini
    server {
        listen                    1965;
        ssl_preread               on;
        proxy_buffer_size         16k;
 
        # pass requests directly to the corresponding Gemini server
        proxy_pass                $name;
    }

    ###
    ### Backends
    ###
 
    # personal gemlog
    upstream mycapsule {
        server              127.0.0.1:1966; # port number needs to match your capsule's listen port
    }

    # tootik instance
    upstream tootik {
        server              127.0.0.1:8965; # port number needs to match tootik's gemini listen port
    }
}

once again check that your nginx config is OK, and if so, restart it:

sudo nginx -t
sudo systemctl restart nginx

And continue to step 10 of the setup guide.

Lastly, here's what the first part of the tootik start command will look like, assuming you're using the ports in the example code above:

tootik -plain -domain tootik.example.com -addr :8080 -gemaddr :8965 -gopheraddr :70 -fingeraddr :79

... etc

* * *

If this post helped you, feel free to send me a message from your working tootik instance: patatas@tootik.patatas.ca