When a music festival was cancelled, idol fans supported the local community

Some uplifting news from Japan:

On April 13th in Shibata City of Niigata prefecture (Japan), the popular idol group Momoiro Clover Z had been planning a large music festival in cooperation with a large number of other artists, as well as local police, schools, and city government. However, on the day of festival the weather took a turn for the worse, and warnings were issued for strong winds, flash floods, and avalanches.

Although more than 10,000 people had arrived in the city already, the group made the decision to cancel the event and quickly organized an online broadcast of the artists’ musical performances in its place.

Among this, the group’s fans have received wide attention for their excellent reaction to the bad news. Making endless reassurances online that “the group made the correct decision” and that “safety is more important than anything,” they then turned their attention to the impact this would have on the local community and businesses. Fans called upon each other to buy food prepared at food stands to prevent excess waste, and to spend money at local businesses before returning home to support the community as much as possible.

There was no backlash, and no hard feelings. Just praise and compassion from everyone involved.

A website redesign

I’ve overhauled the design of my website, and am very happy with how it turned out.

The root homepage. Old design on the left, new design on the right.
The root homepage. Old design on the left, new design on the right.
A post page in dark mode. Old design on the left, new design on the right.
A post page in dark mode. Old design on the left, new design on the right.

Design considerations

The structure

My first inspiration was the concept of slash pages, which I love — they are very easy to understand, and have a fun vibe characteristic of simple webpages that are just collections of pages. I wanted to take it a step further, and use the structure of the website as a design feature. The navigation element is arranged like a file system, and the current page’s URL is displayed prominently in the header.

The colors

I used colors from the uchū color palette by Wibby. I love these colors and was waiting for a project to use them in. I can tell that a lot of care went into choosing each shade, and it made handling the dark mode appearance fairly easy.

Which brings me to:

Dark mode

There is a toggle in the upper-right, but the site will otherwise default to respecting your OS’s preference. I stopped using prefers-color-scheme declarations and instead am using light-dark(), which is fantastic.

I learned about it from this article by Sara Joy, which explained everything I needed to know and more. I won’t go into too many details here because you should just go read that article, but the main points of my implementation are:

  1. Declare color-scheme: light dark; on <html>, to automatically switch themes based on the visitor’s OS.
  2. Each time I specify a color in the CSS, write it like color: light-dark(black, white) to define the color for light mode and dark mode, respectively.
  3. If the theme toggle is clicked, update <html> to be only color-scheme: light or color-scheme: dark to lock it into the correct theme.
  4. Save the chosen theme to the browser’s localStorage to preserve the preference across visits.

All of the theme switching is done with Javascript, which has the advantage of creating a good fallback if Javascript is disabled — the default is to simply follow the OS’s preferences. And since the theme toggle button’s icon is drawn by Javascript to reflect the active theme, having no Javascript will render the button blank — which is perfect because it won’t do anything anyways.

That’s all the important things, I think

You can check out the source code here if you want to look inside.

Please reach out if something looks broken!

I'm going to try automatically un-boosting statuses after one week.

Until now, my usage of boosting was stuck in a mindset that is a remnant of Twitter's culture. Since boosted statuses are displayed on my timeline next to my own words, I find myself boosting statuses that resonate strongly with my own thoughts. "Had I thought of these words first, I may have been the one posting instead" is the metric.

On Mastodon and the fediverse, I think the recommended usage of boosting is to increase visibility to statuses that I think should be seen more widely. This has noting to do with whether they specifically mirror my own thoughts. "This is good, people should see this" is the metric.

At the same time I don't want my timeline to be filled with other people's words, so my solution is to automatically un-boost statuses after one week. After the initial boost of visibility, there shouldn't be a reason to have them stuck on my timeline forever. The aim is that this will give me the freedom to boost more widely, and not worry about diluting my own words.

I may have outgrown Coolify

I initially chose Coolify as a self-hosted alternative to Heroku when it got too expensive. Coolify makes a lot of things very easy, but I ended up having to dig in to the details and learn a lot to fix things that didn’t work. Now that I have learned a fair bit about server management, I’ve found that I may no longer need Coolify’s hand-holding.

Venturing into self-hosting

I knew next to nothing about Linux servers, Docker, reverse proxies, and the like. I had used Heroku for a long time, but its base price became restrictively expensive considering how small each of my little projects was, so I started looking for a service that could ease me into self-hosting my apps on a VPS.

I started with Dokku, but the lack of a GUI made me uncomfortable because I really had no idea what I was doing. I was running with my eyes closed, hoping I didn’t trip. Coolify seemed to make deployments easy, and had a lot of handy tools to let me manage all aspects of my services through a web GUI, so I jumped in.

Coolify was good, until it wasn’t

A lot things were very easy! Go to an open-source project’s repository, find a sample Docker Compose file, paste it into a box, and hit “Go”. It handled URLs, SSL certificates, routing, and probably a lot of other things that I wasn’t fully aware of.

But there were plenty of things that did not go so smoothly. In these cases I had to stumble my way to a working solution, learning about what Docker Compose files do, where files are placed on my server, how to install packages that I need, and so on.

When something went wrong with one of my apps, I would SSH into the server’s root and go digging through the files there to figure out what is happening. I learned how different containers are managed on the server, Docker’s command line utilities to ask each container what it is doing, various ways to change settings and reboot apps on the fly.

