Project

General

Profile

ServerSetup » History » Version 2

Redmine Admin, 05/28/2022 11:20 AM
updating page

1 1
h1. Server Setup
2
3 2 Redmine Admin
In late 2012 I decided it was time to retire the old Dell desktop (the original phalanx) that had been limping along as my fileserver and build a proper fileserver.  The new [[main:Phalanx|phalanx]] was born. Here are some of the important design/configuration decisions that I made:
4 1
5
* boot drive is a small SSD that is separate from the storage array which allows OS to be upgraded independently of file storage
6
* software RAID 5 (device mapper raid) using 6 X 3TBB HDDs (12 TB raw, ~11.1 TB useable)
7
8
Although phalanx's primary purpose is as an internal fileserver, it runs 24/7 and has plenty of spare cycles to also act as a webserver. Below are some of the things it is currently running.
9
10
h2. Update History
11
12 2 Redmine Admin
*5/27/2022*
13
14
   * Wipe and install Ubuntu 22.04
15
16 1
*7/8/2019*
17
18
   * Change Dynamic DNS provider to http://freedns.afraid.org. 
19
   
20
*1/9/2019*
21
22
  * Added 10G Ethernet interface.
23
  
24
*1/4/2019*
25
26
  * Replaced mobo/proc/RAM with parts salvaged from work. Proc i7-4790 (Haswell); RAM 32GB DDR3L.
27
28
*6/2/2018*
29
30
  * Upgraded boot drive to 500 GB SSD. Also installed Ubuntu 18.04 LTS.*
31
32
*1/16/2017*
33
34
  * Upgraded server added 2 x 3 TB additional HDDs (via PCIe SATA expansion card), new power supply, and new (slightly used) case.  After adding the new disks to the RAID and growing the file system, total usable storage on the array is now 11.18 TB.
35
36
   Parts List:
37
   ** 2 - Seagate 3TB BarraCuda SATA (ST3000DM008) 3.5-Inch Internal Hard Drive ($89.99 each)
38
   ** IO Crest SI-PEX40062 4 Port SATA III PCIe 2.0 X2 Controller Card ($37.99)
39
   ** SeaSonic G Series 550-Watt 80 PLUS GOLD Certified Modular Active PFC Power Supply SSR-550RM ($69.99)
40
   ** Corsair case (scavenged for free)
41
42
  * Instructions for adding disks, growing the array, and then growing the file system are below.
43
  
44
*11/18/2016*
45
46
  * Updated (wipe and reinstall) to Ubuntu Server 16.04.1 LTS
47
  
48
*9/2015*
49
50
   * I recently decided to pay for dynamic DNS service from "Dyn":http://dyn.com.  The cost was $30 (after 25% coupon) for a year w/ 30 hostnames. Server is now reachable at https://baranovich.homelinux.org:3268
51
   
52
*8/2014*  
53
54
 * Both of the my original 3TB HDDs started acting funny and died within a week of each other after about 1.8 years of continuous use.  Fortunately I reacted immediately and I was able to back up all of my data onto other disks. Although I regularly back up all of my critical data I decided that I really don't want to have to deal with losing any of my data.  I promptly purchased another HDD and a HW RAID card (an LSI MegaRAID SAS 9240-8i) and set out to build a RAID 5 array.  I quickly ran into problems with the RAID card.  I was only able to get the computer to boot with it installed once.  During that boot I upgraded the card's firmware with the hope that it would fix all my issues, but it did not and I was never able to fully boot with the card installed again.  After a little googling I discovered someone in my same position who claimed to have called LSI tech support and was told that LSI cards are "not compatible with newer motherboards".  The guy didn't elaborate as to what that meant but I assume it means LSI cards don't work in UEFI motherboards. I was disappointed but I started reading about software raid (device mapper raid) and decided that it should work perfectly for my little fileserver.  I also decided that btrfs is not really ready for prime time and I should use some other file system.
