Happy new year! This is going to be a good one.

Every once in a while I fall into the delusion that I am a somewhat interesting person, and spin up a new social networking account.

Having a kid with asthma makes you appreciate just a little bit why Eddie Kaspbrak’s mother was so overbearing.

Installing GoToSocial on Coolify

Following up to my earlier post about the fediverse, I discovered GoToSocial. Compared to Mastodon which required a fair amount of server overhead (more than I could justify for just playing around online), GoToSocial is very lightweight: 1 CPU, 1GB memory, and 15GB-20GB of storage space for the first year or so. Sold!

This would let me set up my own single-user server, which solves all of my misgivings about Mastodon.

Disclaimer:
I am a total novice at all things server-related! I am probably at least a little bit wrong about some of the things I write here. Please take my experience with a grain of salt, and correct me if you can.

I have a VPS with Coolify to manage the multiple apps I have running, and all things considered it makes things very easy.
I used a docker-compose file to deploy GoToSocial, and their example file was almost perfect as-is.

Port settings

Coolify acts as a reverse proxy, so I used that part of the configuration:

services:
  gotosocial:
  ...
    ports:
      # - "443:8080"
      ## For letsencrypt:
      #- "80:80"
      ## For reverse proxy setups:
      - "127.0.0.1:8002:8080"

8002 was just an open port that I chose, and Coolify is smart enough to use that port to route traffic from my GoToSocial domain.

File permissions

Robb Knight’s blog post showed me how to fix the sqlite database being unable to load because of a permissions issue. I had a similar issue with the Wazero compilation cache directory not being created, but I ended up just commenting that line out because it works without.

Shooting myself in the foot

I knew I had to mount a volume to make the database persist across redeploys and not be wiped fresh every time. Coolify’s documentation made it very clear,

The base directory inside the container is /app. So if you need to store your files under storage directory, you need to define /app/storage as the destination path.

So, I changed the settings to make sure that things were stored under /app

services:
  gotosocial:
    ...
    environment:
      ...
      GTS_DB_ADDRESS: /app/storage/sqlite.db
    volumes:
      - ~/gotosocial/data:/app/storage

Which worked, except!
I hadn’t realized that media storage also defaulted to the same (first) /gotosocial/storage directory. Since this directory was no longer being bound, it was wiped clean after every redeploy. Remote media was fine because it could be fetched again, but images I uploaded were lost.

I poked around in the terminal and saw that both /app/storage and /gotosocial/storage were being created and used with no issues, so I just switched the database address back to the default /gotosocial/storage… and everything worked as expected.

So, I don’t quite understand what the Coolify docs were trying to tell me.

End

Things seem to be working fine now, and I’m using mostly Semaphore to interact with the instance.
You can follow me here!

Adguard was preventing sites from loading in Safari sometimes

For some reason, some sites would not load in Safari. Certain assets, often hosted on a CDN but not always, would hang forever and keep the page from loading. Other browsers worked, curl worked, so it didn’t seem like a DNS issue. It was driving me crazy.

I think I finally caught the culprit: Adguard’s network filtering.

Adguard gives you the option to filter all of your internet traffic for various apps on your computer. By default, it does so through a “Network Extension” that registers a local VPN to filter all traffic.

For some reason, this was tripping up just Safari and stopping certain assets from loading. An alternative mode called “Automatic Proxy” is available to avoid conflicts with other VPN applications and such, and switching to this mode seems to have fixed the problem for me. Good!

See Adguard’s documentation here.

Litestack: All your data infrastructure

From the repository:

Litestack is a Ruby gem that provides both Ruby and Ruby on Rails applications an all-in-one solution for web application data infrastructure. It exploits the power and embeddedness of SQLite to deliver a full-fledged SQL database, a fast cache , a robust job queue, a reliable message broker, a full text search engine and a metrics platform all in a single package.

I’ve been learning Python for my small projects recently, but for something that wants a full stack I’ll definitely be checking this out.

I want to love Mastodon...

But it’s just not doing it for me.

Update 2024/12/27
I have set up my own instance of GoToSocial, and have written about it here. This seems like the best solution for me.

The main selling point of Mastodon is its federation I think, and I tend to agree with Tim Bray’s points that some kind of decentralized, protocol-based network for social exchange is what will endure. Having one service run by one group of people is brittle. Having many services run by many groups of people is resilient.

People explain that Mastodon and the Fediverse are similar to email. You can make an account with any provider, and it lets you speak to anyone on a different service. You can have a Gmail account and still send emails to a Fastmail account.

But for me, the analogy is not apt, mainly because of server rules and moderation.

Moderation of Mastodon

