Why I like (GitHub) gists and a short tour through ones I have created
I like sharing code and instructions. Thus, I like gists.
- What are gists?
- Why I like creating gists
- Why I like finding other people's gists
- I could or should put things elsewhere (not on GitHub)
- My gists, or "the gist-list"
- The end
What are gists?
GitHub Gists are "some text on the Internet". Usually, people put code snippets or Markdown in them, and then can share a link to anyone. It's like Pastebin but without (explicit) ads. Here's an example gist and here's the same on Pastebin.
Gists can be used for blog posts, or just to share copied text, or to host a single-branch version controlled script or code snippet. They are also often used to host data which is automatically updated from elsewhere, and can be referenced as the most up-to-date version of that data, for example by ideas like https://jsonresume.org/.
Anyone with a GitHub account can make a gist. It's a very easy way to share nicely formatted text (for example in Markdown), which is why it's the first - and most simple - thing I suggest in my "how to blog" guide.
There are good reasons you may not want to support GitHub. There are other ways to share snippets, with other gist tools, Pastebin, and other options. However, a lot of other code- or text-sharing websites seem fleeting, have ads, and do not look as nice (honourable mention here to https://wormhole.app/, a website for sharing files that looks incredible.)
Why I like creating gists
I like creating gists because they make text easy to share with two groups of people. Those two groups are...
I can share them with people
The first group of people is "other people", either specifically for someone, or just information or code I share a lot, so I like having a quick link to it. Gists I've made in this category include:
- how to create a blog? - I share this one with people whenever they muse about blogging and talk about using some complicated- or expensive-sounding tool, to try and convince them that they need not take on such an undertaking, and can just "put text on the Internet".
- Remove all CSS styles from HTML files with bash - this is a bash script I wrote and shared for CSS Naked Day 2024. There were lots of ways of removing styles for site-builders and site-backends, but none for pure HTML.
- How to use Ruby and Jekyll on Linux - when I set up Jekyll to edit a website for the first time, it was really confusing, partly because I'd never used Ruby before.
I can share them with myself in the future
The second group of people is really just one person, and they are "me in the future". Most of my usage of gists has been to remember how I did some specific thing with code or how I installed something. Writing it down in the first place help future me a lot to remember, because all I have to remember is in what context I did the thing, and then I can find out exactly how by reading the gist. Some examples of gists that have been very helpful to future- (well, now past-) me are:
- How to setup RSA keys for automatic SSH login - I found cryptography and keys confusing for a long time. Writing down what I did helped me set it up and get more confident doing so in future.
-
Plot graphs using the terminal (bash)
- I often
cat
data out to the terminal. It's nice to graph it. This is a way of doing so in the terminal, so doesn't require a UI library. - Common RSS URL extensions - is what it says on the tin
The ramblings of my existence can end up in the same place
I make a lot of random scripts. In another world, they would end up either buried in random repositories on GitHub, or buried in random folders on my computer or laptop. They would get lost.
Gists make it easy to paste a script somewhere, and then find it later, as they are all (I'm sure much to GitHub's enjoyment) in the same place.
Why I like finding other people's gists
More than just being able to share my own code, I like gists because other people have the same ideas as me!
Someone else has probably done what I want to do before
If I'd like to accomplish a small scripting task, understand
something self-contained, or find a code snippet for a specific task,
I often search for it on the web. Unfortunately, in our Lord's
year 2024, pages and pages of whatever search I make are mostly AI
garbage (here
is an article I have not read to pretend to verify my point). One help
here is independent search engines like
Marginalia Search or
Wiby. While they are fun for
exploring a more indie version of the web, I also find adding
"site:gist.github.com"
to my web search often
results in finding exactly what I want to do.
For example, here is a small list of gists from my Internet history that I've found to be useful recently (and as a by-product, an eye into my life and desires for the past several months).
- Simple XSL boilerplate for styling Atom feeds
- Git's Merge vs. Rebase vs. Squash
- CSS Train Departure board
- Change End of Line Sequence from CRLF to LF to all files in a project
- How to copy, read and write Paxton fobs and cards with an RFIDler
- Simple Morse en- & decoding for Arduino
- Getting started with the D1 mini (ESP8266)
- Globally install FFmpeg and convert video to GIF
- RevealJS cheat sheet
- Decoding Morse Code With JavaScript
- Make an issue on GitHub using API V3 and Python
- how to print Avery labels with only a .csv and a web browser
- how to make a Google Form → GitHub issue Google Apps Script
I could or should put things elsewhere (not on GitHub)
The existence of GitHub in the above has mainly been a sidenote. The main thing that excites me about gists is the collaborative nature of them. This is not something that GitHub must have control over, and indeed something that they probably shouldn't have control over.
I've been reading recently a lot about self- or community-hosted alternatives to different things like Git servers (like sourcehut) and, I use Mastodon (talking of self-hosting, I'd like to find an instance that's not mastodon.social) a lot.
I could put my snippets on my website, or something more free. But, I haven't. Yet.
My gists, or "the gist-list"
The list is long. I keep comments brief. I have categorised them as to
my whims. The code blocks show either the full gist, or - if you see
"...
" - a snippet or section of it.
BLOG POSTS
1. how to start blogging
# How to start blogging
You might not think you should blog. I think you should.
I like your thoughts! I want to be able to read them!
Here are some other reasons:
- [todepond's thoughts](https://www.todepond.com/wikiblogarden/art/blog/)
- [Max Böck's thoughts](https://mxb.dev/blog/seven-reasons-why-i-dont-write/)
At its simplest, a blog is "text on the Internet". With this in mind, my immediate reccomendation is [bear.blog](#using-bearblog), as it is super simple to set up, and you have text on the Internet, with no ads, and no nonsense.
Otherwise, here are some ways I know to share text on the Internet (listed in vague order of effort involved to set up/technical knowledge required to be learned).
## create text on the internet and link to it from elsewhere
for example on <https://gist.github.com>
...
I created this for one person who asked me "how do I start a blog". Since I made it a gist, I have shared it with many people.
2. a hat blog
I love hats
...
This is a blog about hats.
JUST DATA
DATA I MANUALLY MADE
3. my spotify wrapped 2023
# ...
[totals]
minutes = 60_724
songs = 7_309
genres = 151
artists = 4_391
[totals.longest_day]
date = "2023-7-08"
minutes = 861
# ...
I started using TOML for lots of things around the same time Spotify Wrapped came out last year. It was fun to think of a way of putting it into TOML format. TOML is fun.
4. a toki pona word list
#...
cat words.txt | awk -F'[^a-zA-Z]' 'BEGIN {delete wds} { if (length($0) > 0 && length($0) < 10) { if (!($1 in wds)) {print $1; wds[$1]} } }' > nimi-ale-pi-toki-pona.txt
#...
I wanted a toki pona word list
for something. I can't remember what, but it was probably
lipu tenpo related. I put the
command and generated list into a gist because I spent some time
tinkering with awk
to create the command, and I was
proud of it. You may spot that theme continuing on.
5. my vscode extension list
{
"name": "newprofile1",
"extensions": "[{\"identifier\":{\"id\":\"bbenoist.doxygen\",\"uuid\":\"aab644b7-f446-4774-87fc-2cce8f0d5a4f\"}},{\"identifier\":{\"id\":\"cschlosser.doxdocgen\",\"uuid\":\"da7e26d5-d57c-4742-ab47-d77fb189e195\"},\"displayName\":\"Doxygen Documentation Generator\"},{\"identifier\":{\"id\":\"davidanson.vscode-markdownlint\",\"uuid\":\"daf8b44d-8aae-4da2-80c5-1f770219f643\"},\"displayName\":\"markdownlint\"},{\"identifier\":{\"id\":\"eamodio.gitlens\",\"uuid\":\"4de763bd-505d-4978-9575-2b7696ecf94e\"},\"displayName\":\"GitLens — Git supercharged\"},{\"identifier\":{\"id\":\"esbenp.prettier-vscode\",\"uuid\":\"96fa4707-6983-4489-b7c5-d5ffdfdcce90\"},\"displayName\":\"Prettier - Code formatter\"},{\"identifier\":{\"id\":\"formulahendry.auto-rename-tag\",\"uuid\":\"6e440e71-8ed9-4f25-bb78-4b13096b8a03\"},\"displayName\":\"Auto Rename Tag\"},{\"identifier\":{\"id\":\"github.copilot\",\"uuid\":\"23c4aeee-f844-43cd-b53e-1113e483f1a6\"},\"displayName\":\"GitHub Copilot\"},{\"identifier\":{\"id\":\"github.vscode-github-actions\",\"uuid\":\"04f49bfc-8330-4eee-8237-ea938fb755ef\"},\"displayName\":\"GitHub Actions\"},{\"identifier\":{\"id\":\"github.vscode-pull-request-github\",\"uuid\":\"69ddd764-339a-4ecc-97c1-9c4ece58e36d\"},\"displayName\":\"GitHub Pull Requests and Issues\"},{\"identifier\":{\"id\":\"jock.svg\",\"uuid\":\"4ae6dc82-7981-4f10-bd81-2d72aec37f39\"},\"displayName\":\"SVG\"},{\"identifier\":{\"id\":\"leonhard-s.python-sphinx-highlight\",\"uuid\":\"a0f17d96-c9f3-4ce4-92b7-27b8c936835b\"},\"displayName\":\"Python Sphinx Highlighter\"},{\"identifier\":{\"id\":\"mhutchie.git-graph\",\"uuid\":\"438221f8-1107-4ccd-a6fe-f3b7fe0856b7\"},\"displayName\":\"Git Graph\"},{\"identifier\":{\"id\":\"ms-python.black-formatter\",\"uuid\":\"859e640c-c157-47da-8699-9080b81c8371\"},\"displayName\":\"Black Formatter\"},{\"identifier\":{\"id\":\"ms-python.pylint\",\"uuid\":\"8dc47276-5882-4c5f-903d-7eef7b9d1584\"},\"displayName\":\"Pylint\"},{\"identifier\":{\"id\":\"ms-python.python\",\"uuid\":\"f1f59ae4-9318-4f3c-a9b5-81b2eaa5f8a5\"},\"displayName\":\"Python\"},{\"identifier\":{\"id\":\"ms-python.vscode-pylance\",\"uuid\":\"364d2426-116a-433a-a5d8-a5098dc3afbd\"},\"displayName\":\"Pylance\"},{\"identifier\":{\"id\":\"ms-toolsai.jupyter\",\"uuid\":\"6c2f1801-1e7f-45b2-9b5c-7782f1e076e8\"},\"displayName\":\"Jupyter\"},{\"identifier\":{\"id\":\"ms-toolsai.jupyter-keymap\",\"uuid\":\"9f6dc8db-620c-4844-b8c5-e74914f1be27\"},\"displayName\":\"Jupyter Keymap\"},{\"identifier\":{\"id\":\"ms-toolsai.jupyter-renderers\",\"uuid\":\"b15c72f8-d5fe-421a-a4f7-27ed9f6addbf\"},\"displayName\":\"Jupyter Notebook Renderers\"},{\"identifier\":{\"id\":\"ms-toolsai.vscode-jupyter-cell-tags\",\"uuid\":\"ab4fb32a-befb-4102-adf9-1652d0cd6a5e\"},\"displayName\":\"Jupyter Cell Tags\"},{\"identifier\":{\"id\":\"ms-toolsai.vscode-jupyter-slideshow\",\"uuid\":\"e153ca70-b543-4865-b4c5-b31d34185948\"},\"displayName\":\"Jupyter Slide Show\"},{\"identifier\":{\"id\":\"ms-vscode.cpptools\",\"uuid\":\"690b692e-e8a9-493f-b802-8089d50ac1b2\"},\"displayName\":\"C/C++\"},{\"identifier\":{\"id\":\"ms-vscode.cpptools-extension-pack\",\"uuid\":\"3957b2f6-f086-49b5-a7b4-5da772123130\"},\"displayName\":\"C/C++ Extension Pack\"},{\"identifier\":{\"id\":\"ms-vscode.cpptools-themes\",\"uuid\":\"99b17261-8f6e-45f0-9ad5-a69c6f509a4f\"},\"displayName\":\"C/C++ Themes\"},{\"identifier\":{\"id\":\"ms-vscode.powershell\",\"uuid\":\"40d39ce9-c381-47a0-80c8-a6661f731eab\"},\"displayName\":\"PowerShell\"},{\"identifier\":{\"id\":\"ms-vscode.vscode-typescript-next\",\"uuid\":\"15305aca-2588-4ca0-8147-ab2c64730b82\"},\"displayName\":\"JavaScript and TypeScript Nightly\"},{\"identifier\":{\"id\":\"mushan.vscode-paste-image\",\"uuid\":\"ffaf4ec8-f001-4f02-b671-705ecf079cde\"},\"displayName\":\"Paste Image\"},{\"identifier\":{\"id\":\"naumovs.color-highlight\",\"uuid\":\"121396ad-85a1-45ec-9fd1-d95028a847f5\"},\"displayName\":\"Color Highlight\"},{\"identifier\":{\"id\":\"njpwerner.autodocstring\",\"uuid\":\"2d6fea35-f68e-461d-9b7b-5cd05be99451\"},\"displayName\":\"autoDocstring - Python Docstring Generator\"},{\"identifier\":{\"id\":\"rangav.vscode-thunder-client\",\"uuid\":\"2fd56207-78ef-49d4-95d2-9b801eee4dbf\"},\"displayName\":\"Thunder Client\"},{\"identifier\":{\"id\":\"ritwickdey.liveserver\",\"uuid\":\"b63c44fd-0457-4696-99e9-dbfdf70d77de\"},\"displayName\":\"Live Server\"},{\"identifier\":{\"id\":\"tumido.cron-explained\",\"uuid\":\"6ee451cb-7b81-4520-9eb4-059db43a1431\"},\"displayName\":\"Cron Explained\"},{\"identifier\":{\"id\":\"usernamehw.errorlens\",\"uuid\":\"9d8c32ab-354c-4daf-a9bf-20b633734435\"},\"displayName\":\"Error Lens\"},{\"identifier\":{\"id\":\"valentjn.vscode-ltex\",\"uuid\":\"840e9c85-0e99-42ce-aa62-81088245e699\"},\"displayName\":\"LTeX – LanguageTool grammar/spell checking\"},{\"identifier\":{\"id\":\"yzhang.markdown-all-in-one\",\"uuid\":\"98790d67-10fa-497c-9113-f6c7489207b2\"},\"displayName\":\"Markdown All in One\"}]"
}
When I originally made this, it was human-readable: you could see a nice, multi-line list of my VSCode extensions. They have since changed how the export/import works, so now it looks very ugly. I no longer find this useful.
DATA THAT'S AUTOMATICALLY UPDATED
6. my json resume
#...
"references": [
{
"reference": "\"This is very neat thank you for this contribution.\"",
"name": " Alexandre Lavigne, open-source pull request.",
"url": "https://github.com/burnash/gspread/pull/1187#pullrequestreview-1451621771"
},
{
"reference": "\"Thanks @strib and. @alifeee - very good team work!!!!\"",
"name": "Romano Silva, open-source pull request.",
"url": "https://github.com/keyteki/keyteki/pull/3222#issuecomment-1589734669"
},
#...
This is auto-updated by my CV repository. I used to use json-resume a bit more, but I stopped doing the themes how they did it and made it myself. I still use the schema, though, and still update this gist, so I can view my CV in many different styles. Neat!
7. my web bookmarks
{
"last_modified": "2024-03-25T00:44:15.551843Z",
"bookmarks": {
"TOP 10 personal websites/blogs": [
{
"title": "Tom Forth's Homepage",
"url": "https://www.tomforth.co.uk/",
"date_added": "2023-05-29T18:23:46.689000Z",
"last_modified": "2023-11-12T22:19:05.160000Z"
},
{
"title": "nonnullish",
"url": "https://nonnullish.pages.dev/",
"date_added": "2023-09-12T15:53:49.290000Z",
"last_modified": "2023-11-12T22:19:28.376000Z"
},
...
After making my CV automatically push to a gist, it was easy to do similar when I was making my Firefox bookmark exporter. I don't really use this gist, but I guess having the data in machine-readable format is nice. Although alifeee.co.uk/bookmarks probably already fills that role.
HOW-TOS
THINGS I WANTED TO DO MULTIPLE TIMES
Most of these gists exist because I spent a while figuring out how to do a process, and I thought that I would want to repeat the process in the future.
8. how to generate and host a Factorio map
...
## To create maps
With:
1. saves from Steam version of Factorio in `C:\Users\alifeee\AppData\Roaming\Factorio\saves`
2. saves moved from here to standalone Factorio install in `D:\Factorio\Factorio_1.1.100\saves`
3. `FactorioMaps` mod installed in `D:\Factorio\Factorio_1.1.100\mods\L0laapk3_FactorioMaps_4.4.0`
Assuming the saves are named `"multplayer 1"`, `"multplayer 2"`, etc...
Run the following to generate the map frontend
```bash
find . -regex '.*mult.*' | awk '{printf "\"%s\" ", substr($0, 3, length-6)} END {print ""}'
# copy output
# paste from above
py auto.py --dayonly multplayer "multplayer start" "multplayer 1" "multplayer 2" ...
```
...
why did I make it?
I played a big multiplayer Factorio world once a week for ten weeks,
and I used
FactorioMaps
to create an interactive map of the save after every week. You can
(maybe) see the final map on
https://server.alifeee.net/factorio/.
who is it for?
Myself. It took a few hours to set this up the first time, and I was doing it every week, so making a gist helped me do it repeatedly and more mindlessly.
have I come back to it?
Every week for ten weeks when I was generating the maps often.
9. how to download data from Toggl's api
...
KEYS="${TOGGL_KEYS:-.id, .workspace_id, .project_id, .task_id, .billable, .start, .stop, .duration, .description, .duronly, .at, .server_deleted_at, .user_id, .uid, .wid, .pid}"
# print CSV headers
echo $KEYS | awk -F', ' '{for (i=1; i<NF; i++) {printf "%s,", substr($i, 2)}} END {printf "\n"}'
# print CSV content (parse JSON with jq)
cat $1 | jq -r '.[] | ['"${KEYS}"'] | @csv'
I track time using https://toggl.com/. I do not pay for it, so they do not keep my data past 3 months. So, every month I download the month's data. Rather than remembering which buttons to press on the UI, I wrote a script that I can run. I thought it might be nice to accidentally come across it if you were a netizen.
10. reusable ffmpeg commands
# FFmpeg Commands
## Turn mp4 into gif
Used [here](https://github.com/sheffieldhackspace/train-signs). From [here](https://superuser.com/a/1695537).
```bash
ffmpeg -y -i input.mp4 -filter_complex "fps=5,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen=max_colors=32[p];[s1][p]paletteuse=dither=bayer" output.gif
```
I thought I'd use this one more, but I haven't. I made it because I love writing an FFmpeg command for a repeatable task, as it's so easy to do something again the same way later on. But, I haven't really been doing much video/audio stuff recently.
11. how to make bar charts in bash
...
# > ./bar.sh 25 100 12
# ███░░░░░░░░░
awk -v prog=$1 -v TOTAL=$2 -v TOTSEG=$3 'BEGIN {
frac = prog / TOTAL;
segs = frac * TOTSEG;
segs_int = int(sprintf("%.0f", segs));
for (s=0; s<segs_int; s++) {
printf "%s", "█";
}
for (s=0; s<(TOTSEG - segs_int); s++) {
printf "%s", "░";
}
}'
I love bash, I love awk, and I love statistics. This combines them wonderfully. I use this vaguely regularly when I want to visually compare numbers, such as for my Advent of Code statistics, or comparing magazine release date differences.
12. how to make graphs in bash
...
Plot graphs using the terminal. E.g.,
> cat sensor.txt | awk -F ':| *' '{print $2}' | eplot -d -t CO2 2> /dev/null
4000 +-------------------------------------------------------------------+
| + +.+.+ + + + + |
| : .+ CO2 +.....+ |
| + .+ |
3500 |-+ : .+ +-|
| : .+ |
| + .+ |
| : + |
3000 |-+ : + +-|
| : .+ |
| : .+.+ |
| : .+ |
2500 |-+ : .+ +-|
| + .+.+ |
| + .+.+ |
| + +.+.+ |
2000 |-+ + .+.+.+.+ +-|
| + |
| + |
|.+.+.+ + + + + + + |
1500 +-------------------------------------------------------------------+
0 5 10 15 20 25 30 35
...
> cat sensor.txt | awk -F ':| *' '{print $2}' | eplot -d -t CO2 2> /dev/null
...
As I said already, I love statistics. I made this when I was setting up a CO2 monitor, to sanity check the results I was getting. I had it set up to just send numbers through serial, so I found out how to graph it to be able to better compare those numbers to one another.
I wanted to do it in bash, so I could do it interactively, and watch the graph change in real time. If I wanted a pretty graph, I'd use Matplotlib.
THINGS THAT OTHER PEOPLE COULD WANT TO DO
These are things that I did once, or do repeatedly and remember how to do. But, I put them into gists so that I could share with people how I do common things, or so people with very specific google searches might stumble across something useful.
13. a script to remove all styles from an html file
...
# to change lots of files, use `find` and `xargs`
# e.g., find all files ending with ".html" and replace them with the output of this script
# find . -name "*.html" -print0 | xargs -0 -i bash -c './scripts/naked.sh "{}" > "{}.temp" && mv "{}.temp" "{}"'
cat "$1" | perl -0777pe 's|<link[^>]*rel="stylesheet"[^>]*/>||gms' | perl -0777pe 's|<style>.*?</style>||gms' | perl -0777pe 's|style="[^"]*"||gms'
I made this to make it easy for me to participate in CSS Naked Day 2024. I shared it so that anyone else could do the same. There were many ways of removing styles on the homepage, but they were all for PHP, or Django, or Perl, or ... etc. Nothing for "just HTML", so I added it.
14. common RSS extensions
# Common RSS URL extensions
I like blogs. I like RSS feeds. Often, blogs don't have an RSS feed link. Often, these blogs *do* have an RSS feed, thanks to whatever site generator they use.
Thus, I like to try and find the hidden feed. These are the URLs I usually put on the URL to try and find the feed.
For example, [`blog.alifeee.co.uk`](https://blog.alifeee.co.uk/) -> [`blog.alifeee.co.uk/feed.xml`](https://blog.alifeee.co.uk/feed.xml)
```text
/feed
/feed.xml
/rss
/rss.xml
/atom
/atom.xml
/index.xml
./feed
./feed.xml
./rss
./rss.xml
./atom
./atom.xml
./index.xml
```
As the gist says, I like RSS. You should use it to keep up with your favourite blogs. Whenever I was on a blog and I couldn't find a link to an RSS feed, I would find myself trying a random combination of the above. I wrote it down so that now I can be more systematic about it, and so that now I can keep up to date with my favourite random personal websites!
15. a script to combine Squarespace RSS feeeds
...
# fetch the file
rss=$(curl -s "${baseurl}&${querystring}" | tr -d '\n')
# remove header with "<\?xml.*?<\/description>"
if [ $i -ne 1 ]; then
rss=$(echo $rss | perl -pe 's/<\?xml.*?<\/description>//g')
fi
# remove footer
if [ $i -ne $months_ahead ]; then
rss=$(echo $rss | sed 's/<\/channel><\/rss>//g')
fi
all_rss="$all_rss$rss"
...
More RSS love. This was made in frustration at Squarespace only offering an RSS feed for each month of the calendar, and no "all" option I could see. Thus, I made a script to combine RSS feeds of the next few months so that I could stay up to date. I thought it might be useful if someone encountered the same issue with a different Squarespace site.
16. a script to convert font files to css styles
...
name_without_spaces=$(echo $name | tr '[:upper:]' '[:lower:]' | tr ' ' '-')
echo '@font-face {
font-family: "'$name'";
src: url("'$1'") format('woff');
}
.font--'$name_without_spaces' {
font-family: "'$name'" !important;
}
'
For my font-workshop and font-talk, I wanted to make a couple of CSS rules for around 100 or more fonts. This was a fun challenge to do using bash, and I ended up with a nice script. It's another one that I only put online because it was easy to do so, and again so that if someone came at Google with a very niche ask, they might find help here.
17. a script to convert gpl files to css styles
...
cat $1 | awk -F ' ' '
BEGIN {
printf ":root {\n"
} /^([0-9]{1,3})\s+([0-9]{1,3})\s+([0-9]{1,3})\s+(.*)$/ {
colourname = ""
for (i=4;i<=NF;i++) {
colourname = colourname "-" $i
}
printf " --colour%s: #%02x%02x%02x;\n", colourname, $1, $2, $3
} END {
printf "}\n"
}'
Similar to the above, this is a script for converting a gimp colour palette to CSS styles. I used it for turning a colour palette for typesetting lipu tenpo into CSS for the lipu tenpo website. Again, who's to say, but it's nice to imagine that someone could be attempting this specific thing in future and stumble across this gist.
HOW TO SET UP THINGS ON A LINUX SERVER
Having and doing things on a Linux server is an entire world in itself. When I started doing it, lots was confusing. Lots is still confusing. Whenever I do something describable, I try and write it down so that I can build upon my knowledge, rather than having to re-find-out how to do it every time I do something.
I have come back to most of these quite a lot because they contain a lot of POSIX/bash/shell commands that I remember using, but have forgotten how to use, or what they were called.
18. how to set up rsa encryption keys
...
### Add key to `~/.ssh/authorised_keys`
```bash
cat .ssh/alifeeePC.pub >> .ssh/authorized_keys
```
### Add host and key to SSH config file
Doing this means I can type `ssh server` and it basically runs the [above command](#connect-using-key-vanilla)
Add the following to `~/.ssh/config`
```text
Host server
HostName server.alifeee.net
User root
IdentityFile ~/.ssh/alifeeePC
```
...
I made this gist because I really didn't understand what RSA keys or SSH keys were, or how they worked, so I spent a while figuring out my understanding of it, and I wrote it down. I came back to it a lot over time to remind myself how to generate keys, where to put them for SSH, and how to edit my SSH config.
19. how to set up nginx
...
## Config examples
### subdomain redirect
This redirects `webring.alifeee.co.uk` to `localhost:8080`. Without this, you would have to access the endpoint with `webring.alifeee.co.uk:8080`, which looks ugly :(
```nginx
server {
listen 80;
server_name webring.alifeee.co.uk;
location / {
proxy_pass http://localhost:8080;
}
}
```
### (default) static site
This serves static files from `/var/www/server_homepage`
```nginx
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/server_homepage;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
```
### Folder alias
This redirects requests to `https://server.alifeee.net/factorio` to `/var/www/factorio` instead of `/var/www/server_homepage/factorio`
```nginx
location /factorio {
alias /var/www/factorio_map/;
try_files $uri $uri/ =404;
}
```
...
I've come back to this one a lot. Installing nginx was one of
the first services I installed on my server, so it was useful
whenever I installed new services to remind myself of the commands
for running them. It was also useful for some more basic concepts
like scp
.
Sharing files as a web server is one of the more exciting things to do on a server, and there are many ways to do it, which are each subtly different. For example, the quote above shows three different ways of setting up a server and location for slightly different use cases.
The gist also serves as a backup for my nginx config, in case I lose access to my server. I have spent a lot of time in that file editing it to do exactly what I want. It should probably be multiple "sites-enabled" files, as people usually do web server setups, but this works for me at the moment, so that's how it will be. ;)
20. how to transfer folders over scp
# Transfer Folders over SCP
With tar + zip
## Commands
### zip + tar
```bash
tar -cvzf <nameoftar>.tar.gz <nameoffolder>
```
### Transfer over scp
```bash
scp ./<nameoftar>.tar.gz <user>@<server>:<filelocation>
```
### untar + unzip (on remote)
```bash
tar -xvzf <nameoftar>.tar.gz
```
I made this because I was struggling with using FTP or other ways of
moving files around. Once I worked it out, scp
was
useful. I have since found out that you can use
scp
recursively, so there's no real need to use
tar
to tar zip the folder before sending it, you can
just use scp *
. But, learning scp
and
writing this gist means that I got an appreciation for the syntax of
both scp
and tar
, which I've used a
few times since then.
21. how to run a program as a service with systemd
...
## An example service file
For an application stored in `/root/go/webring-go/serve` that serves files over HTTP, an example service file is
```service
[Unit]
Description=Webring using Go and TOML
After=network.target
[Service]
ExecStart=/root/go/webring-go/serve
WorkingDirectory=/root/go/webring-go
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
```
## How to enable
If the service is named `webring.service`
```bash
cp webring.service /etc/systemd/system/webring.service
sudo systemctl enable webring.service
sudo systemctl start webring.service
sudo systemctl status webring.service
```
...
This was a very useful gist for me to write. As it says in the gist preamble, I was running bots and programs (daemons) on my server in a very volatile way, so that I couldn't restart the server, or I would have to go and manually start 4 or 5 different programs.
Working out how to use systemd
with very simple use
cases felt very handy, so I wrote it up because it was difficult for
me to find good information on how to do it.
22. how to set up a mumble server
# Mumble Server setup
## Setup
This describes commands to set up Mumble's server (Murmur) on Ubuntu Linux.
### Install
```bash
sudo apt-get install mumble-server
```
### Configure
```bash
sudo dpkg-reconfigure mumble-server
sudo nano /etc/mumble-server.ini
```
Edit `welcometext`, `serverpassword`, `registerName`.
```bash
sudo service mumble-server restart
```
...
I mainly wrote this one because it seemed like a lot of configuration when I was setting up the Mumble Server, so I wanted to be able to do it again with the same configuration.
I was also a little worried that when I first used Mumble (to play the Factorio game), I might have to do some "live" restarting or checking of the server if it broke, and writing down how to do that would make it a lot easier and less stressful.
23. how to install ruby and jekyll on linux
### Using Ruby on Linux
#### Install Ruby + Gems
```bash
sudo apt-get install ruby-full
gem install bundler
bundle config set --local path 'vendor/bundle'
bundle install
```
#### Serve hot-reloading website
```bash
bundle exec jekyll serve --watch
```
For whatever reason, I struggled to install Ruby & Jekyll locally on my computer. I imagine the struggle is similar to installing Python and pip, and not really understanding how to use them "properly". I also wrote it down because I wanted to install it both on my PC and my laptop.
24. how to set up ftp on linux
# How to set up FTP on Ubuntu
Mainly following <https://gist.github.com/CloudLinuxDeveloper/ec801e51c0a3917555c01d8b064e7f9a>
```bash
sudo apt update && sudo apt install vsftpd
sudo service vsftpd status
sudo ufw allow 20/tcp
sudo ufw allow 21/tcp
sudo ufw allow 40000:50000/tcp
sudo ufw allow 990/tcp
sudo adduser weeknotes
sudo nano /etc/ssh/sshd_config
> DenyUsers weeknotes
sudo service sshd restart
sudo mkdir /home/weeknotes/ftp
sudo chown nobody:nogroup /home/weeknotes/ftp
sudo chmod a-w /home/weeknotes/ftp
sudo mkdir /home/weeknotes/ftp/files
sudo chown weeknotes:weeknotes /home/weeknotes/ftp/files
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.original
sudo nano /etc/vsftpd.conf
> write_enable=YES
> chroot_local_user=YES
> chroot_local_user=YES
> force_dot_files=YES
> pasv_min_port=40000
> pasv_max_port=50000
> user_sub_token=$USER
> local_root=/home/$USER/ftp
sudo service vsftpd restart
```
This is not really a gist I have come back to, nor one that I used properly. After I set up FTP, I decided I didn't want to use it, so I un-set it up. But, if I ever want it again, I can follow my own instructions, which maybe contain parts of my own personality as commands.
The end
I hope you enjoyed a skim through the gist-list. Some are boring, but that's because I didn't hold out, and included every gist, so you could have a fair judgement of how many are actually useful and how many end up not being.
Maybe next time you write a small script, or spend a couple of hours figuring out how to do something, you'd consider writing it down and putting it somewhere?...
Comments
Email me → alifeee@alifeee.net :)
Message me on any social media → https://linktr.ee/alifeee :)