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