mirror of
https://github.com/wezm/wezm.net.git
synced 2024-12-18 18:29:54 +00:00
Add Alpine Linux and Docker Infrastructure Three Years Later
This commit is contained in:
parent
f0eed29ba7
commit
902b75077e
3 changed files with 321 additions and 0 deletions
|
@ -0,0 +1,106 @@
|
||||||
|
+++
|
||||||
|
title = "Alpine Linux and Docker Infrastructure Three Years Later"
|
||||||
|
date = 2022-02-28T09:52:10+10:00
|
||||||
|
|
||||||
|
[extra]
|
||||||
|
#updated = 2022-01-27T21:07:32+10:00
|
||||||
|
+++
|
||||||
|
|
||||||
|
Three years ago I published,
|
||||||
|
[Rebuilding My Personal Infrastructure With Alpine Linux and Docker][original-post],
|
||||||
|
in which I described how I was hosting various applications using an [Alpine
|
||||||
|
Linux][alpine] host and [Docker] on a virtual machine at [Vultr]. I thought it
|
||||||
|
would be good to write a follow-up on how this worked out.
|
||||||
|
|
||||||
|
<!-- more -->
|
||||||
|
|
||||||
|
The server I set up in 2019 is still running, although it has been through a
|
||||||
|
few Alpine upgrades in that time. Since there are very few packages installed
|
||||||
|
on the host, upgrades are painless. When I originally configured the
|
||||||
|
server Docker Compose was not in the stable Alpine package repos. It was added
|
||||||
|
in the mid-2019 Alpine 3.10 release. I was glad to be able to remove `pip` and
|
||||||
|
not have to manually manage compose updates after migrating to the package from
|
||||||
|
that point on.
|
||||||
|
|
||||||
|
In 2019 the services I was hosting looked like this:
|
||||||
|
|
||||||
|
![Before](https://www.wezm.net/images/2019/services.svg)
|
||||||
|
|
||||||
|
In 2022 the situation is now:
|
||||||
|
|
||||||
|
![After](services.svg)
|
||||||
|
|
||||||
|
As you can see the server is now running more containers. It now hosts a number
|
||||||
|
of new services including a [Pleroma] instance and several web-applications I
|
||||||
|
built in Rust ([leaf], [quotes], [dewpoint]). I also retired the [Binary
|
||||||
|
Trance] Rails instance and migrated from [acme.sh] to [lego]. I ran a [Nitter]
|
||||||
|
instance for a while but removed it after it bots made it consume a huge amount
|
||||||
|
of bandwidth. See my [Burning 2.5Tb of Bandwidth Hosting a Nitter
|
||||||
|
Instance](@/posts/2021/nitter-bandwidth/index.md) post for more details on
|
||||||
|
that.
|
||||||
|
|
||||||
|
The [Read Rust] application is implemented in [Crystal]. This one posed a bit
|
||||||
|
of a challenge. It is the only container I run that is not derived from a
|
||||||
|
minimal Alpine base image that I build myself. Instead, it uses `debian-slim`. I
|
||||||
|
need to use a specific version of the Crystal compiler to build my application,
|
||||||
|
which means I can't use the version in the Alpine package repos. Additionally
|
||||||
|
the Linux binaries that the project published for this version are not
|
||||||
|
dynamically linked but the bundled `libgc.a` assumes a `glibc` based system:
|
||||||
|
|
||||||
|
$ crystal build src/asdf.cr
|
||||||
|
/usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/../../../../x86_64-alpine-linux-musl/bin/ld: /crystal-0.34.0-1/bin/../lib/crystal/lib/libgc.a(pthread_support.o): in function `GC_thr_init':
|
||||||
|
pthread_support.c:(.text+0x1137): undefined reference to `gnu_get_libc_version'
|
||||||
|
⋮
|
||||||
|
|
||||||
|
For this reason I opted to use a Debian base image for this container and that's
|
||||||
|
worked fine.
|
||||||
|
|
||||||
|
Another notable change is the move from [acme.sh] to [lego] for managing TLS
|
||||||
|
certificates. In my original post I noted the following regarding how the
|
||||||
|
certificates were renewed:
|
||||||
|
|
||||||
|
> Docker and cron is also a challenge. I ended up solving that with a simple
|
||||||
|
> solution: use the host cron to `docker exec` acme.sh in the `hitch` container.
|
||||||
|
> Perhaps not “pure” Docker but a lot simpler than some of the options I saw.
|
||||||
|
|
||||||
|
It turned out that this never worked. I could see that cron was running the
|
||||||
|
script but the certs would not get renewed. For a while I ran the
|
||||||
|
script manually to renew them, which did work. Eventually I got sick of this, and
|
||||||
|
thinking `acme.sh` was to blame I searched for an alternative.
|
||||||
|
|
||||||
|
I settled on [lego], an ACME client implemented in Go. I [discovered and
|
||||||
|
suggested a fix for a bug][lego-bug] and [contributed LuaDNS
|
||||||
|
support][lego-luadns] in May 2020 and then migrated over to using it instead of
|
||||||
|
`acme.sh`. It was in the final stages of test this that I discovered the cron
|
||||||
|
bug was in my script all along. Adding `-T` to inhibit `docker-compose exec`
|
||||||
|
from allocating a TTY fixed the issue. It's likely this would have fixed the
|
||||||
|
issue for `acme.sh` as well. Ultimately lego felt like the better option as the
|
||||||
|
code in `acme.sh` for constructing API requests and [parsing their
|
||||||
|
results][acme-parse] seemed quite fragile
|
||||||
|
|
||||||
|
[Jokes aside][it-works-on-my-machine], I still find the Docker workflow of
|
||||||
|
iterating on an image locally then shipping it when it's working to be quite
|
||||||
|
pleasant. In summary this server has served me well over the last three years
|
||||||
|
and I have no immediate plans to rebuild again. It's been reliable and mostly
|
||||||
|
hassle free. Hosting on [Vultr] has also been reliable and stable over that
|
||||||
|
whole time with only the odd interruption for network maintenance or network
|
||||||
|
issues.
|
||||||
|
|
||||||
|
[original-post]: https://www.wezm.net/technical/2019/02/alpine-linux-docker-infrastructure/
|
||||||
|
[alpine]: https://alpinelinux.org/
|
||||||
|
[Docker]: https://www.docker.com/
|
||||||
|
[Vultr]: https://www.vultr.com/?ref=7903263
|
||||||
|
[lego-luadns]: https://github.com/go-acme/lego/pull/1135
|
||||||
|
[lego-bug]: https://github.com/go-acme/lego/issues/1150
|
||||||
|
[acme-parse]: https://github.com/acmesh-official/acme.sh/blob/2a2d556551e9266a3924da205c1ede55d89a689d/dnsapi/dns_lua.sh#L117-L126
|
||||||
|
[Pleroma]: https://pleroma.social/
|
||||||
|
[lego]: https://go-acme.github.io/lego/
|
||||||
|
[acme.sh]: https://github.com/acmesh-official/acme.sh
|
||||||
|
[Read Rust]: https://github.com/wezm/read-rust/
|
||||||
|
[Crystal]: https://crystal-lang.org/
|
||||||
|
[Binary Trance]: https://binarytrance.com/
|
||||||
|
[leaf]: https://github.com/wezm/leaf
|
||||||
|
[quotes]: https://github.com/wezm/Quotes
|
||||||
|
[dewpoint]: https://github.com/wezm/dewpoint.7bit.org
|
||||||
|
[Nitter]: https://github.com/zedeus/nitter
|
||||||
|
[it-works-on-my-machine]: https://www.reddit.com/r/ProgrammerHumor/comments/cw58z7/it_works_on_my_machine/
|
|
@ -0,0 +1,24 @@
|
||||||
|
digraph G {
|
||||||
|
node[shape=box];
|
||||||
|
edge[headport=n];
|
||||||
|
|
||||||
|
subgraph cluster {
|
||||||
|
hitch
|
||||||
|
lego
|
||||||
|
}
|
||||||
|
hitch -> varnish;
|
||||||
|
varnish -> nginx;
|
||||||
|
varnish -> pkb;
|
||||||
|
varnish -> wizards;
|
||||||
|
varnish -> rust_melbourne;
|
||||||
|
varnish -> pleroma;
|
||||||
|
varnish -> read_rust;
|
||||||
|
varnish -> read_rust_leaf;
|
||||||
|
varnish -> quotes;
|
||||||
|
varnish -> dewpoint;
|
||||||
|
pkb -> syncthing;
|
||||||
|
read_rust -> postgresql:ne;
|
||||||
|
wizards -> postgresql;
|
||||||
|
rust_melbourne -> postgresql:ne;
|
||||||
|
pleroma -> postgresql:ne;
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||||
|
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<!-- Generated by graphviz version 2.50.0 (0)
|
||||||
|
-->
|
||||||
|
<!-- Title: G Pages: 1 -->
|
||||||
|
<svg width="891pt" height="276pt"
|
||||||
|
viewBox="0.00 0.00 890.50 276.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
|
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 272)">
|
||||||
|
<title>G</title>
|
||||||
|
<polygon fill="white" stroke="transparent" points="-4,4 -4,-272 886.5,-272 886.5,4 -4,4"/>
|
||||||
|
<g id="clust1" class="cluster">
|
||||||
|
<title>cluster</title>
|
||||||
|
<polygon fill="none" stroke="black" points="314,-208 314,-260 456,-260 456,-208 314,-208"/>
|
||||||
|
</g>
|
||||||
|
<!-- hitch -->
|
||||||
|
<g id="node1" class="node">
|
||||||
|
<title>hitch</title>
|
||||||
|
<polygon fill="none" stroke="black" points="448,-252 394,-252 394,-216 448,-216 448,-252"/>
|
||||||
|
<text text-anchor="middle" x="421" y="-230.3" font-family="Times,serif" font-size="14.00">hitch</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish -->
|
||||||
|
<g id="node3" class="node">
|
||||||
|
<title>varnish</title>
|
||||||
|
<polygon fill="none" stroke="black" points="456,-180 386,-180 386,-144 456,-144 456,-180"/>
|
||||||
|
<text text-anchor="middle" x="421" y="-158.3" font-family="Times,serif" font-size="14.00">varnish</text>
|
||||||
|
</g>
|
||||||
|
<!-- hitch->varnish -->
|
||||||
|
<g id="edge1" class="edge">
|
||||||
|
<title>hitch->varnish:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M421,-215.81C421,-208.28 421,-199.1 421,-190.06"/>
|
||||||
|
<polygon fill="black" stroke="black" points="424.5,-190 421,-180 417.5,-190 424.5,-190"/>
|
||||||
|
</g>
|
||||||
|
<!-- lego -->
|
||||||
|
<g id="node2" class="node">
|
||||||
|
<title>lego</title>
|
||||||
|
<polygon fill="none" stroke="black" points="376,-252 322,-252 322,-216 376,-216 376,-252"/>
|
||||||
|
<text text-anchor="middle" x="349" y="-230.3" font-family="Times,serif" font-size="14.00">lego</text>
|
||||||
|
</g>
|
||||||
|
<!-- nginx -->
|
||||||
|
<g id="node4" class="node">
|
||||||
|
<title>nginx</title>
|
||||||
|
<polygon fill="none" stroke="black" points="56,-108 0,-108 0,-72 56,-72 56,-108"/>
|
||||||
|
<text text-anchor="middle" x="28" y="-86.3" font-family="Times,serif" font-size="14.00">nginx</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->nginx -->
|
||||||
|
<g id="edge2" class="edge">
|
||||||
|
<title>varnish->nginx:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M385.78,-159.92C297.61,-156.8 71.7,-146.02 33.52,-116.75"/>
|
||||||
|
<polygon fill="black" stroke="black" points="36.29,-114.59 28,-108 30.37,-118.33 36.29,-114.59"/>
|
||||||
|
</g>
|
||||||
|
<!-- pkb -->
|
||||||
|
<g id="node5" class="node">
|
||||||
|
<title>pkb</title>
|
||||||
|
<polygon fill="none" stroke="black" points="128,-108 74,-108 74,-72 128,-72 128,-108"/>
|
||||||
|
<text text-anchor="middle" x="101" y="-86.3" font-family="Times,serif" font-size="14.00">pkb</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->pkb -->
|
||||||
|
<g id="edge3" class="edge">
|
||||||
|
<title>varnish->pkb:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M385.84,-158.82C311.15,-153.77 140.75,-139.87 106.91,-116.35"/>
|
||||||
|
<polygon fill="black" stroke="black" points="109.63,-114.14 101,-108 103.92,-118.18 109.63,-114.14"/>
|
||||||
|
</g>
|
||||||
|
<!-- wizards -->
|
||||||
|
<g id="node6" class="node">
|
||||||
|
<title>wizards</title>
|
||||||
|
<polygon fill="none" stroke="black" points="218,-108 146,-108 146,-72 218,-72 218,-108"/>
|
||||||
|
<text text-anchor="middle" x="182" y="-86.3" font-family="Times,serif" font-size="14.00">wizards</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->wizards -->
|
||||||
|
<g id="edge4" class="edge">
|
||||||
|
<title>varnish->wizards:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M385.99,-160.44C325.31,-158.6 205.13,-150.8 184.92,-117.95"/>
|
||||||
|
<polygon fill="black" stroke="black" points="188.17,-116.61 182,-108 181.46,-118.58 188.17,-116.61"/>
|
||||||
|
</g>
|
||||||
|
<!-- rust_melbourne -->
|
||||||
|
<g id="node7" class="node">
|
||||||
|
<title>rust_melbourne</title>
|
||||||
|
<polygon fill="none" stroke="black" points="365.5,-108 236.5,-108 236.5,-72 365.5,-72 365.5,-108"/>
|
||||||
|
<text text-anchor="middle" x="301" y="-86.3" font-family="Times,serif" font-size="14.00">rust_melbourne</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->rust_melbourne -->
|
||||||
|
<g id="edge5" class="edge">
|
||||||
|
<title>varnish->rust_melbourne:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M385.97,-159.89C354.01,-156.98 310.54,-147.58 302.36,-118.24"/>
|
||||||
|
<polygon fill="black" stroke="black" points="305.78,-117.45 301,-108 298.85,-118.37 305.78,-117.45"/>
|
||||||
|
</g>
|
||||||
|
<!-- pleroma -->
|
||||||
|
<g id="node8" class="node">
|
||||||
|
<title>pleroma</title>
|
||||||
|
<polygon fill="none" stroke="black" points="458.5,-108 383.5,-108 383.5,-72 458.5,-72 458.5,-108"/>
|
||||||
|
<text text-anchor="middle" x="421" y="-86.3" font-family="Times,serif" font-size="14.00">pleroma</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->pleroma -->
|
||||||
|
<g id="edge6" class="edge">
|
||||||
|
<title>varnish->pleroma:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M421,-143.81C421,-136.28 421,-127.1 421,-118.06"/>
|
||||||
|
<polygon fill="black" stroke="black" points="424.5,-118 421,-108 417.5,-118 424.5,-118"/>
|
||||||
|
</g>
|
||||||
|
<!-- read_rust -->
|
||||||
|
<g id="node9" class="node">
|
||||||
|
<title>read_rust</title>
|
||||||
|
<polygon fill="none" stroke="black" points="561.5,-108 476.5,-108 476.5,-72 561.5,-72 561.5,-108"/>
|
||||||
|
<text text-anchor="middle" x="519" y="-86.3" font-family="Times,serif" font-size="14.00">read_rust</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->read_rust -->
|
||||||
|
<g id="edge7" class="edge">
|
||||||
|
<title>varnish->read_rust:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M456.1,-156.48C480.82,-151.36 510.68,-140.58 517.54,-118.01"/>
|
||||||
|
<polygon fill="black" stroke="black" points="521.02,-118.4 519,-108 514.1,-117.39 521.02,-118.4"/>
|
||||||
|
</g>
|
||||||
|
<!-- read_rust_leaf -->
|
||||||
|
<g id="node10" class="node">
|
||||||
|
<title>read_rust_leaf</title>
|
||||||
|
<polygon fill="none" stroke="black" points="698,-108 580,-108 580,-72 698,-72 698,-108"/>
|
||||||
|
<text text-anchor="middle" x="639" y="-86.3" font-family="Times,serif" font-size="14.00">read_rust_leaf</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->read_rust_leaf -->
|
||||||
|
<g id="edge8" class="edge">
|
||||||
|
<title>varnish->read_rust_leaf:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M456.03,-159.68C511.87,-156.7 616.77,-147.23 635.95,-117.79"/>
|
||||||
|
<polygon fill="black" stroke="black" points="639.37,-118.59 639,-108 632.68,-116.51 639.37,-118.59"/>
|
||||||
|
</g>
|
||||||
|
<!-- quotes -->
|
||||||
|
<g id="node11" class="node">
|
||||||
|
<title>quotes</title>
|
||||||
|
<polygon fill="none" stroke="black" points="781.5,-108 716.5,-108 716.5,-72 781.5,-72 781.5,-108"/>
|
||||||
|
<text text-anchor="middle" x="749" y="-86.3" font-family="Times,serif" font-size="14.00">quotes</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->quotes -->
|
||||||
|
<g id="edge9" class="edge">
|
||||||
|
<title>varnish->quotes:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M456.1,-158.97C532.12,-154.15 707.97,-140.59 742.9,-116.56"/>
|
||||||
|
<polygon fill="black" stroke="black" points="746.05,-118.17 749,-108 740.35,-114.11 746.05,-118.17"/>
|
||||||
|
</g>
|
||||||
|
<!-- dewpoint -->
|
||||||
|
<g id="node12" class="node">
|
||||||
|
<title>dewpoint</title>
|
||||||
|
<polygon fill="none" stroke="black" points="882.5,-108 799.5,-108 799.5,-72 882.5,-72 882.5,-108"/>
|
||||||
|
<text text-anchor="middle" x="841" y="-86.3" font-family="Times,serif" font-size="14.00">dewpoint</text>
|
||||||
|
</g>
|
||||||
|
<!-- varnish->dewpoint -->
|
||||||
|
<g id="edge10" class="edge">
|
||||||
|
<title>varnish->dewpoint:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M456.09,-160.24C548.95,-157.8 796.69,-148.37 835.78,-116.77"/>
|
||||||
|
<polygon fill="black" stroke="black" points="838.89,-118.38 841,-108 832.88,-114.8 838.89,-118.38"/>
|
||||||
|
</g>
|
||||||
|
<!-- syncthing -->
|
||||||
|
<g id="node13" class="node">
|
||||||
|
<title>syncthing</title>
|
||||||
|
<polygon fill="none" stroke="black" points="144,-36 58,-36 58,0 144,0 144,-36"/>
|
||||||
|
<text text-anchor="middle" x="101" y="-14.3" font-family="Times,serif" font-size="14.00">syncthing</text>
|
||||||
|
</g>
|
||||||
|
<!-- pkb->syncthing -->
|
||||||
|
<g id="edge11" class="edge">
|
||||||
|
<title>pkb->syncthing:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M101,-71.81C101,-64.28 101,-55.1 101,-46.06"/>
|
||||||
|
<polygon fill="black" stroke="black" points="104.5,-46 101,-36 97.5,-46 104.5,-46"/>
|
||||||
|
</g>
|
||||||
|
<!-- postgresql -->
|
||||||
|
<g id="node14" class="node">
|
||||||
|
<title>postgresql</title>
|
||||||
|
<polygon fill="none" stroke="black" points="361,-36 269,-36 269,0 361,0 361,-36"/>
|
||||||
|
<text text-anchor="middle" x="315" y="-14.3" font-family="Times,serif" font-size="14.00">postgresql</text>
|
||||||
|
</g>
|
||||||
|
<!-- wizards->postgresql -->
|
||||||
|
<g id="edge13" class="edge">
|
||||||
|
<title>wizards->postgresql:n</title>
|
||||||
|
<path fill="none" stroke="black" d="M218.34,-74.98C248.03,-63.48 287.89,-47.9 305.71,-40.38"/>
|
||||||
|
<polygon fill="black" stroke="black" points="307.45,-43.43 315,-36 304.46,-37.1 307.45,-43.43"/>
|
||||||
|
</g>
|
||||||
|
<!-- rust_melbourne->postgresql -->
|
||||||
|
<g id="edge14" class="edge">
|
||||||
|
<title>rust_melbourne->postgresql:ne</title>
|
||||||
|
<path fill="none" stroke="black" d="M340.43,-71.93C354.33,-64.2 366.38,-54.62 365.61,-44.91"/>
|
||||||
|
<polygon fill="black" stroke="black" points="368.71,-43.27 361,-36 362.49,-46.49 368.71,-43.27"/>
|
||||||
|
</g>
|
||||||
|
<!-- pleroma->postgresql -->
|
||||||
|
<g id="edge15" class="edge">
|
||||||
|
<title>pleroma->postgresql:ne</title>
|
||||||
|
<path fill="none" stroke="black" d="M400.43,-71.93C390.8,-63.72 379.09,-53.44 368.29,-43.12"/>
|
||||||
|
<polygon fill="black" stroke="black" points="370.6,-40.48 361,-36 365.71,-45.49 370.6,-40.48"/>
|
||||||
|
</g>
|
||||||
|
<!-- read_rust->postgresql -->
|
||||||
|
<g id="edge12" class="edge">
|
||||||
|
<title>read_rust->postgresql:ne</title>
|
||||||
|
<path fill="none" stroke="black" d="M476.21,-74.9C440.12,-62.98 391.17,-46.73 370.66,-39.59"/>
|
||||||
|
<polygon fill="black" stroke="black" points="371.59,-36.2 361,-36 369.16,-42.76 371.59,-36.2"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 8.9 KiB |
Loading…
Reference in a new issue