thought/my-deployment-platform-is-a-shell-script.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
my deployment platform is a shell script
2024-04-09
like many people, i fell in love with free software
because i could install it. i'd come home from work and
install a bunch of software.
what fun! tee hee! a playground and i'm the prince!
but eventually, relentlessly, it all starts to feel more
like a horror show.
proxmox needs an upgrade! *SPOOKY WIND*
how the fuck does k8s work again?? *SPOOKY CRICKETS*
promql *EXISTENTIAL SCREAM*
i'm too old now - i'm more fickle with my time. i like
things that work for years with as little interaction
from me as possible.
when it comes to my own projects, i always prioritize
maintainability.
to that end, i built a little deployment system that i
run on a single virtual machine - it's a shell script!
i run it every minute via cron.
here's the script, in its entirety:
#!/bin/sh
println() {
printf "%s\n" "$1" >> /root/gocicd.log
}
die() {
printf "%s\n" "$1" >> /root/gocicd.log
exit 1
}
cd /root
for project in $(ls go-cicd); do
cd "/root/go-cicd/$project" 2>&1 >> /root/gocicd.log
git fetch origin 2>&1 >> /root/gocicd.log
if git status | grep -q behind; then
println "$(date): building $project"
git merge origin/main ||
git merge origin/master ||
die "could not merge $project"
go build ||
die "could not build $project"
mv "$project" "/usr/local/bin/$project"
cat <<EOF >/etc/init.d/$project"
#!/sbin/openrc-run
supervisor="supervise-daemon"
command="/usr/local/bin/j3s.sh"
directory="/root/go-cicd/j3s.sh"
EOF
service "$project" restart
exec gocicd
fi
done
whenever i make an upstream change to any of my tracked
projects, it is cloned, built, and running within 60
seconds.
this gives me a lot of joy. the blog post you're reading
right now was deployed using this system (j3s.sh is a go
application).
this has worked for many years with no maintenance at
all!
my script will never:
- go down
- require an upgrade
- force me to migrate
- surprise me
- keep me up at night
all of this makes jes very happy.
digging in a little, the contents of the go-cicd dir look like this:
$ ls go-cicd/
existentialcrisis.sh jackal nekobot
j3s.sh vore neoarkbot
these are all of my "tracked projects".
to start tracking a new project, i only need to clone a
repository:
$ cd go-cicd
$ git clone git.j3s.sh/newproject
now whenever a new commit is made to
git.j3s.sh/newproject, it is deployed within 60 seconds.
ez.
here's a little taste of the log file:
$ tail -n 5 go-cicd.log
Thu Feb 8 00:13:12 UTC 2024: building vore
Fri Feb 9 22:08:25 UTC 2024: building vore
Mon Apr 8 02:07:00 UTC 2024: building j3s.sh
Mon Apr 8 02:59:00 UTC 2024: building j3s.sh
Tue Apr 9 21:11:00 UTC 2024: building vore
cool! i wonder what happened in march.
(oh, i moved to Virginia, right)
i recognize that this script is pretty limited. it can
only deploy golang applications to my alpine system, but
that's exactly the point i'm trying to prove:
a little, specific solution might be easier to maintain
and straight up more enjoyable than a larger, more
general system.
i spent maybe 10 minutes writing this script in December
of 2021, and i'm proud of how reliable it has been.
consider keeping your little things little.
it worked for little old me.
until next time, with love from virginia,
lil jes