Skip to main content

Ralsina.Me — Roberto Alsina's website

Posts about linux (old posts, page 20)

Owning a Pet Server, in 2022

Introduction

The slow­est pen­du­lum in tech is the dis­tri­bu­tion/­cen­tral­iza­tion one. It takes years, even decades to swing. That's why we once had cen­tral­ized time­shar­ing com­put­ers with dumb ter­mi­nal­s, and then we had per­son­al com­put­er­s, which we turned in­to in­ter­net ter­mi­nal­s, which we are stuck with.

This seems to be stick­ing, but hey, so did the oth­er two. It may swing the oth­er way, or it may not. Who knows, I am not a fu­tur­ol­o­gist, but I am swing­ing it a lit­tle bit, for my­self, in one small area: I am not hap­py with my da­ta liv­ing pri­mar­i­ly in large serv­er farms owned by oth­er­s.

So, rather than hav­ing my da­ta live in a cat­tle serv­er in a serv­er far­m, it now most­ly lives in a pet server, at home.

Al­low me to in­tro­duce you to ... pinky.

Picture of a small white plastic computer

Pinky will not wow you with spec­s, it's per­haps the slow­est prac­ti­cal serv­er pos­si­ble:

  • Rasp­ber­ry Pi 3b+, 1GB of RAM
  • 16GB SD card
  • 2x500GB HDD (mir­rored)

But it is more than enough for some spe­cif­ic class­es of work I need­ed. In this doc­u­ment I will try to ex­plain why I want­ed to do them, de­scribe them, and ex­plain the trade­offs in­volved, and the de­ci­sion process that lead me to the de­ci­sion to adopt this so­lu­tion.

Software

One of the most im­por­tant things here is Gitea.

It's hard to over­state what a game chang­er it is for a spe­cif­ic kind of user: Gitea makes host­ing a user-friend­ly git ser­vice easy and cheap.

So what? You may ask.

Well, a git serv­er is use­ful as a back­end for many ac­tu­al­ly use­ful ser­vices, even if you don't care about soft­ware de­vel­op­ment (which I do).

Pass

For ex­am­ple, sup­pose you want to man­age your own pass­word­s, in­stead of re­ly­ing on a third par­ty ser­vice. Well one way to do it is to use pass which is an open source im­ple­men­ta­tion which is sup­port­ed in most web browser­s, desk­top ap­pli­ca­tion­s, ter­mi­nals and what­not.

But if you have more than one de­vice ... then how do you sync your pass­words be­tween them? Yes, us­ing a git serv­er.

Chezmoi

Yes, I use more than one com­put­er. I have one at home, one in the of­fice, an­oth­er one for work, plus I am build­ing some home­made stuff us­ing rasp­ber­ry pis, and I want some things to work in the same way in all of them.

Chez­moi is an im­ple­men­ta­tion of the dot­files con­cep­t.

Ba­si­cal­ly: you tell it to man­age some of the con­fig files in your home di­rec­to­ry, which are then ver­sioned and shared be­tween com­put­ers us­ing ... you guessed it, a git serv­er.

It took some ef­fort to get things in a use­ful state but now I think it's ac­tu­al­ly adding val­ue to my sys­tem­s.

My Website

Yeah, I know, so 2003. But hey, it works for me. A cen­tral­ized lo­ca­tion for:

  • Things I write, like this one
  • Books I read and com­ment one, via goodreads
  • Videos I make, via youtube

Again, one of the goals is that my da­ta is mine so all those book list­s, and com­ments and star-rat­ings and what­ev­er ... why would they live on­ly in goodread­s? What if Ama­zon clos­es it?

Well, be­cause I can write soft­ware, I just get it all and put it in my own site, thank you very much.

And guess where the canon­i­cal source of all that is? Yeah, a git repos­i­to­ry, au­to­mat­i­cal­ly built and de­ployed.

Dis­clo­sure: my site is most­ly host­ed on a VPS I al­ready pay for, but there is a mir­ror at home­.ralsi­na.me which is, in­deed, in my pinky serv­er.

Gateway to my Office / Home VPN

All these ser­vices need to be ac­cessed from some­where. Us­ing some gen­er­ous free-ti­er ser­vices from fly and tailscale plus some con­fig­u­ra­tion ef­fort I can, from any of my com­put­ers (and my phone too) ac­cess any oth­er, re­gard­less of where they are, as long as they have some sort of in­ter­net con­nec­tion.

Hardware

Why THIS Hardware?

Be­cause I had it ly­ing around.

  • The rasp­ber­ry from old pro­ject­s, gath­er­ing dust.
  • Two 500GB HDDs from old note­books and giv­en as gift­s.

I had to buy 2 US­B-SA­TA ca­bles (about 5 dol­lars) and a nicer knit­ted mi­cro-usb an­gled ca­ble so it looked pret­ty (1 dol­lar).

