burrow: Static Gopherhole Generator
_ _
| |__ _ _ _ _ _ _ ___ __ __ __ (_)
| '_ \ | || | | '_| | '_| / _ \ \ V V / _
|_.__/ \_,_| |_| |_| \___/ \_/\_/ (_)
___ _ _ _
/ __| | |_ __ _ | |_ (_) __
\__ \ | _| / _` | | _| | | / _|
|___/ \__| \__,_| \__| |_| \__|
___ _ _ _
/ __| ___ _ __ | |_ ___ _ _ | |_ ___ | | ___
| (_ | / _ \ | '_ \ | ' \ / -_) | '_| | ' \ / _ \ | | / -_)
\___| \___/ | .__/ |_||_| \___| |_| |_||_| \___/ |_| \___|
|_|
___ _
/ __| ___ _ _ ___ _ _ __ _ | |_ ___ _ _
| (_ | / -_) | ' \ / -_) | '_| / _` | | _| / _ \ | '_|
\___| \___| |_||_| \___| |_| \__,_| \__| \___/ |_|
╔─*──*──*──*──*──*──*──*──*──*──*──*──*──*──*──*─╗
║1 ........................................ 1║
║2* ........................................ *2║
║3 ........................................ 3║
║1 ...........Posted: 2024-03-10........... 1║
║2* Tags: gopher haskell showcase my_warez . *2║
║3 ........................................ 3║
║1 ........................................ 1║
╚────────────────────────────────────────────────╝
You may have heard of *static site generators*. You may even have heard of the
Gopher Protocol[1]. But have you heard of a *static gopherhole generator?*
burrow[2] creates gopherholes for you. It has a lot of features to do so. It's
so good, in my opinion, I'm considering expanding the output to websites as
well, or at least abstracting-out some of its library components.
Here's my gopherhole, which I built with burrow:
* Visit in gopherspace: gopher://gopher.someodd.zip:7071/
* Try visiting using my Gopher Protocol client, "waffle"[3]
* `sudo apt-get install gopher && gopher -p "/" gopher.someodd.zip 7071`
* Visit using the Floodgap Gopher-HTTP gateway[4] (although, I'm not so sure
about
its UTF-8 support)
Some highlights:
* Particularly proud of the code quality here, written mostly before AI became a
big part of my workflow. Some examples:
* Some descriptive FrontMatter error handling[5]
* Getting abstract with the usage of `MultiParamTypeClasses`,
`FunctionalDependencies`, `AllowAmiguousTypes`, and `FlexibleInstances`[6]
* I got to work with the author (@sternenseemann[7]) of my favorite Gopher
Protocol server daemon (spacecookie[8]), who I believe I have worked with on
other matters as well.
* I went out-of-my-way to have fantastic error handling in some respects
* Had some fun with some very abstract features of Haskell, to me
The example:
## Serving/Docker Setup
I made a Docker setup for spacecookie[9]. It was nice working with the author of
Spacecookie on this project, and I think others!
I even made a setup/branch specific to burrow[10], which makes it easy to simply
push a commit and the server rebuilds the gopherhole for you!.
I think these setups were made originally around serving a Gopherhole via Tor so
I'll suggest some modifications.
### Using the burrow setup (no Tor)
I had to tweak the Docker spacecookie burrow setup[11] a bit to get it to play
nice.
Using nonstandard ports.
Firewall for the gopherhole service:
```
sudo ufw allow 7071/tcp comment 'gopherhole (docker)'
```
Firewall for git/ssh, my rule makes is for only accessing via local network or
my VPN:
```
sudo ufw allow from 192.168.1.0/24 to any port 2222 proto tcp comment 'gopherhole (docker) git ssh'
sudo ufw allow from 10.1.0.0/24 to any port 2222 proto tcp comment 'gopherhole (docker) git ssh'
```
also making it listen ssh different port! -- only allow from localnet ufw. had
to edit docker expose, i also had to add this to dockerfile, modifying so this
section looks like this (the sed command)
```
RUN apt-get install -y openssh-server
RUN sed -i '/^#Port 22/c\Port 2222' /etc/ssh/sshd_config
RUN service ssh start
```
This is in my `~/.ssh/config` (`192.168.1.100` is the IP of my server, although
I realize now I want to modify this now to also specify the IP on the VPN too,
if possible):
```
Host gopherhole
HostName 192.168.1.100
Port 2222
User git
IdentityFile ~/.ssh/id_rsa_hgopher
```
I modified `make run` (`Makefile`):
```
docker run -d --restart=always --net servicenet --hostname=spacecookie -p 2222:2222 -p 7071:7071 --ip=172.18.0.68 spacecookie
```
Port forward on router, then it should all work.
Try to `git push` to the server IP hosting the docker container and also make
sure you port forward and you should be able to access...
### tweaks i made due to port conflicts and stuff?
```
+++ b/Dockerfile
@@ -44,11 +44,12 @@ RUN wget -O /tmp/burrow.deb https://github.com/someodd/burrow/releases/download/
RUN apt install /tmp/burrow.deb
RUN apt-get install -y openssh-server
+RUN sed -i '/^#Port 22/c\Port 2222' /etc/ssh/sshd_config
RUN service ssh start
-EXPOSE 70
-EXPOSE 22
+EXPOSE 7071
+EXPOSE 2222
+++ b/Makefile
@@ -12,7 +12,7 @@ build:
docker build -t spacecookie .
run:
- docker run -d --restart=always --net servicenet --hostname=spacecookie --ip=172.18.0.68 spacecookie
+ docker run -d --restart=always --net servicenet --hostname=spacecookie -p 2222:2222 -p 7071:7071 --ip=172.18.0.68 spacecookie
test:
echo "$(running_id)"
+++ b/spacecookie.json
@@ -1,8 +1,8 @@
{
- "hostname" : "localhost",
+ "hostname" : "someodd.duckdns.org",
"listen" : {
"addr" : "::",
- "port" : 70
+ "port" : 7071
},
```
## Example image
This is an example of a gopherhole generated with *burrow,* as rendered by my
software waffle[12]:
!burrow-generated gopherhole in waffle =>
/assets/showcase/burrow/burrow-columnate-fonts-justify-example.png
The burrow repository[13] (hopefully) has an example of a gopherhole that can be
built with `burrow`.
## Example fonts
Here are some fonts that I and others have made for `burrow`:
* Fonts I made for burrow, as part of the repo[14]
## Story of development
I think I started developing this piece of software before AI started being
something I leaned heavily on in my development process. I think the code is
very clean, well organized/architectured, and well researched.
### Using abstract and advanced Haskell features
In this project I feel like I used very abstract and advanced Haskell features.
Here I will talk about the language extensions and documentation practices...
How I made my own markdown parser?
### Markdown parsing
### Coming back to this project after a while
* Needed to pin versions
* Trying to get nix working
* GHC versions...
* cabal freeze, lock.nix
* Removed depend marked as broken by nixpkgs, with code generated by ai
## Footnotes
[1]: Gopher Protocol: https://en.wikipedia.org/wiki/Gopher_(protocol)
[2]: burrow: https://github.com/someodd/burrow
[3]: my Gopher Protocol client, "waffle": /showcase/waffle
[4]: Visit using the Floodgap Gopher-HTTP gateway: https://gopher.floodgap.com/gopher/gw?a=gopher%3A%2F%2Fgopher.someodd.zip%3A7071%2F
[5]: Some descriptive FrontMatter error handling: https://github.com/someodd/burrow/blob/dfecdace53504dfadda34f7d5717d14a763f373b/src/FrontMatter.hs
[6]: Getting abstract with the usage of `MultiParamTypeClasses`, `FunctionalDependencies`, `AllowAmiguousTypes`, and `FlexibleInstances`: https://github.com/someodd/burrow/blob/dfecdace53504dfadda34f7d5717d14a763f373b/src/Phlog.hs
[7]: @sternenseemann: https://github.com/sternenseemann
[8]: spacecookie: https://github.com/sternenseemann/spacecookie
[9]: a Docker setup for spacecookie: https://github.com/someodd/docker-spacecookie
[10]: a setup/branch specific to burrow: https://github.com/someodd/docker-spacecookie/tree/feature/git-server-burrow
[11]: Docker spacecookie burrow setup: https://github.com/someodd/docker-spacecookie/tree/feature/git-server-burrow
[12]: waffle: /showcase/waffle
[13]: The burrow repository: https://github.com/someodd/burrow
[14]: Fonts I made for burrow, as part of the repo: https://github.com/someodd/burrow/tree/master/data/fonts