55
56
h2. OS Configuration
57
58 2 Redmine Admin
Current (May 2022) OS information:
59
| *Ubuntu Version:* | Ubuntu 22.04 Server LTS |
60
| *Kernel Version:* | 5.15.0-XX |
61 1
62
h2. DNS
63
64
Current hostname is: https://phalanx.homelinuxserver.org
65
66
To configure automatic DNS updates, make sure to install @ddclient@:
67
<pre>
68
$ sudo apt-get install ddclient
69
</pre>
70
Then follow instructions to log into account and select correct hostname.
71
72
h2. Network Interfaces
73
74 2 Redmine Admin
|*Interface*        | *MAC*                 | *Reserved IP*        | *Notes*  |
75
|enp4s0             |d0:50:99:51:75:a4|192.168.8.6            |primary interface gigabit|
76
|enp5s0             |d0:50:99:51:75:a5|--                             |secondary gigabit (unused)|
77
|enp1s0f0          |0c:c4:7a:1f:00:ae |10.250.1.2               |10G fiber interface|
78
|enp1s0f1          |0c:c4:7a:1f:00:af  |--                             |secondary 10G fiber (unused)|
79
|ipmi                  |bc:5f:f4:fe:6b:cb   |192.168.208.1         |IPMI interface|
80 1
81
h2. Storage Configuration 
82
83
The software RAID5 array is block device @/dev/md0@ which is mounted at @/storage@; total usable storage is about -5.5TB- 11.1TB with the current drive configuration
84
85
The primary mechanism for accessing the storage on phalanx is via NFS v4. I have found that performance is excellent (much better than samba!) and NFS is supported fairly well on both Mac OS and Linux, which are the main client OSes I use.  The only annoyance I discovered is that uids on all systems MUST match.  This is no big deal on Linux, but I had to manually change my uid on Mac OS, which was not as easy as it should have been. 
86
87
h3. Storage setup
88
89
*NOTE:* After installing Ubuntu 16.04.1 I was pleasantly surprised to discover that none of the steps below were necessary.  The software RAID had already been found and assembled for me.  The stuff below is for reference.
90
91
* Install mdadm:
92
<pre>
93
$ sudo aptitude install mdadm xfsprogs
94
</pre>
95
* For each drive (sdb, sdc, sdd):
96
<pre>
97
# parted -a optimal /dev/sdb
98
GNU Parted 2.3
99
Using /dev/sdb
100
Welcome to GNU Parted! Type 'help' to view a list of commands.
101
(parted) mklabel gpt
102
Warning: The existing disk label on /dev/sdd will be destroyed and all data on
103
this disk will be lost. Do you want to continue?
104
Yes/No? y
105
(parted) mkpart primary 0% 100%
106
(parted) align-check opt 1
107
1 aligned
108
(parted) quit
109
Information: You may need to update /etc/fstab.
110
</pre>
111
* Create the array using mdadm:
112
<pre>
113
# mdadm --create --verbose /dev/md0 --level=5 --raid-devices=3 /dev/sd[b-d]1
114
</pre>
115
* The above step takes quiet a while, about 6 hours in my case. To watch progress:
116
<pre>
117
$ watch cat /proc/mdstat
118
</pre>
119
* Once this is done you can create the XFS file system on the new @/dev/md0@ block device:
120
<pre>
121
$ sudo mkfs -t xfs -d su=512k -d sw=2 /dev/md0
122
</pre>
123
* To make sure the array reappears after reboot:
124
<pre>
125
# mdadm --examine --scan >> /etc/mdadm/mdadm.conf  # NOTE: this syntax is deprecated and no longer works!
126
# mdadm --detail --scan >> /etc/mdadm/mdadm.conf
127
# update-initramfs -u
128
</pre>
129
* If any issues arise you can stop a software RAID and reassemble it using:
130
<pre>
131
$ sudo mdadm --stop /dev/md127
132
$ mdadm --assemble /dev/md0 /dev/sdb1 /dev/sdc1 /dev/sdd1
133
</pre>
134
* To view array status:
135
<pre>
136
dsorber@phalanx:~$ sudo mdadm --detail /dev/md0
137
/dev/md0:
138
        Version : 1.2
139
  Creation Time : Fri Aug 22 17:05:41 2014
140
     Raid Level : raid5
141
     Array Size : 11720534016 (11177.57 GiB 12001.83 GB)
142
  Used Dev Size : 2930133504 (2794.39 GiB 3000.46 GB)
143
   Raid Devices : 5
144
  Total Devices : 5
145
    Persistence : Superblock is persistent
146
147
    Update Time : Fri Jan 20 16:45:45 2017
148
          State : clean 
149
 Active Devices : 5
150
Working Devices : 5
151
 Failed Devices : 0
152
  Spare Devices : 0
153
154
         Layout : left-symmetric
155
     Chunk Size : 512K
156
157
           Name : phalanx:0  (local to host phalanx)
158
           UUID : 54bfb945:47ec32da:d2ccc4db:9d3615fa
159
         Events : 4001
