content/blog/2022-10-22-alpine-linux.org
277 lines · 8669 bytes
1#+date: <2022-10-22 Sat 00:00:00>
2#+title: Alpine Linux: Installing and Configuring a Minimalist Server Operating System
3#+description: Detailed procedure for deploying Alpine Linux to achieve a secure, lightweight server environment optimized for web hosting and containerization.
4#+slug: alpine-linux
5#+filetags: :alpine:linux:server:
6
7* Alpine Linux
8
9[[https://alpinelinux.org][Alpine Linux]] is a very small distro, built
10on musl libc and busybox. It uses ash as the default shell, OpenRC as
11the init system, and apk as the package manager. According to their
12website, an Alpine container "requires no more than 8 MB and a minimal
13installation to disk requires around 130 MB of storage." An actual bare
14metal machine is recommended to have 100 MB of RAM and 0-700 MB of
15storage space.
16
17Historically, I've used Ubuntu's minimal installation image as my server
18OS for the last five years. Ubuntu worked well and helped as my original
19server contained an nVidia GPU and no onboard graphics, so quite a few
20distros won't boot or install without a lot of tinkering.
21
22Alpine has given me a huge increase in performance across my Docker apps
23and Nginx websites. CPU load for the new server I'm using to test Alpine
24hovers around 0-5% on average with an Intel(R) Core(TM) i3-6100 CPU @
253.70GHz.
26
27The only services I haven't moved over to Alpine are Plex Media Server
28and Syncthing, which may increase CPU load quite a bit depending on how
29many streams are running.
30
31** Installation
32
33In terms of installation, Alpine has an incredibly useful
34[[https://wiki.alpinelinux.org/wiki/Installation][wiki]] that will guide
35a user throughout the installation and post-installation processes, as
36well as various other articles and guides.
37
38To install Alpine, find an appropriate
39[[https://alpinelinux.org/downloads/][image to download]] and flash it
40to a USB using software such as Rufus or Etcher. I opted to use the
41Standard image for my x86_{64} architecture.
42
43Once the USB is ready, plug it into the machine and reboot. Note that
44you may have to use a key such as =Esc= or =F1-12= to access the boot
45menu. The Alpine Linux terminal will load quickly and for a login.
46
47To log in to the installation image, use the =root= account; there is no
48password. Once logged-in, execute the setup command:
49
50#+begin_src sh
51setup-alpine
52#+end_src
53
54The setup script will ask a series of questions to configure the system.
55Be sure to answer carefully or else you may have to re-configure the
56system after boot.
57
58- Keyboard Layout (Local keyboard language and usage mode, e.g., us and
59 variant of us-nodeadkeys.)
60- Hostname (The name for the computer.)
61- Network (For example, automatic IP address discovery with the "DHCP"
62 protocol.)
63- DNS Servers (Domain Name Servers to query. For privacy reasons, it is
64 NOT recommended to route every local request to servers like Google's
65 8.8.8.8.)
66- Timezone
67- Proxy (Proxy server to use for accessing the web. Use "none" for
68 direct connections to the internet.)
69- Mirror (From where to download packages. Choose the organization you
70 trust giving your usage patterns to.)
71- SSH (Secure SHell remote access server. "Openssh" is part of the
72 default install image. Use "none" to disable remote login, e.g. on
73 laptops.)
74- NTP (Network Time Protocol client used for keeping the system clock in
75 sync with a time-server. Package "chrony" is part of the default
76 install image.)
77- Disk Mode (Select between diskless (disk="none"), "data" or "sys", as
78 described above.)
79
80Once the setup script is finished, be sure to reboot the machine and
81remove the USB device.
82
83#+begin_src sh
84reboot
85#+end_src
86
87** Post-Installation
88
89There are many things you can do once your Alpine Linux system is up and
90running, and it largely depends on what you'll use the machine for. I'm
91going to walk through my personal post-installation setup for my web
92server.
93
941. Upgrade the System
95
96 First, login as =root= in order to update and upgrade the system:
97
98 #+begin_src sh
99 apk -U upgrade
100 #+end_src
101
1022. Adding a User
103
104 I needed to add a user so that I don't need to log in as root. Note
105 that if you're used to using the =sudo= command, you will now need to
106 use the =doas= command on Alpine Linux.
107
108 #+begin_src sh
109 apk add doas
110 adduser <username>
111 adduser <username> wheel
112 #+end_src
113
114 You can now log out and log back in using the newly-created user:
115
116 #+begin_src sh
117 exit
118 #+end_src
119
1203. Enable Community Packages
121
122 In order to install more common packages that aren't found in the
123 =main= repository, you will need to enable the =community=
124 repository:
125
126 #+begin_src sh
127 doas nano /etc/apk/repositories
128 #+end_src
129
130 Uncomment the community line for whichever version of Alpine you're
131 running:
132
133 #+begin_src sh
134 /media/usb/apks
135 http://dl-cdn.alpinelinux.org/alpine/v3.16/main
136 http://dl-cdn.alpinelinux.org/alpine/v3.16/community
137 #http://dl-cdn.alpinelinux.org/alpine/edge/main
138 #http://dl-cdn.alpinelinux.org/alpine/edge/community
139 #http://dl-cdn.alpinelinux.org/alpine/edge/testing
140 #+end_src
141
1424. Install Required Packages
143
144 Now that the community packages are available, you can install any
145 packages you need. In my case, I installed the web server packages I
146 need for my services:
147
148 #+begin_src sh
149 doas apk add nano nginx docker docker-compose ufw
150 #+end_src
151
1525. SSH
153
154 If you didn't install OpenSSH as part of the installation, you can do
155 so now:
156
157 #+begin_src sh
158 doas apk add openssh
159 #+end_src
160
161 Next, either create a new key or copy your SSH key to the server from
162 your current machines:
163
164 #+begin_src sh
165 # Create a new key
166 ssh-keygen
167 #+end_src
168
169 If you need to copy an existing SSH key from a current machine:
170
171 #+begin_src sh
172 # Copy key from existing machines
173 ssh-copy-id <username>@<ip_address>
174 #+end_src
175
1766. Firewall
177
178 Lastly, I installed =ufw= above as my firewall. To set up, default to
179 deny incoming and allow outgoing connections. Then selectively allow
180 other ports or apps as needed.
181
182 #+begin_src sh
183 doas ufw default deny incoming
184 doas ufw default allow outgoing
185 doas ufw allow SSH
186 doas ufw allow "WWW Full"
187 doas ufw allow 9418 # Git server port
188 #+end_src
189
1907. Change Hostname
191
192 If you don't like the hostname set during installation, you just need
193 to edit two files. First, edit the simple hostname file:
194
195 #+begin_src sh
196 doas nano /etc/hostname
197 #+end_src
198
199 #+begin_src sh
200 <hostname>
201 #+end_src
202
203 Next, edit the =hosts= file:
204
205 #+begin_src sh
206 doas nano /etc/hosts
207 #+end_src
208
209 #+begin_src sh
210 127.0.0.1 <hostname>.local <hostname> localhost.local localhost
211 ::1 <hostname> <hostname>.local
212 #+end_src
213
214* Nginx Web Server
215
216To set up my web server, I simply created the =www= user and created the
217necessary files.
218
219#+begin_src sh
220doas adduser -D -g 'www' www
221mkdir /www
222doas mkdir /www
223doas chown -R www:www /var/lib/nginx/
224doas chown -R www:www /www
225#+end_src
226
227If you're running a simple webroot, you can alter the main =nginx.conf=
228file. Otherwise, you can drop configuration files in the following
229directory. You don't need to enable or symlink the configuration file
230like you do in other systems.
231
232#+begin_src sh
233doas nano /etc/nginx/http.d/example_website.conf
234#+end_src
235
236Once the configuration is set and pointed at the =/www= directory to
237serve files, enable the Nginx service:
238
239#+begin_src sh
240# Note that 'default' must be included or Nginx will not start on boot
241doas rc-update add nginx default
242#+end_src
243
244* Docker Containers
245
246Docker works exactly the same as other systems. Either execute a
247=docker run= command or create a =docker-compose.yml= file and do
248=docker-compose up -d=.
249
250* Git Server
251
252I went in-depth on how to self-host a git server in another post:
253[[../git-server/][Self-Hosting a Personal Git Server]].
254
255However, there are a few differences with Alpine. First note that in
256order to change the =git= user's shell, you must do a few things a
257little different:
258
259#+begin_src sh
260doas apk add libuser
261doas touch /etc/login.defs
262doas mkdir /etc/default
263doas touch /etc/default/useradd
264doas lchsh git
265#+end_src
266
267* Thoughts on Alpine
268
269So far, I love Alpine Linux. I have no complaints about anything at this
270point, but I'm not completely finished with the migration yet. Once I'm
271able to upgrade my hardware to a rack-mounted server, I will migrate
272Plex and Syncthing over to Alpine as well - possibly putting Plex into a
273container or VM.
274
275The performance is stellar, the =apk= package manager is seamless, and
276system administration tasks are effortless. My only regret is that I
277didn't install Alpine sooner.