content/blog/2022-10-22-alpine-linux.org

e8577d98faff1bed72ba6f2d204b8b44c6827c23
cleberg.net/content/blog/2022-10-22-alpine-linux.org rendered · source · history · blame · raw

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.