Set up a server for a static Web site and a Gemini capsule
This is how I set up the site/capsule you are on right now. There are hosting providers that specialize in static sites, and there are docker containers for popular servers, but I prefer to set everything up myself, natively, and as simple as possible. Perhaps someone might find this guide useful, too.Obtain hosting
I lease a small VPS (virtual private server) from Linode - Nanode (1 shared CPU, 1 GB RAM, 25 GB storage, 1 TB transfer total per month) for $5 a monthLinode
DigitalOcean is another popular hosting provider
DigitalOcean
It is possible to host from home, even using a residential internet connection. This might be against the service agreement, but I did not find anything about it with my ISP. Although your residential IP can change, in my experience, it stayed the same for months if not years.
Create a server
Log into your hosting provider (Linode) and request a new VPS instance (Nanode). Choose an OS you prefer. Ubuntu 22.04 LTS is probably the most well-known and supported, and Debian 11 is probably the most stable. Set a strong password since it gives you root access.Your hosting provider will assign you a VPS with a unique IP address.
(I will refer to your server's IP address as your.server.ip.address)
Register a domain
If you want your site/capsule to be accessible by name (yaky.dev) and not just the IP (45.79.190.208), and to obtain proper security certificates, you need to register a domain and point it at your.server.ip.address.I purchased my domain name from Porkbun.
Porkbun
(I will refer to your registered domain as your.domain)
Log into your server
Assuming you are on a Linux machine:ssh root@your.server.ip.addressor
ssh root@your.domain
On Windows, you can use PuTTY
PuTTY for Windows
This login method will work for now. However, a good security practice would be:
- Change SSH port (bots will try to log in on port 22 all the time)
- Set up login using an SSH key (it's more convenient, too)
- Disable password-based login
- Create a user with limited privileges and disable root login altogether
NOTE: All further commands on this page are assumed to be run as root (whether you are logged in as root, or use sudo)
Update the system
Good idea to update everything before installing additional software.Assuming you are logged in as root on Debian or Ubuntu:
apt update apt upgradeIf you want a text editor with more familiar Windows-like shortcuts (Ctrl-Z to undo, Ctrl+X/C/V for clipboard), install micro:
apt install microAnd then use micro instead of nano in further commands.
Obtain certificates
Let's Encrypt is a great, popular, and free certificate authorityInstall certbot
apt install certbotTell certbot to obtain a certificate. There is an option for different web servers, but I prefer the certificate-only option, which will place the certificates in a shared directory such that they can be used by multiple services at once.
certbot certonlyChoose "1: Spin up a temporary webserver (standalone)" and follow prompts. Certificates will be saved to
/etc/letsencrypt/live/your.domain/Let's Encrypt certificates are valid for 90 days, and have to be renewed after 75 days. To renew:
certbot renew
Installing a static site server
For serving static web pages I use... nginx. Odd choice since it's primarily a reverse proxy, but it works well with other hosted services that use HTTP/HTTPS.First, install nginx:
apt install nginxThen, create a separate config for your server:
nano /etc/nginx/conf.d/your.domain.confThis is how my nginx config looks
# HTTP site # Redirect HTTP to HTTPS server { server_name your.domain; listen 80; listen [::]:80; return 301 http://$host$request_uri; } # HTTPS site server { server_name your.domain; listen 443 ssl; listen [::]:443 ssl; ssl_certificate /etc/letsencrypt/live/your.domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your.domain/privkey.pem; # Default website hosting directory is /var/www # I use /srv/www for static web pages # so Gemini content can go into /srv/gemini location / { root /srv/www; } # Logs for troubleshooting access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log error; }Now you can put your web content into /srv/www and it should be available on https://your.domain
If you run into issues, restart nginx
systemctl restart nginx
Installing a Gemini capsule server
There are many Gemini servers out there. I have used gmnisrv and Agate, both of which are simple to set up and work well.Gemini software
gmnisrv
Agate
I will use Agate as it has a few more features and has been reliable for me in the past.
Get the pre-compiled binary (thank you, Matt Brubeck), unzip it, move to the proper directory and set the executable flags
wget https://github.com/mbrubeck/agate/releases/download/v3.2.4%2Bbuild/agate.x86_64-unknown-linux-gnu.gz gunzip agate.x86_64-unknown-linux-gnu.gz mv agate.x86_64-unknown-linux-gnu /usr/local/bin/agate chmod +x /usr/local/bin/agate
To make life easier, set up Agate to run as a systemd service, which will automatically launch Agate when server starts and automatically restart it if it fails.
First, create the service:
nano /etc/systemd/system/agate.serviceDefine the service:
[Unit] Description=Agate Gemini Server After=network.target [Service] Type=simple ExecStart=agate --hostname your.domain --content /srv/gemini --certs /etc/letsencrypt/live/your.domain --lang en-US Restart=always RestartSec=3 SyslogIdentifier=agate [Install] WantedBy=multi-user.targetReload the system service definitions and enable the new service
systemctl daemon-reload systemctl enable agate systemctl start agateNow you can place your Gemini content in /srv/gemini and it should be available on gemini://your.domain
Building content
If you like Gemini markup and want to create a static web site along with your Gemini capsule, consider using my Cosmodrome tool. It takes pages in .gmi syntax, builds HTML pages and wraps them in header/footer.Cosmodrome on GitHub
Other useful tools and services
rsyncRemote sync utility to incrementally sync files between two machines. Needs to be installed on both your local machine and the server. As an a example, run this command on your local machine to sync the 'srv' directory on your local machine to the '/srv' directory on the server:
rsync -rP srv/ root@your.domain:/srv/
fail2ban
This utility check for frequent login attempts and bans offending IPs for incrementally longer periods.
If you want to see who is attempting to connect to your server, run
journalctl -eIf you rent a VPS, most likely it will be polluted with bad login attempts.
Install fail2bad on Debian and Debian-derived systems:
apt install fail2banDefault config is quite sufficient and works very well.
Check log:
tail /var/log/fail2ban.logCheck status and which IPs are currently banned:
fail2ban-client status sshdNow you have a bit more of a peace of mind.