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