Performance

Yes, it's pret­ty slow, but ... is it?

The rasp­ber­ry pi 3b+ is a 4-­core ma­chine, so it can run gitea, a web serv­er and a cou­ple oth­er things with­out any is­sues.

Sure, it's USB 2.0 on­ly, so ac­cess to stor­age is ... not fast.

OTO­H, most of the time I am ac­cess­ing ei­ther very small things (a git pull is pret­ty ef­fi­cien­t!) or over a slow link (30Mbps at most) so stor­age speed is hard­ly ev­er the bot­tle­neck.

One spe­cif­ic thing that makes no sense would be RAID mir­ror­ing be­tween the two disks, it would just make ev­ery­thing slow­er be­cause of the need to write each change twice.

So I turn off one of the disks (saves on wear) and turn it on at night to back­up the whole serv­er in­to it.

Adi­tion­al­ly, I can once a week take the sec­ondary disk and back it up off­site.

Power Usage

Run­ning at full throt­tle, my USB pow­er con­sump­tion mea­sur­ing thing I got for a dol­lar (so take it with a grain of salt) says it may use 1.1A at 5v, so in av­er­age it's prob­a­bly us­ing some­thing like 4W.

I checked my pow­er bill and that comes down to about 20 ar­gen­tini­an pe­sos a mon­th, or 10 US cents.

The Case

I grabbed a rasp­ber­ry "sleeve" case and a 2.5" HDD "sleeve" case out of thin­gi­verse, and slapped them on­to a few box­es, then print­ed it in the cheap­est 3D print­er mon­ey can buy. It works great.

Be­cause it's a Pi 3 and not a Pi 4 it can be pas­sive­ly cooled with no prob­lem and I print­ed the HDD sleeves at 50% in­fill so they would muf­fle the noise a bit. I can on­ly hear the oc­ca­sion­al click from the hard drives, but it's pret­ty much silen­t.

It's al­so around 10cm in each di­men­sion. That's pret­ty smal­l.

Conclusion

