--- title: gemini:// weight: 6 --- Here I explain how to set up a `gemini://` server, which is known as a `capsule`. If you don't know what `gemini://` is, essentially it is a text-only `https://` alternative. It allows you to browse text only feeds, and is a welcome escape from ads and javascript and bloat. {{% hint info %}} Gemini in general does not support anything except for pure text. There is no CSS, no JavaScript, nothing, except for text and sometimes images (but not in-line, you have to click them). It is considered an alternative to the web, seen as "better/superior" because it forces minimalism, however it is a bad comparison. The issue with modern web is the invasiveness, not the CSS or JS (although JS sucks); in this regard, I prefer my site being static and served over the web where I can use CSS, than gemini, where in the name of "minimalism" I have to give up expressive liberty. Be that as it may, it's nice to have options, plus the minimalism might appeal to some, or might enable a "rehab" sentiment. {{% /hint %}} ## setup The nixos configuration is a bit more difficult because of how simple `gemini` servers are. This simplicity means that we need to set up our own user, open the port (since `nginx` is a ***web*** server, it can't work with `gemini://`), and set up autosync so we don't need to sync files manually with git. ### specs There are many servers to host; the `gemini://` protocol is extremely simple, and so servers can take ~200-500 lines of code, and are *extremely* lightweight. This guide sets up `agate` since it's a service in `nixos`. We start by making a folder `gemini` and `gemini/default.nix` ```sh $ mkdir gemini && touch gemini/default.nix ``` (or use the file explorer of your choice) ### nix declaration Open `gemini/default.nix` in any text editor, and copy the following ```nix { config, pkgs, lib, ... }: { services.agate = { enable = true; hostnames = [ "" ]; addresses = [ "0.0.0.0:1965" ]; language = "en"; contentDir = "/srv/gemini"; }; networking.firewall.allowedTCPPorts = [ 1965 ]; users = { groups.agate = { }; users = { agate = { isSystemUser = true; description = "gemini user"; group = "agate"; home = "/srv/gemini"; createHome = true; shell = "${pkgs.git}/bin/git-shell"; }; }; }; systemd = { # set service services."gemini" = { description = "Update Gemini site from repo"; script = '' if [ -d /srv/gemini/.git ]; then ${pkgs.git}/bin/git -C /srv/gemini pull else ${pkgs.git}/bin/git clone https:// /srv/gemini fi ''; serviceConfig = { Type = "oneshot"; User = "agate"; }; }; timers."gemini" = { description = "Hourly Gemini-site update"; wantedBy = [ "timers.target" ]; timerConfig = { OnCalendar = "hourly"; Persistent = true; }; }; }; } ``` Then to enable it, just include it in the server config file: ```nix imports = [ # ... other services ./gemini # ... other services ]; ``` and you're done. {{% hint warning %}} Make sure to replace `` with your actual gemini repo above {{% /hint %}} Let's break the config file down. ### explanation 1) We declare the `agate` service as enabled. 2) We define the hostname for the `gemini://` network, set the address(es) to serve from, and declare the language we will be writing in. Finally we declare the content directory 3) We open port 1965 to the internet 4) We declare a group `agate` 5) We declare a user `agate`, in group `agate`, with the home folder being at `srv/gemini`, having access only to the git shell, for security. 6) We declare a `systemd` service, `gemini`, that checks if `/srv/gemini` is a git repo; if it isn't it `git clone` at a specified repository, if it is, it runs `git pull`. This service is set to run once (not continuously), and to be run by user `agate` 7) We declare a timer that runs the `gemini` service we just declared, once per hour. This automates the setup ### adding content In order to add content to your new capsule, simply go to the `content/` folder and start writing. By default `gemini://` serves the `index.gmi` at `/`, so make that file first. {{% hint info %}} `.gmi` is the markup flavour that gemini reads/serves. It is a stripped down version of markdown (`.md` files). [You can find out more about it here](https://geminiprotocol.net/docs/gemtext.gmi) {{% /hint %}} Since servers simply serve `.gmi` files, you don't need to do any update/reload or anything. It happens automatically. Personally, I use `git` to keep files synced (as in, the content folder is a git repo). ## client In order to browse `gemini://` you need a dedicated client. Use [`Lagrange`](https://gmi.skyjake.fi/lagrange/).