Each Mastodon server has its own set of rules and moderation guidelines. There are things you can’t say on certain servers, and servers can even blacklist other servers if they notice a strong trend of bad activity. Let’s be clear, I prefer keeping angry Nazis away. But it’s not the same as an email provider.

Imagine if Gmail didn’t allow you to send emails that made derogatory comments. Or emails that contained copyrighted images. Or if Fastmail stopped allowing you to send emails to Hotmail users because there was too much spam coming from it.

The point is not whether those are good or bad decisions, but that it does matter who you sign up with.

Who do I want moderating my experience?

When comparing Bluesky to Mastodon, one point brought up often is that it is venture-backed. The service needs to generate money, and in the long run, for-profit services will go to shit. This is probably true.

Honestly, I’m OK with staying while it’s good and getting out when it gets bad. That’s what I’ve done with Facebook and Twitter and Instagram and whatever else. That’s life online.

The more pressing issue in the short term is who I want to be running the service I sign up for. The unpaid volunteers of a particular Mastodon instance who want to keep the service good because they care? Or paid employees of a publically scrutinized company who want to keep the service good for a strong salary?

Am I crazy to say that the latter feels more stable and reliable?

Passion projects fizzle out when the passion dies, but money keeps the wheels turning. Bluesky’s mission now is agreeable to me, so I’ll stay on their service and feel peace of mind. As the service strays from this ideal in the future, as it most likely will, I’ll look around for whatever better option is available then.

The actual best solution

If I want freedom and permanence together, the best solution is probably to run my own Mastodon server. And that does seem like the answer I’m looking for. I’m in control of my data and can do with it as I please. I can connect to other Mastodon instances and participate in the larger community. And while the small details may change, I can bet on a federated future that continues to let me maintain a node that plugs into a larger network.

The only problem, and it’s kind of a big one, is the price and the hassle. Setting up a Mastodon server is still kind of a lot of work, and the cost of upkeep is significant. I hope that entry costs will continue to go down because that is the future that I am most excited to see.

Comments are back

This site has gone through many forms, and comments have come and gone. Now they are back, made possible by commento++. Commento was popular and on my radar for a while, but the original repository has been dead for a while. Commento++ is a fork that has been dead for… a little bit less of a while. But it has a few improvements from the original, and as long as it’s stable I don’t care so much.

But the better question is not how, but why have comments? (Or why not to?)

I didn’t have comments for a long time, because I decided that this blog was a place where I didn’t care what other people said. It was a space for me to write and save things, just for myself. That’s fine, too.

But I’ve been thinking a lot about what it means for me to write on this blog, espeically in the context of generative AI getting so good at replacing mediocre writers. Paul Graham’s post Writes and Write-Nots resonated with me. The ability to write well is equivalent to the ability to think well. By continuing to write, on my own, I hope I can keep up my ability to think well.

And in many contexts, writing is also the ability to turn your thoughts into words and share them with other people. It is the ability to communicate. Writing in a personal journal might be good for my thinking, but I want to focus on my communication too. So, comments.

I’ll write articles on this blog with the intent of communciating my thoughts to my readers, few as they are. And since communication is a two-way street, I wanted some kind of commenting system to get feedback and discourse. So I hope you find my posts here engaging, and would be very happy if you left me a comment, too.

Installing Python3 modules on Macs in 2024

When trying to install python modules on a new Mac, I kept getting thwarted by this error:

error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try brew install
    xyz, where xyz is the package you are trying to
    install.
    
    If you wish to install a non-brew-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip.
    
    If you wish to install a non-brew packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.

It seems like installing modules into a virtual environment is the way to go, which is what I had been doing for individual applications, but I wanted to be able to run this script from Alred workflows.

Create a virtualenv in a central place that is easy to access

python3 -m venv ~/.virtualenvs/python3
source ~/.virtualenvs/python3/bin/activate
pip install xyz

Use this virtualenv whenever I run the script

By specifying the python executable inside the virtualenv we created, we can be sure that it can access the modules we installed there.

~/.virtualenvs/python3/bin/python /path/to/my/script.py "{query}"

Bonus

Add an alias to my ~/.zshrc so that can just type vpython /path/to/my/script.py

alias vpython='~/.virtualenvs/python3/bin/python'

Web Links - November 2022

A.N. Lucas's 88x31 button Collection
A collection of classic web banner images.
How to Run Stable Diffusion on Your PC to Generate AI Images
For personal reference.
If You Can't Answer These 6 Questions You Don't Have A Story - Glenn Gers
The essence of a story is a character trying to accomplish something while people or things get in their way. Every character (not just the main one) is trying to accomplish something, and narrative is born each time they collide and get bumped off track, like billiard balls.