160
161
    Number   Major   Minor   RaidDevice State
162
       0       8       17        0      active sync   /dev/sdb1
163
       1       8       33        1      active sync   /dev/sdc1
164
       3       8       49        2      active sync   /dev/sdd1
165
       5       8       81        3      active sync   /dev/sdf1
166
       4       8       65        4      active sync   /dev/sde1
167
</pre>
168
* @/etc/fstab@
169
<pre>
170
# /etc/fstab: static file system information.
171
#
172
# Use 'blkid' to print the universally unique identifier for a
173
# device; this may be used with UUID= as a more robust way to name devices
174
# that works even if disks are added and removed. See fstab(5).
175
#
176
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
177
# / was on /dev/sda1 during installation
178
UUID=66e8057c-1b75-40ba-8ceb-480b6e4405ab /               ext4    errors=remount-ro 0       1
179
180
/dev/md0        /storage        xfs     rw,nobarrier,noatime,nodiratime 0       0
181
/storage        /export/storage    none    bind    0    0
182
</pre>
183
184
h2. Firewall Configuration
185
186 2 Redmine Admin
|*Port*|*Description*|
187 1
|22|ssh|
188
|80|http|
189
|111|SUN rpc|
190
|443|https|
191
|2049|NFS|
192
|3142|apt-cacher-ng|
193
|4045|lockd|
194
|17641|NFS connect|
195
|61993|bt|
196
197
It was a bit annoying to get NFS working when the firewall was enabled but I found some good instructions and got them to work.  The issue was that some of the important rpc/NFS daemons use random ports when they boot up.
198
199
* Edit @/etc/default/nfs-kernel-server@ comment out this line:
200
<pre>
201
RPCMOUNTDOPTS=--manage-gids
202
</pre>
203
 add this line
