How to create a Gemini static site with gssg and SourceHut

Gemini 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. Some services offer hosting for free. One of such services, SourceHut, offers its users both HTTP and Gemini hosting.

Info about the service including tutorials can be found here.

Once the account is made, an OAuth token is needed for interacting with the service. Generate one here. 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 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, a static site templating tool. To test the site locally you need a server and a client. ‘JetForce’ is a good Gemini server with quick installation and configuration. For the client, the safe option is the command-line tool ‘AV-98’, 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

Replace 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:


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 so it can be available to the public. More info on how SourceHut Gemini pages support work can be seen (Gemini) here.

SourceHut requires that we upload a tarball with our capsule to their 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.

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 \

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

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 subdomain to point to the Gemini capsule. In case if you use your hosting machine configure the subdomain 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. More info on custom domain support can be seen (Gemini) here.

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 services around Geminispace including announcing it on the Gemini mailing list.

Here are the services:

And that is pretty much it, you are ready for Gemini.

Enjoy your travel through Geminispace.