This serv­er (with­out the case, that's new) has been work­ing for around a month. It has au­to­mat­ic soft­ware up­dates for ev­ery­thing and if some­thing would hap­pen to break I can live with­out it for a few days with­out any is­sues.

I con­sid­er it a com­plete suc­cess.

The Cheapest Server in the Universe

Intro

This is a sto­ry about hav­ing your own web app serv­er in the cheap­est, sim­plest, func­tion­al man­ner.

Let's as­sume that for what­ev­er rea­son you have some apps you want to use. Me, I have two:

  • Gitea: sort of your own GitHub. Why? Be­­cause own­ing your own da­­ta is OK, I think. So I want the POS­SI­­BIL­I­­TY of hav­ing my own serv­er. You can still clone the re­­pos to GitHub so you lose noth­ing.

  • My own site: Be­­cause, again, what I write is mine, and why not host it my­­self in­­stead of up­­load­­ing to Medi­um or some oth­­er sim­i­lar­­ly ma­lig­­nant pus­­tule of a site. Be­­sides, I've been do­ing it for over 20 years, so why stop now.

It could be any­thing! Some app you are de­vel­op­ing, some­thing you want to try, Own­Cloud or what­ev­er, if you are the sort of nerd that wants his own ap­p/site ... it's doable.

So let's con­fig­ure, from scratch, ev­ery­thing you need to ac­cess those sites/app­s.

Level 1: self hosting

For your own app­s, you will need your own hard­ware in which they can run. Let's con­sid­er the cheap­est gen­er­al use com­put­er you can buy that has some sort of net­work sup­port?

A Rasp­ber­ry Pi Ze­ro W ... 10 bucks if you could buy one. But hey, I have one or six of them, the one I'll use is called pinky.

If you don't have or don't want one of those, any­thing that can run Lin­ux is prob­a­bly OK. Or win­dows. Or Ma­cOS, but this guide as­sumes Lin­ux, so I rec­om­mend that for now. The hard­ware can prob­a­bly by any work­ing com­put­er, there is prob­a­bly no com­put­er too slow for this.

Or rather, it de­pends on what you want to run in it, so YM­MV.

I won't go in­to de­tail­s, but in­stall what­ev­er you want to run, and make it work lo­cal­ly. In my case that mean­s:

How? Look it up for what­ev­er thing you are try­ing to make work dude!

As long as it's not work­ing and ac­ces­si­ble in your lo­cal net­wor? Good, Lev­el Up!

Level 2: remote access

What about us­ing that site when you are not on the same lo­cal net­work?

Well, that won't work. Of course http://pinky.lo­cal:3000 on­ly works lo­cal­ly, so let's fix that.

There are many ways, but this is one: tailscale, specif­i­cal­ly the free one-per­son ver­sion.

What's tailscale? It's a VP­N.

It's a per­son­al VP­N. If you reg­is­ter and in­stall it in at least a cou­ple of ma­chines it will cre­ate a net­work con­nect­ing all ma­chines to each oth­er even when they are not in the same lo­cal net­work.

So if you in­stall tailscale on a serv­er (pinky in my case) and in the note­book you nor­mal­ly use (in this case salma) those ma­chines can al­ways see each oth­er us­ing some spe­cial names tailscale gives them.

Tailscale dashboard

Click­ing on one of the ma­chines gives de­tails about it:

Tailscale machine details

As you can see pinky now is al­so known as pinky.ralsi­na.github.­be­ta.­tailscale.net thanks to tailscale.

Don't both­er try­ing to ac­cess that be­cause it on­ly works if you are mem­bers of my VPN and you ain't gonna.

But I can!

gitea via tailscale

Maybe this is all you need. Right now you can ac­cess your servers from any­where as long as you are logged in­to the tailscale VP­N. Nice!

But what about oth­er peo­ple? Then you need to Lev­el UP!

Level 3: Ingress Rules

Again there are many ways to give oth­ers ac­cess to your server, but this is one I like: fly­.io

Fly is a com­pa­ny that gives you the abil­i­ty to run "stuff" on "free" vir­tu­al ma­chi­nes, with­in cer­tain lim­it­s. For ex­am­ple, not more than 160GB of out­go­ing da­ta a mon­th, more than that and they start charg­ing.

So, how about run­ning one of those VMs and con­nect­ing it to our tailscale VP­N? And then run there a re­verse proxy in it so it's an in­ter­me­di­ary that al­lows third par­ties ac­cess to our server­s? Right?

Well, this is the doc­u­men­ta­tion you need to con­nect a Fly VM to a Tailscale VP­N.

And here's a slight mod­i­fi­ca­tion of those files, so the VM runs Ng­inx

Mod­i­fy ng­inx.­conf as need­ed to route con­nec­tions where you wan­t.

At this point you can probably not use two hostnames (later we can) and server_name should be the public name Fly gave you, in my case white-wave-7409.fly.dev

dashboard fly.io

Once you do that, you should be able to ac­cess some­thing us­ing that host­name:

My site working in that URL

As you can see it's us­ing HTTP­S, be­cause Fly al­so pro­vides an "outer" re­verse proxy that's do­ing HTTPS ter­mi­na­tion, so no need to cre­ate cer­tifi­cates or any­thing.

And now we have a web­site, ac­ces­si­ble from any de­vice with an in­ter­net con­nec­tion, for free (up to 160G­B) ... mis­sion ac­com­plished!

Ex­cept ... that URL is ug­ly. I would rather have Gitea use some­thing like git.ralsi­na.me and my home­-host­ed site at home­.ralsi­na.me, right?

Well, we need to Lev­el UP again!

Level 4: Custom DNS

There are in­fi­nite ways to do this but this is the one I used.

Cloud­flare works as a free DNS serv­er. If you al­ready have a do­main, con­fig­ure it, or use your own DNS server, or what­ev­er.

If you don't own a do­main buy or bor­row one, use google, fig­ure it out.

Once you have Cloud­flare or what­ev­er DNS work­ing, con­fig­ure CNAME records for each host you wan­t. I did two:

CNAMEs at cloudflare

Both are point­ed to the name Fly gave me, so they re­solve llike this:

> host git.ralsina.me
git.ralsina.me is an alias for white-wave-7409.fly.dev.
white-wave-7409.fly.dev has address 37.16.0.181
white-wave-7409.fly.dev has IPv6 address 2a09:8280:1::6:3716

If you are us­ing cloud­flare they must be con­fig­ured as "DNS On­ly".

The last step is telling Fly that we use those CNAMEs so we need to cre­ate and reg­is­ter SSL cer­tifi­cates for them. Luck­i­ly that's easy, just run these com­mands in the ma­chine where you are man­ag­ing your Fly ap­p:

> flyctl certs create git.ralsina.me
> flyctl certs create home.ralsina.me

Again fix ng­inx con­fig so it us­es the host­names to route re­quests wher­ev­er they should go and ev­ery­thing should "Just Work".

What have we achieved?

  • Servers ac­ces­si­ble from any­where: Gitea and My site
  • Which are run­ning in the cheap­est pos­si­ble serv­er
  • With nice URLs
  • For free
  • With­out hav­ing to make holes and re­con­fig­ure fire­wall­s.

I have not seen a guide that ex­plains this all the way, so hope­ful­ly it will be use­ful for some­one!

The perfect Raspberry Pi setup

I am do­ing some semi-se­ri­ous Rasp­ber­ry Pi de­vel­op­men­t, so it was time I fig­ured out how to do it com­fort­ably.

My desk­top set­up is a two-­mon­i­tor con­fig­u­ra­tion, with my note­book on the ta­ble and a larg­er mon­i­tor above it. I like it, it's nice. The point­er nat­u­ral­ly goes from one screen to the oth­er in the ob­vi­ous way.

Desktop setup

Spe­cial­ly nice is that the lap­top's screen is touch and has an ac­tive pen, so I can use it nat­u­ral­ly.

But now, with the Rasp­ber­ry, I want to oc­ca­sion­al­ly show its dis­play. And that means switch­ing the mon­i­tor to it. Since I hate plug­ging and un­plug­ging things, I use one of the­se:

HDMI switch

It's a cheap tiny black plas­tic box that takes up to 5 HD­MI in­puts and switch­es be­tween them to its one out­put by click­ing a but­ton. It on­ly goes through the in­puts that have sig­nal, so since I on­ly have the lap­top's and the Pi's the but­ton tog­gles be­tween them.

If your mon­i­tor has more than one HD­MI in­put you can prob­a­bly just use that, but mine has just one.

But... what about key­board and mouse?

I could get a mul­ti­de­vice key­board and mouse, but I like the ones I have.

I could use a USB switch and tog­gle be­tween the two de­vices, but ... I don't have one.

So, I use bar­ri­er and con­fig­ure it in both the rasp­ber­ry pi and in the lap­top so that when my point­er goes "up" in­put goes to the Pi, and when it goes "down" in­put goes to the lap­top. That's ex­act­ly the same as with the du­al-dis­play se­tup, but with two com­put­er­s. Neat!

So, go ahead and con­fig­ure bar­ri­er. It's easy and there are tons of tu­to­ri­al­s.

Nex­t, make sure bar­ri­er starts when I lo­gin in­to both com­put­er­s. They way I pre­fer to do these things is us­ing sys­temd.

Put this in ~/.local/share/systemd/user/barrier.service in both machines:

[Unit]
Description=Barrier server
[Service]
Environment=DISPLAY=:0
Type=simple
TimeoutStartSec=0
ExecStart=/usr/bin/barrier
[Install]
WantedBy=default.target

Now you can make it start with systemctl --user start barrier or stop with systemctl --user stop barrier and make it start on every login with systemctl --user enable barrier

But while this is nice, it presents a prob­lem. When I am us­ing both dis­plays for the lap­top, I don't want bar­ri­er run­ning! Since I can't see the Pi's dis­play, it makes no sense.

So, I want to start bar­ri­er when the lap­top is us­ing one mon­i­tor, and stop it when it's us­ing two.

To do that, the trick is udev in the laptop. Put this (replacing my username with yours) in /etc/udev/rules.d/90-barrier.rules:

ACTION=="change", \
    KERNEL=="card0", \
    SUBSYSTEM=="drm", \
    ENV{DISPLAY}=":0", \
    ENV{XAUTHORITY}="/home/ralsina/.Xauthority", \
    ENV{XDG_RUNTIME_DIR}="/run/user/1000", \
    RUN+="/home/ralsina/bin/monitors-changed"

Basically that means "when there is a change in the configuration of the video card, run monitors-changed. Change the 1000 by your user ID, too.

The last piece of the puzzle is the monitors-changed script:

if `xrandr --listmonitors | grep -q HDMI`
then
    # The HDMI output is connected, stop barrier
    su ralsina -c '/usr/bin/systemctl stop --user barrier'
else
    # The Pi is using the monitor, start barrier
    su ralsina -c '/usr/bin/systemctl start --user barrier'
fi

And that's it!

This is the be­hav­iour now:

  • When the lap­­top is us­ing both dis­­­plays, they work nor­­mal­­ly in a "ex­­tend­ed dis­­­play" con­­fig­u­ra­­tion. They be­have like a sin­­gle large screen.

  • When I click on the HD­­MI switch and change the top dis­­­play to show the Pi's desk­­top, au­­to­­mat­i­­cal­­ly bar­ri­er starts in the lap­­top, and now the point­er and key­board change from one com­put­er to the oth­­er when the point­er moves from one mon­i­­tor to the nex­t.

  • If I click on the HD­­MI switch again, bar­ri­er stops on the lap­­top and I have a sin­­gle two-screen desk­­top again.

Ev­ery­thing be­haves per­fect­ly and I can switch be­tween com­put­ers by click­ing a but­ton.

Al­ter­na­tive­ly, we could start the bar­ri­er client when the rasp­ber­ry pi "get­s" the dis­play, and stops it when it goes away. The re­sult should be the same ex­cept for some cor­ner cas­es, but it has the added ben­e­fit of al­low­ing for a set­up with up to 5 de­vices :-)


Contents © 2000-2022 Roberto Alsina