204
<pre>
205
RPCMOUNTDOPTS="--port 17641"
206
</pre>
207
* Edit/create @/etc/modprobe.d/options.conf@:
208
<pre>
209
options lockd nlm_udpport=4045 nlm_tcpport=4045
210
</pre>
211
* Edit @/etc/modules@ and add @lockd@ on its own line:
212
<pre>
213
...
214
lockd
215
</pre>
216
* Now create the firewall rules (only allow incoming access for the local network), for each port in the table above:
217
<pre>
218 2 Redmine Admin
$ sudo ufw allow from 192.168.8.0/24 to any port <PORT>
219 1
</pre>
220
* Add external allow rules (i.e. up these ports to the outside world) for ssh, https, and bt :
221
<pre>
222
$ sudo ufw allow <PORT>
223
</pre>
224
* Start ufw:
225
<pre>
226
$ sudo ufw enable
227
</pre>
228
Overview of added rules:
229
<pre>
230
sudo ufw allow proto tcp to 0.0.0.0/0 port 22
231
sudo ufw allow proto tcp to 0.0.0.0/0 port 443
232
sudo ufw allow proto tcp to 0.0.0.0/0 port 61993
233
234
sudo ufw allow from 192.168.4.0/24 to any port 111
235
sudo ufw allow from 192.168.4.0/24 to any port 2049
236
sudo ufw allow from 192.168.4.0/24 to any port 4045
237
sudo ufw allow from 192.168.4.0/24 to any port 17641
238
239
sudo ufw allow from 192.168.8.0/24 to any port 111
240
sudo ufw allow from 192.168.8.0/24 to any port 2049
241
sudo ufw allow from 192.168.8.0/24 to any port 4045
242
sudo ufw allow from 192.168.8.0/24 to any port 17641
243
244 2 Redmine Admin
sudo ufw allow from 10.250.1.0/24 to any port 111
245
sudo ufw allow from 10.250.1.0/24 to any port 2049
246
sudo ufw allow from 10.250.1.0/24 to any port 4045
247
sudo ufw allow from 10.250.1.0/24 to any port 17641
248
</pre>
249 1
250 2 Redmine Admin
h2. NFS setup:
251
252
* Install NFS (note be sure to configure the firewall first):
253
<pre>
254
$ sudo apt install nfs-kernel-server
255 1
</pre>
256 2 Redmine Admin
* Edit @/etc/exports@:
257
<pre>
258
/storage    192.168.8.0/24(rw,nohide,insecure,no_subtree_check,async)
259
/storage    192.168.4.0/24(rw,nohide,insecure,no_subtree_check,async)
260 1
261 2 Redmine Admin
/storage    10.250.1.0/24(rw,nohide,insecure,no_subtree_check,async)
262
</pre>
263
* Restart NFS:
264
<pre>
265
$ sudo systemctl restart nfs-kernel-server
266
</pre>
267
* Export filesystems:
268
<pre>
269
$ sudo exportfs
270
</pre>
271 1
272
h2. Apache
273
274 2 Redmine Admin
I didn't originally document my Apache setup, but when wiping to install 14.04 I remedied this. The Apache configs (see repo), are the really important part here. Below is a section on each application that's running on/from Apache.  I am using https with a permanent redirect from port 80 along with a self-signed certificate.  Most of the sections below are password protected using mod_auth_digest.  The appropriate digest file is created and managed with the "htdigest":http://httpd.apache.org/docs/2.2/programs/htdigest.html tool. *NOTE:* make sure the password digest file (e.g. @/home/dsorber/web_users@) is owned by @www-data:www-data@ and permissions are set to @600@.
275 1
276
* Install apache2 itself:
277
<pre>
278 2 Redmine Admin
$ sudo apt install apache2
279 1
</pre>
280
* Enable apache modules:
281
<pre>
282
$ sudo a2enmod ssl proxy proxy_http auth_digest
283
</pre>
284
* Copy backed up apache configs to their location:
285
<pre>
286
$ sudo cp apache_configs/* /etc/apache2/sites-available/
287
</pre>
288
* Setup SSL cert:
289
<pre>
290
cd /etc/apache2
291
sudo mkdir ssl
292 2 Redmine Admin
sudo cp phalanx.{crt,key} /etc/apache2/ssl
293 1
</pre>
294
* Turn on main site (also disable default apache2 site):
295
<pre>
296
$ sudo a2ensite main
297
</pre>
298
299
h3. Transmission
300
301 2 Redmine Admin
I use "Transmission":http://www.transmissionbt.com/ to download Linux .isos and give back to the community by sharing them using my own bandwidth. Transmission with its webui runs as a separate daemon so apache is configured to act as reverse proxy.
302 1
303 2 Redmine Admin
Transmission has its own configuration file: @settings.json@.
304 1
305
* Install transmission daemon:
306
<pre>
307 2 Redmine Admin
$ sudo apt install transmission-daemon
308 1
</pre>
309
* Copy over configuration:
310
<pre>
311
$ sudo systemctl stop transmission-daemon.service
312
$ sudo cp settings.json /etc/transmission-daemon
313
$ sudo systemctl start transmission-daemon.service
314
</pre>
315 2 Redmine Admin
* Make sure the user digest file is in place (NOTE: be sure to change use directory permissions to 755 or Apache will not be able to read the web_users file):
316 1
<pre>
317
$ cd /home/dsorber
318
$ cp web_users .
319 2 Redmine Admin
$ cd /home
320
$ sudo chmod 755 dsorber
321 1
</pre>
322
* Enable site:
323
<pre>
324
$ sudo a2ensite transmission
325
</pre>
326
327 2 Redmine Admin
h3. Redmine + Git
328 1
329 2 Redmine Admin
Unfortunately Trac completely stagnated and never completed moving to Python 3. Therefore I switched to Redmine + Git which (at least as of now) is still maintained.  Note the following uses PostgresQL for the backend database (which is also used for nextcloud).
330 1
331 2 Redmine Admin
# Install prereqs:
332 1
<pre>
333 2 Redmine Admin
 $ sudo apt install apache2 pbzip2 zip unzip postgresql libpq-dev build-essential ruby ruby-dev
334 1
</pre>
335 2 Redmine Admin
# Download Redmine:
336 1
<pre>
337 2 Redmine Admin
$ cd /srv/
338
$ sudo wget https://www.redmine.org/releases/redmine-5.0.1.tar.gz
339
$ sudo tar xf redmine-5.0.1.tar.gz
340
$ sudo mv redmine-5.0.1 redmine
341
$ sudo chown -R root:root redmine
342 1
</pre>
343 2 Redmine Admin
# Setup postgres database for Redmine:
344 1
<pre>
345 2 Redmine Admin
$ sudo -u postgres psql postgres
346
> CREATE ROLE redmine LOGIN ENCRYPTED PASSWORD 'password_goes_here' NOINHERIT VALID UNTIL 'infinity';
347
> CREATE DATABASE redmine WITH ENCODING='UTF8' OWNER=redmine;
348
Ctrl+D
349 1
</pre>
350 2 Redmine Admin
# Install bundle and dependencies:
351 1
<pre>
352 2 Redmine Admin
$ sudo gem install bundler
353
$ cd /srv/redmine
354
$ sudo bundle config set --local without 'development test'
355
$ sudo bundle install 
356 1
</pre>
357 2 Redmine Admin
# Configure Redmine database:
358 1
<pre>
359 2 Redmine Admin
$ sudo rake generate_secret_token
360
$ sudo RAILS_ENV=production rake db:migrate
361
$ sudo RAILS_ENV=production rake redmine:load_default_data
362 1
</pre>
363 2 Redmine Admin
# Configure permissions:
364
<pre>
365
$ sudo chown -R www-data:www-data files log tmp public/plugin_assets
366
$ sudo chmod -R 755 files log tmp public/plugin_assets
367
</pre>
368
# Setup webserver:
369
<pre>
370
$ sudo chown www-data:www-data /srv/redmine/config/environment.rb
371
$ sudo ln -s /srv/redmine/public /var/www/redmine
372
</pre>
373
# Install Passenger:
374
<pre>
375
$ sudo apt install libcurl4-openssl-dev libssl-dev apache2-dev libapr1-dev libaprutil1-dev zlib1g-dev
376
$ sudo gem install passenger
377
$ sudo passenger-install-apache2-module (follow instructions)
378
$ sudo vim /etc/apache2/mods-available/passenger.load
379
-------------------------------------------------------------------------------
380
LoadModule passenger_module /var/lib/gems/3.0.0/gems/passenger-6.0.14/buildout/apache2/mod_passenger.so
381
-------------------------------------------------------------------------------
382 1
383 2 Redmine Admin
$ sudo vim /etc/apache2/mods-available/passenger.conf
384
-------------------------------------------------------------------------------
385
  <IfModule mod_passenger.c>
386
     PassengerRoot /var/lib/gems/3.0.0/gems/passenger-6.0.14
387
     PassengerDefaultRuby /usr/bin/ruby3.0
388
   </IfModule>
389
-------------------------------------------------------------------------------
390
391
$ sudo a2enmod passenger
392
$ sudo systemctl restart apache2
393
</pre>
394
# Setup Apache config. Note the Redmine section is now included in @main.conf@ and should be commented out until this step is reached.
395
# Install theme(s):
396 1
<pre>
397 2 Redmine Admin
$ cd /srv/redmine/public/themes
398
$ git clone https://github.com/koppen/redmine-pepper-theme.git
399
$ git clone https://github.com/makotokw/redmine-theme-gitmike
400 1
</pre>
401
402 2 Redmine Admin
h3. Git Integration
403
404
# Install prereqs:
405
<pre>
406
$ sudo apt install libapache2-mod-perl2 libdbi-perl libdbd-pg-perl
407
</pre>
408
# Configure:
409
<pre>
410
$ sudo ln -s /srv/redmine/extra/svn/Redmine.pm /usr/lib/x86_64-linux-gnu/perl5/5.34/Apache2/Redmine.pm
411
$ sudo a2enmod perl dav dav_fs
412
</pre>
413
# Setup git repo. Note if using an existing repo then just copy it into path: @/srv/git@
414
<pre>
415
$ sudo mkdir -p /srv/git
416
$ cd /srv
417
$ sudo chown -R dsorber:dsorber git
418
(optional used to test below)
419
$ cd git 
420
$ mkdir test; cd test
421
 $ git init --bare
422
</pre>
423
# Setup grack:
424
<pre>
425
$ cd /var/www
426
$ sudo git clone https://github.com/grackorg/grack.git
427
$ sudo vim grack/config.ru
428
-------------------------------------------------------------------------------
429
require 'grack/app'
430
require 'grack/git_adapter'
431
432
config = {
433
  :root => '/srv/git',
434
  :allow_push => true,
435
  :allow_pull => true,
436
  :git_adapter_factory => ->{ Grack::GitAdapter.new }
437
}
438
439
run Grack::App.new(config)
440
441
-------------------------------------------------------------------------------
442
443
$ sudo chown -R www-data:www-data grack
444
$ cd /var/www/grack
445
$ sudo mkdir public
446
$ sudo mkdir tmp
447
$ sudo chown -R www-data:www-data .
448
$ sudo bundle install
449
</pre>
450
# Configure apache. Note a separate Apache config @git.conf@ exists for this step. Copy it into place and enable:
451
<pre>
452
$ sudo a2ensite git 
453
$ sudo systemctl restart apache2
454
</pre>
455
456 1
h3. Nextcloud
457
458 2 Redmine Admin
"Nextcloud":https://nextcloud.com/|Nextcloud is a self-hosted "cloud". It allows easy file viewing and sharing as well as CardDav and CalDav servers:
459 1
460 2 Redmine Admin
# Install prereqs:
461 1
<pre>
462 2 Redmine Admin
$ sudo apt install apache2 libapache2-mod-php php-gd php-pgsql php-curl php-mbstring php-intl php-gmp php-bcmath php-xml php-imagick php-zip
463 1
</pre>
464 2 Redmine Admin
# Download and move into place:
465 1
<pre>
466 2 Redmine Admin
$ wget https://download.nextcloud.com/server/releases/latest.tar.bz2
467
$ tar xf latest.tar.bz2
468
$ sudo mv nextcloud /var/www/nextcloud
469
$ cd /var/www
470
$ sudo chown -R www-data:www-data nextcloud
471 1
</pre>
472 2 Redmine Admin
# Config database (use postgresql; same as redmine):
473 1
<pre>
474 2 Redmine Admin
$ sudo -u postgres psql postgres
475
> CREATE ROLE nextcloud LOGIN ENCRYPTED PASSWORD 'password_goes_here' NOINHERIT VALID UNTIL 'infinity';
476
> CREATE DATABASE nextcloud WITH ENCODING='UTF8' OWNER=nextcloud;
477
Ctrl+D
478 1
</pre>
479 2 Redmine Admin
# Setup Apache config. Note the Redmine section is now included in @main.conf@ and should be commented out until this step is reached.
480 1
<pre>
481
$ sudo a2enmod rewrite headers env dir mime
482 2 Redmine Admin
$ sudo vim /etc/apache2/envvars
483
-------------------------------------------------------------------------------
484
## Uncomment the following line to use the system default locale instead:
485
486
#. /etc/default/local here
487
-------------------------------------------------------------------------------
488
489 1
$ sudo systemctl restart apache2
490
</pre>
491 2 Redmine Admin
# Complete configuration by navigating to https://phalanx.homelinuxserver.org/nextcloud in a web browser and following the instructions.
492 1
493
h4. Other configuration
494
495
* To setup local storage: go to Apps > Disabled Apps > External Storage (click Enable)
496
* To setup pretty URLS:
497
 * https://docs.nextcloud.com/server/13/admin_manual/installation/source_installation.html#pretty-urls
498
 * <pre> $ sudo vim /var/www/nextcloud/config/config.php </pre>
499
 * <pre> $ sudo systemctl restart apache2 </pre>
500
501
h2. Misc
502 2 Redmine Admin
503 1
* Setup the display script:
504
 * Edit @~/.profile@ and add @./repo/software/misc/display.py@
505
* Setup checker script:
506
 * 
507
<pre>
508
$ sudo su
509
# crontab -e
510
</pre>
511
 add this line:
512
<pre>
513
0 * * * *       /home/dsorber/repo/software/misc/checker.py
514
</pre>
515
* Install @apt-cacher-ng@:
516
<pre>
517
$ sudo apt install apt-cacher-ng
518
</pre>
519
 * Edit @/etc/apt/apt.conf.d/02proxy@ add: @Acquire::http::Proxy "http://192.168.8.6:3142";@
520
521
----
522
523
h3. Sources
524
525
* "Adding an extra disk to an mdadm array":http://zackreed.me/adding-an-extra-disk-to-an-mdadm-array/
526
* https://raid.wiki.kernel.org/index.php/Growing
527
* "Ubuntu Setting Up NFS HowTo":https://help.ubuntu.com/community/SettingUpNFSHowTo
528
* http://ubuntuforums.org/showthread.php?t=2228292
529
* http://www.mysolutions.it/tutorial-mdadm-software-raid-ubuntu-debian-systems/
530
* http://ubuntuforums.org/showpost.php?p=7959294&postcount=17
531
* http://trac.edgewall.org/wiki/TracModWSGI
532
* "Pro Git":http://git-scm.com/book
533
* http://baikal-server.com/
534
* https://github.com/jeromeschneider/Baikal
535
* https://easyengine.io/tutorials/linux/ubuntu-postfix-gmail-smtp/
536
* https://wiki.archlinux.org/index.php/Btrfs
537
* https://blog.packagecloud.io/eng/2015/05/05/using-apt-cacher-ng-with-ssl-tls/