How to create a Gemini static site with gssg and SourceHut

Gemini [1] is a new protocol on the Internet that is positioned where HTTP is on the TCP/IP stack. It does not aim to replace it, rather coexist. In that sense, the infrastructure work is pretty much the same when trying to host a page - capsule in Geminispace.

There are a lot of hosting options to choose from, including doing it yourself. Gemini capsules don't require much in terms of resources and can be hosted on rather 'weak' computers like Raspberry Pi or similar. Many services offer Gemini hosting and one such service is SourceHut [2], specifically pages.sr.ht [3] (also visible in Geminispace [4]). Take notice that SourceHut is currently in alpha stage and hosting is free, but it will be a paid service in the future.

Once the account is made, an OAuth token is needed for interacting with the service [5]. Save it somewhere because it will only be visible once!

After the 'where' goes the 'what'. The Gemini site can be stored on the SourceHut git repository [6] or any other. You don't need to store the source on SourceHut to host it. There are a lot of tools that can help with capsule development. If you aim for a blog type capsule - gemlog - you can use gssg - Gemini static site generator [7], a static site templating tool. To test the site locally you need a server and a client. JetForce [8] is a good Gemini server with quick installation and configuration. For the client, the safe option is the command-line tool AV-98 [9], since it is made by the Gemini author. For the browser-like experience go for Lagrange, one of the best Gemini explorers out there.

Let's build a capsule by first creating an empty gssg project:

gssg -init example.com

Replace example.com with your site's name. This command will generate all the necessary files to start writing a gemlog. When you are satisfied with the contents, generate the site by running the following command:

gssg

The generated static site will be located in the public directory if the default configuration is retained.

To test the site, let's install the JetForce server. Although it is not needed it can be installed via Python virtualenv. From the project directory:

python3 -m virtualenv ./venv
source ./venv/bin/activate
pip install jetforce

To serve the generated site:

./venv/bin/jetforce --dir public/

The site is now located at localhost:1965. Use AV-98 or Lagrange to inspect it.

JetForce will listen to the directory for any changes so when any modifications are done, run `gssg` again and refresh the client to view them.

When done the site should be pushed to the SourceHut Pages so it can be available to the public.

SourceHut requires that we upload a tarball with our capsule to the Pages service. A script will pack everything the site needs. During the upload, we need to authenticate using the generated token. Lastly, a second script will do the uploading. First, let's make our token usable by the scripts by placing it in an environment variable. For example:

echo 'export gemini_bearer_token=<token>' >> ~/.bashrc
source ~/.bashrc

Now, let's pack the site. We need to put everything from the public directory to our tarball. The following script will regenerate the capsule and pack it into a tarball in a separate directory.

gssg
rm -rf out/
mkdir out/
cd public/
tar -cvz * > ../out/site.tar.gz

This can be saved in an executable script so it can be reused and/or automated.

Finally, the script that will upload/publish the site. It can also be saved in a separate executable.

curl --oauth2-bearer "$gemini_bearer_token" \
    -Fcontent=@out/site.tar.gz \
    -Fprotocol=GEMINI \
    https://pages.sr.ht/publish/username.srht.site

Substitute username in username.srht.site with your own SourceHut username. The command will return the hash value if successful and your capsule should be live at gemini://username.srht.site.

There is an easier way to upload a capsule with the hut tool [10], an all-in-one CLI tool for interacting with various SourceHut services. Upon installation, hut needs to be initialized before we can upload the capsule. All required OAuth actions are done when hut is initialized.

hut init
hut pages publish -d username.srht.site -p GEMINI site.tar.gz

Your capsule can also be served using a custom domain. Choosing and configuring the hostname is done in the same way as for HTTP sites since there is no reason for it to be any different. In your chosen DNS provider configure the sub-domain to point to the Gemini capsule. In case if you use your hosting machine configure the sub-domain to point to the IP. If you host on SourceHut you can use a CNAME record. You can even configure the same hostname for both Gemini and HTTP sites. SourceHut has a tutorial for configuring custom domains [11].

When the capsule is developed and published it would be nice to announce it to the world. This is done by submitting your capsule to various aggregation services around Geminispace.

Antena

Capcom

Gmisub Aggregate

Medusae

Spacewalk


And that is pretty much it, you are ready for Gemini. Enjoy your travel through Geminispace.

[Edited 04.01.2024.] The post has been edited with the up-to-date information about Gemini and the mentioned services.

[1] Gemini protocol

[2] SourceHut

[3] pages.sr.ht

[4] Gemini pages.sr.ht

[5] SourceHut OAuth panel

[6] git.sr.ht

[7] gssg

[8] JetForce

[9] AV-98

[10] Hut tool

[11] Custom domains on pages.sr.ht