The last battle

My GoToSocial instance had a problem where it would randomly become unresponsive once every couple of days. I would realize that everything was timing out, and restarting the service was the only way to get things running again. It took me months of “debugging”, where I would dump out service logs, sift through documentation, and dig into every line of configuration that looked like it might be related to the problem in any way.

At last, I tracked down the problem.

My GoToSocial compose file defined a Docker network called gotosocial, as a network is required for the application and the database to communicate with each other. However, because a network is of course required, Coolify conveniently was also defining its own unique network, automatically and behind the scenes. And for some reason, a third network was also being created as the result of some combination of settings (I never did figure out why this was happening).

Of these multiple redundant networks, the GoToSocial application was attached to only two, and the reverse proxy was attached to a different two. Something at some point would trigger some load balancing in the reverse proxy, and it would switch to its second known network, which did not have the application attached. Hence the unresponsiveness.

All I had to do to fix this was to delete the gotosocial network declaration in the Docker Compose file. But in discovering that solution, I ended learning a lot about how reverse proxies and Docker networks work, and walking around in a lot of code. Now, I feel pretty confident that I would be able to manage Docker-based deploys without Coolify in the middle.

Which brings me to my latest realization.

Now, I can do this myself

Coolify does a lot of (most of the time) convenient things behind the scenes, but sometimes they aren’t what I need. To understand what these conveniences are, how to work with them, when they are good and when they are not, and how to change things when I need to, I had to learn a lot about all of the moving parts of a Linux server with multiple docker containers running various services.

Now that I have this experience, it seems like Coolify’s behind-the-scenes actions might be causing more trouble than convenience.

I think I will get myself a fresh new VPN and start trying to replicate my apps with just manual Docker deployments + a simple Caddy configuration. Or maybe Dokku again, that’s worth a revisit.

So, thanks to Coolify for bringing me here, but I think our time together will be ending.

Watched Adolescence, and wow what a ride. I was gripped from start to finish and was pretty emotionally battered at the end.

My AI manifesto

This is my personal manifesto for how I will and will not use generative AI. I believe it can be an extremely useful tool in certain situations, but can also have many negative repurcussions if used incorrectly.

1: Use to expand my abilities, not as a crutch.

A: Teach me new things

As a coding assistant, AI can quickly show me the correct syntax. It can suggest implementations, and teach me how to implement new functions. These are extremely useful, and help me to be exponentionally more productive as a hobby developer.

I must take care to use this as a tool to help me learn and grow. Instead of receiving the AI’s solution and calling it done, I need to understand what it has suggested and why, so that next time I will be better able to produce that answer on my own.

B: Do things I can’t do

If there is a trivial thing that I actually can’t do, and it is a progress blocker, I will use AI to fill in the gaps in my skill. Drawing a logo image for a silly pet project, creating a colorful, abstract background image, etc. It doesn’t make sense for me to learn how to do that for myself, so I feel comfortable delegating that to AI.

C: Don’t do things I can do

I do not use AI to write for me. I am able to write for myself, to express my thoughts through words in order to share my ideas with others. I believe that skills deteriorate without practice, and I am afraid of ever losing that ability. I will never delegate my writing, my thinking, and my shaping of ideas.

2: Treat as a tool for creators, not as a creator unto itself.

I work in a very creative, collaborative environment so this is very relevant professionally as well. It’s possible for me have an AI generate ideas, texts, and images, and by doing make me seem self-sufficient without collaborators. I will not do that.

A: Help those who create

There are many ways for creative professionals to use AI as a tool within their process. If an artist uses AI somehow to help in the creation of their own art, that feels fine. As above, my hope is that they will use it as a way to expand their capabilities, and not as a crutch.

B: Don’t try to be a creator

It feels wrong for a non-artist to generate images using AI and treat it as creative output. If I need visual artwork as part of a product, it will be created by a human creator. AI creations will not replace human creations.

AI can be used as a tool through the creative process, but will not be directly creating any part of the finished product. That is the responsibility of the creators, the people, and is too important to be delegated.

C: Help me to collaborate

While I will always value my ability to communicate through words, sometimes an image can be far more efficient. Finding common ground through concept art, such as by generating many sample images to collectively define what is needed, can be a fast way to reach a shared understanding.

The ease of producing many different formats for presenting an idea allows for experimentation in communication, which has possibilities that aren’t even fully explored yet.

Corollaries

1B + 2B: Do what I can’t do, while not replacing real creators

I will use AI to do things that I cannot do, but I will not treat the AI as a creator. Anything I create that directly uses something generated by AI will be presented as a proof-of-concept. I will not treat it as a finished product.

Anything that I present as a finished product will be ultimately created by people who can take responsibility as creators. Delegating that role to an AI is irresponsible.

I may have just flipped a setting that will halve our utility bill. Equal parts happy that I discovered this, and annoyed that I had been pissing away money for so long.

The Photo Composition Challenge

I am a mediocre photographer at best, but of course I want to improve. When I saw that @hiro was putting together 5-week challenge to experiment with various compositional techniques and share our photos, I had to join.

I don’t have fancy gear, or a lot of time to go hunting for photos, so almost all of my shots were scenes from my daily life, taken with an iPhone. I realized pretty quickly though, that being deliberate about composition gave a new perspective on even familiar scenes, and I was surprised at compelling some of the photos turned out.

Continue reading →