@@ -32,6 +32,18 @@ REQUIRED_SYSTEM_PACKAGES="
32
32
sqlite3
33
33
xxd
34
34
"
35
+
36
+ # System dependencies for Arch Linux
37
+ REQUIRED_SYSTEM_PACKAGES_ARCH="
38
+ ca-certificates
39
+ curl
40
+ gnupg
41
+ jq
42
+ lsb-release
43
+ openssl
44
+ sqlite
45
+ "
46
+
35
47
# Docker packages.
36
48
REQUIRED_DOCKER_PACKAGES="
37
49
containerd.io
@@ -40,6 +52,12 @@ REQUIRED_DOCKER_PACKAGES="
40
52
docker-compose-plugin
41
53
"
42
54
55
+ # Docker packages for Arch Linux
56
+ REQUIRED_DOCKER_PACKAGES_ARCH="
57
+ docker
58
+ docker-compose
59
+ "
60
+
43
61
PUBLIC_IP=" "
44
62
METADATA_URLS=()
45
63
METADATA_URLS+=(" http://169.254.169.254/v1/interfaces/0/ipv4/address" ) # Vultr
@@ -86,6 +104,7 @@ function main {
86
104
87
105
# Check for a supported distribution.
88
106
SUPPORTED_OS=" false"
107
+ IS_ARCH=" false"
89
108
if [[ " ${DISTRIB_ID} " == " ubuntu" ]]; then
90
109
if [[ " ${DISTRIB_CODENAME} " == " focal" ]]; then
91
110
SUPPORTED_OS=" true"
@@ -105,10 +124,14 @@ function main {
105
124
SUPPORTED_OS=" true"
106
125
echo " * Detected supported distribution Debian 12"
107
126
fi
127
+ elif [[ " ${DISTRIB_ID} " == " arch" ]] || [[ " $( grep -i ' arch linux' /etc/os-release || true) " ]]; then
128
+ SUPPORTED_OS=" true"
129
+ IS_ARCH=" true"
130
+ echo " * Detected supported distribution Arch Linux"
108
131
fi
109
132
110
133
if [[ " ${SUPPORTED_OS} " != " true" ]]; then
111
- echo " Sorry, only Ubuntu 20.04, 22.04, Debian 11 and Debian 12 are supported by this installer. Exiting..."
134
+ echo " Sorry, only Ubuntu 20.04, 22.04, Debian 11, Debian 12, and Arch Linux are supported by this installer. Exiting..."
112
135
exit 1
113
136
fi
114
137
@@ -145,11 +168,19 @@ function main {
145
168
# Attempt to determine server's public IP.
146
169
#
147
170
148
- # First try using the hostname command, which usually works.
171
+ # Get IP addresses using a cross-platform approach - use ip command if available, fall back to ifconfig
149
172
if [[ -z " ${PUBLIC_IP} " ]]; then
150
- PUBLIC_IP=$( hostname --all-ip-addresses | awk ' { print $1 }' )
173
+ if command -v ip > /dev/null 2>&1 ; then
174
+ PUBLIC_IP=$( ip -4 addr show scope global | grep -oP ' (?<=inet\s)\d+(\.\d+){3}' | head -n1)
175
+ elif command -v ifconfig > /dev/null 2>&1 ; then
176
+ PUBLIC_IP=$( ifconfig | grep -Eo ' inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo ' ([0-9]*\.){3}[0-9]*' | grep -v ' 127.0.0.1' | head -n1)
177
+ elif [[ " ${IS_ARCH} " == " false" ]] && command -v hostname > /dev/null 2>&1 ; then
178
+ # Try hostname command with --all-ip-addresses flag (Debian/Ubuntu only)
179
+ PUBLIC_IP=$( hostname --all-ip-addresses 2> /dev/null | awk ' { print $1 }' || true)
180
+ fi
151
181
fi
152
182
183
+
153
184
# Prevent any private IP address from being used, since it won't work.
154
185
if [[ " ${PUBLIC_IP} " =~ ^(127\. | 10\. | 172\. 1[6-9]\. | 172\. 2[0-9]\. | 172\. 3[0-1]\. | 192\. 168\. ) ]]; then
155
186
PUBLIC_IP=" "
@@ -231,58 +262,87 @@ INSTALLER_MESSAGE
231
262
#
232
263
# Install system packages.
233
264
#
234
- if lsof -v > /dev/null 2>&1 ; then
235
- while true ; do
236
- apt_process_count=" $( lsof -n -t /var/cache/apt/archives/lock /var/lib/apt/lists/lock /var/lib/dpkg/lock | wc --lines || true) "
237
- if (( apt_process_count == 0 )) ; then
238
- break
239
- fi
240
- echo " * Waiting for other apt process to complete..."
241
- sleep 2
242
- done
243
- fi
265
+ if [[ " ${IS_ARCH} " == " true" ]]; then
266
+ echo " * Installing system packages for Arch Linux"
267
+ # Check if pacman is already running
268
+ if [[ -f /var/lib/pacman/db.lck ]]; then
269
+ echo " * Waiting for other pacman process to complete..."
270
+ while [[ -f /var/lib/pacman/db.lck ]]; do
271
+ sleep 2
272
+ done
273
+ fi
274
+
275
+ # Install system packages for Arch
276
+ pacman -Sy --noconfirm ${REQUIRED_SYSTEM_PACKAGES_ARCH}
277
+ else
278
+ if lsof -v > /dev/null 2>&1 ; then
279
+ while true ; do
280
+ apt_process_count=" $( lsof -n -t /var/cache/apt/archives/lock /var/lib/apt/lists/lock /var/lib/dpkg/lock | wc --lines || true) "
281
+ if (( apt_process_count == 0 )) ; then
282
+ break
283
+ fi
284
+ echo " * Waiting for other apt process to complete..."
285
+ sleep 2
286
+ done
287
+ fi
244
288
245
- apt-get update
246
- apt-get install --yes ${REQUIRED_SYSTEM_PACKAGES}
289
+ apt-get update
290
+ apt-get install --yes ${REQUIRED_SYSTEM_PACKAGES}
291
+ fi
247
292
248
293
#
249
294
# Install Docker
250
295
#
251
296
if ! docker version > /dev/null 2>&1 ; then
252
297
echo " * Installing Docker"
253
- mkdir --parents /etc/apt/keyrings
254
298
255
- # Remove the existing file, if it exists,
256
- # so there's no prompt on a second run.
257
- rm --force /etc/apt/keyrings/docker.gpg
258
- curl --fail --silent --show-error --location " https://download.docker.com/linux/${DISTRIB_ID} /gpg" | \
259
- gpg --dearmor --output /etc/apt/keyrings/docker.gpg
299
+ if [[ " ${IS_ARCH} " == " true" ]]; then
300
+ # Install Docker on Arch Linux
301
+ pacman -Sy --noconfirm ${REQUIRED_DOCKER_PACKAGES_ARCH}
260
302
261
- echo " deb [arch=$( dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/${DISTRIB_ID} ${DISTRIB_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
303
+ # Start and enable Docker service
304
+ systemctl enable docker.service
305
+ systemctl start docker.service
306
+ else
307
+ mkdir --parents /etc/apt/keyrings
262
308
263
- apt-get update
264
- apt-get install --yes ${REQUIRED_DOCKER_PACKAGES}
309
+ # Remove the existing file, if it exists,
310
+ # so there's no prompt on a second run.
311
+ rm --force /etc/apt/keyrings/docker.gpg
312
+ curl --fail --silent --show-error --location " https://download.docker.com/linux/${DISTRIB_ID} /gpg" | \
313
+ gpg --dearmor --output /etc/apt/keyrings/docker.gpg
314
+
315
+ echo " deb [arch=$( dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/${DISTRIB_ID} ${DISTRIB_CODENAME} stable" > /etc/apt/sources.list.d/docker.list
316
+
317
+ apt-get update
318
+ apt-get install --yes ${REQUIRED_DOCKER_PACKAGES}
319
+ fi
265
320
fi
266
321
267
322
#
268
323
# Configure the Docker daemon so that logs don't fill up the disk.
269
324
#
270
- if ! [[ -e /etc/docker/daemon.json ]]; then
271
- echo " * Configuring Docker daemon"
272
- cat << 'DOCKERD_CONFIG ' >/etc/docker/daemon.json
325
+ # Configure Docker daemon for log rotation
326
+ if [ ! -d /etc/docker ]; then
327
+ mkdir -p /etc/docker
328
+ echo " * Created /etc/docker directory"
329
+ fi
330
+
331
+ if [ ! -e /etc/docker/daemon.json ]; then
332
+ echo " * Configuring Docker daemon"
333
+ cat << 'DOCKERD_CONFIG ' >/etc/docker/daemon.json
273
334
{
274
- "log-driver": "json-file",
275
- "log-opts": {
276
- "max-size": "500m",
277
- "max-file": "4"
278
- }
335
+ "log-driver": "json-file",
336
+ "log-opts": {
337
+ "max-size": "500m",
338
+ "max-file": "4"
339
+ }
279
340
}
280
341
DOCKERD_CONFIG
281
- systemctl restart docker
342
+ systemctl restart docker
282
343
else
283
- echo " * Docker daemon already configured! Ensure log rotation is enabled."
344
+ echo " * Docker daemon already configured! Ensure log rotation is enabled."
284
345
fi
285
-
286
346
#
287
347
# Create data directory.
288
348
#
0 commit comments