# Algemeen

Onderwerpen wat van toepassing zijn voor iedere gehoste applicatie.

# De lokale e-mailserver

Op iedere beheerde applicatie-server is een SMTP mailserver geïnstalleerd waardoor de applicatie e-mails kan versturen (niet ontvangen). In dit artikel leggen we uit hoe je deze mailserver kan gebruiken.

## Configuratie van je applicatie

In je gehoste applicatie kan je onderstaande configuratie gebruiken. De exacte locatie waar je dit in de applicatie doet, is afhankelijk van de applicatie. Kom je er niet uit, contacteer ons dan gerust.

- **Protocol**: SMTP
- **Host**: localhost
- **Poort**: 25
- **Encryptie**: geen
- **Authentificatie**: geen
- **Afzender**: email@app.jouwhostname.be

<p class="callout warning">Het e-mailadres van de afzender moet steeds binnen het subdomein van jouw applicatie vallen. Is je applicatie bijvoorbeeld bereikbaar op unifi.jouwfirma.net, dan is een gelding e-mailadres: app@unifi.jouwfirma.net.</p>

<p class="callout info">Je lokale mailserver verzendt e-mails geëncrypteerd als de ontvangende mailserver dat toestaat. Als de ontvangende mailserver niet in staat is om geëncrypteerde e-mails te ontvangen, dan zal de e-mail niet geëncrypteerd verzonden worden.</p>

### DNS aanpassing

Als het DNS records van jouw subdomein verwijst naar `CNAME clnXXX-prd-app00X.nexxwave.net`, verwijder dan dit record en vervang het door het A en AAAA record.

Het A en AAAA record van jouw applicatie server kan je achterhalen met een ping naar het adres van jouw server:

```bash
ping -4 clnXXX-prd-app00X.nexxwave.net
ping -6 clnXXX-prd-app00X.nexxwave.net
```

### SPF record aan je DNS toevoegen

SPF is een schakel in de strijd tegen spoofing. Voor meer informatie over SPF, [zie Wikipedia](https://en.wikipedia.org/wiki/Sender_Policy_Framework). Afhankelijk hoe de SPF instellingen voor jouw domeinnaam ingesteld zijn, is het al dan niet noodzakelijk om je applicatie-server in je SPF record te vermelden. Wij raden aan om je applicatie-server steeds in je SPF record op te nemen.

Je applicatie is bereikbaar over zowel IPv4 als IPv6. Je lokale mailserver zal e-mails over beide protocollen versturen, dus het is noodzakelijk om zowel het IPv4 als het IPv6 adres in je SPF record op te nemen. Beide IP-adressen kan je eenvoudig achterhalen door een ping te sturen naar je applicatie-server. Bijvoorbeeld:

```bash
ping -4 clnXXX-prd-app00X.nexxwave.net
ping -6 clnXXX-prd-app00X.nexxwave.net
```

Beide IP-adressen voeg je vervolgens aan je SPF record toe als `ip4:` en `ip6:`. Een geldig SPF record zou bijvoorbeeld kunnen zijn:

`v=spf1 a ip4:233.252.0.1 ip6:2001:db8::1 include:_spf.google.com ~all`

### DKIM record aan je DNS toevoegen

Ook DKIM is een schakel in de strijd tegen spoofing, zie [Wikipedia](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) voor meer informatie over DKIM. Om een geldige DKIM controle kunnen uit te voeren, moet er een publieke DKIM key als TXT record toegevoegd worden. Dit is een unieke key per server. [Contacteer ons](mailto:help@nexxwave.be) zodat we jou deze key kunnen bezorgen.

Heb je de key ontvangen? Voeg deze dan toe als een TXT record met als host `nexx.domainkey.app.jouwhostname.be` en met als waarde de key die je via e-mail ontvangen hebt. Bijvoorbeeld:

[![image.png](https://docs.nexxwave.be/uploads/images/gallery/2023-09/scaled-1680-/Gw39bO7gNfsZEH2Y-image.png)](https://docs.nexxwave.be/uploads/images/gallery/2023-09/Gw39bO7gNfsZEH2Y-image.png)

## Een eigen SMTP server gebruiken

Wil je dat je applicatie e-mails via een eigen SMTP server verzendt, dan kan je dat zelf in de applicatie aanpassen. Wanneer een applicatie niet toelaat om SMTP instellingen aan te passen, neem dan [contact](https://www.nexxwave.be/contact) met ons op zodat we dit voor jou kunnen instellen.

# Gepland onderhoud en updates

Wij onderhouden de server waarop jouw applicatie draait. Daarvoor is het noodzakelijk dat we je server en de applicatie regelmatig updaten.

## Updates van het besturingssysteem

Iedere week installeren we alle beschikbare updates van het besturingssysteem. Dit doen we steeds op maandagochtend tussen 05:00u en 07:00u. Wanneer de update een herstart van de server vereist, dan volgt deze herstart direct na het installeren van de updates. Een herstart is meestal enkel noodzakelijk wanneer bijvoorbeeld de Linux kernel geupdate werd.

Van deze updates merk je meestal niets; met uitzondering dat je applicatie enkele minuten niet bereikbaar zal zijn wanneer de server herstart moet worden.

## Updates van de applicatie

De ontwikkelaar van je applicatie brengt ook regelmatig updates uit met als doel het toevoegen van nieuwe functionaliteit of het oplossen van bugs. We installeren deze applicatie updates steeds op maandagochtend tussen 07:00u en 09:00u.

Tijdens deze update zal je applicatie niet bereikbaar zijn. Meestal duurt dit slechts 5 tot 10 minuten.

### Communicatie van applicatie updates

Minstens een week op voorhand brengen we je via e-mail op de hoogte dat er een update zal plaatsvinden van de applicatie wat je gebruikt. Zo kan je eventueel je gebruikers tijdig op de hoogte brengen. We geven dan ook steeds mee naar welke versie er geupdate zal worden en wat de wijzigingen in die versie zijn.

## Dringende veiligheidsupdates

Wanneer in een applicatie of in het besturingssysteem een kwetsbaarheid ontdekt wordt, dan moet die zo spoedig mogelijk gedicht worden. Dan zullen we daarvoor - onafhankelijk van de dag - een updatemoment voor inlassen. We trachten dit alsnog steeds in de vroege ochtend te plannen.

# Meldingen van applicatie updates

Wanneer de ontwikkelaar een update uitbrengt van zijn applicatie wat jij gebruikt, dan installeren we deze zo spoedig mogelijk. Zie [deze pagina](https://docs.nexxwave.be/books/algemeen/page/gepland-onderhoud-en-updates "Gepland onderhoud en updates") met alle informatie over de updatemomenten van je server en applicatie.

## Het versienummer ontleed

Alle applicaties hebben een versienummer. Dit versienummer bestaat uit drie elementen gescheiden door een punt, zoals bijvoorbeeld 24.8.13. Het eerste element geeft het 'major' level aan, het tweede element het 'minor' level en het derde element het 'patch' level, dus MAJOR.MINOR.PATCH.

- Een verhoging van het '**major**' element wijst op zeer grote wijzigingen die mogelijks niet compatibel zijn met de vorige versie en waarvoor mogelijks configuratiewijzigingen nodig zijn.
- Een verhoging van het '**minor**' element wijst op toevoegingen en wijzigingen van functionaliteiten in de applicatie, maar die wel nog compatibel zijn met voorgaande versies.
- Een verhoging van het '**patch**' element wijst op het oplossen van bugs.

<p class="callout info">Dit type van versienummering heet 'Semantic Versioning'. Wil je daar meer informatie over, neem dan een kijkje op [semver.org](https://www.semver.org).</p>

## Het updateproces

Wanneer van een applicatie een update wordt uitgebracht, dan installeren we deze eerst op een testserver. Als we geen problemen opmerken, dan installeren we de update tijdens [een onderhoudsvenster](https://docs.nexxwave.be/books/algemeen/page/gepland-onderhoud-en-updates "Gepland onderhoud en updates") op alle beheerde applicatie-servers.

## Update meldingen via e-mail

Wanneer een applicatie een update krijgt waarbij het 'major' of het 'minor' element verhoogt wordt, dan sturen we jou een week op voorhand via e-mail als berichtgeving dat de applicatie op jouw server geupdate zal worden. We geven dan ook mee welke wijzigingen er van toepassing zijn en welke stappen jij eventueel moet ondernemen als voorbereiding op of na de update.

Wanneer de ontwikkelaar een 'patch' update uitbrengt, dan testen we de update maar we sturen hiervoor geen e-mail.

# Technische specificaties van de servers

Onze applicaties bieden we aan in de pakketten 'standard' en 'plus'. De applicatie heeft in beide pakketten steeds exact dezelfde functionaliteit. Het verschil in beide pakketten zit in de hardware specificaties van de server.

## Upgraden en downgraden

### Upgraden

Wanneer je bij het bestelproces bijvoorbeeld gekozen hebt voor een 'Standard' pakket, dan kan je dit steeds laten upgraden naar een 'Plus' pakket. Dit kan noodzakelijk zijn om bijvoorbeeld meer processor-kracht of meer RAM geheugen kunnen in te zetten, of om de opslagruimte te verhogen.

### Downgraden

Als een server bijvoorbeeld van het 'Standard' naar het 'Plus' pakket wordt geupgrade, dan heb je de keuze om enkel de processor (CPU) en het RAM-geheugen te upgraden, of ook de opslagruimte. Wanneer enkel processor en het RAM-geheugen geupgrade wordt, dan kan in de toekomst steeds een downgrade naar het 'Standard' pakket gebeuren. Wanneer ook de opslagruimte geupgrade werd, dan is een downgrade niet meer mogelijk.

## Algemene specificaties

Onze virtuele machines worden gehost op servers waarbij de processor en het RAM-geheugen gedeeld worden met andere virtuele machines. Op aanvraag is het mogelijk om dedicated vCPU's te gebruiken.

- **Processor**: de exacte CPU GHz kan verschillen, maar zal steeds minimaal 2GHz bedragen. Als processor wordt steeds een AMD EPYC 2nd Gen of een Intel® Xeon® Gold gebruikt (1 vCPU = 1 hyper-thread).
- **RAM-geheugen**: het geheugen is steeds ECC-geheugen.
- **Opslagruimte**: lokale NVMe SSD's op RAID10.
- **IP-adressen**: er wordt steeds 1 IPv4 en 1 IPv6 adres voorzien. Extra IPv4 adressen zijn tegen extra kost verkrijgbaar. Extra IPv6 adressen worden kosteloos toegewezen moest dit noodzakelijk zijn.
- **Netwerk**: de server is met een redundante verbinding verbonden met het internet. De netwerksnelheid kan wisselen naar gelang de drukte op dat moment van de dag.

## Specificaties van de servers

In [dit overzicht](https://www.nexxwave.be/app-hosting/specificaties) vind je een beschrijving van de exacte server specificaties per applicatie en per pakket.

## Benchmarks

Onderstaande benchmarks werden uitgevoerd op een virtuele server met 2 vCPU's en 4 GB RAM-geheugen. Als besturingssysteem gebruikten we Debian 11.3 met Linux kernel 5.10.0-14.

### Opslagruimte

Om benchmarks op de opslagruimte uit te voeren, gebruikte we fio versie 3.25.

#### Write

We schreven 2GB (4 jobs van 512MB):

```shell
sudo fio --name=randwrite --ioengine=libaio --iodepth=1 --rw=randwrite --bs=4k --direct=0 --size=512M --numjobs=4 --runtime=240 --group_reporting
```

Dat gaf dit resultaat:

```
randwrite: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
...
fio-3.25
Starting 4 processes
randwrite: Laying out IO file (1 file / 512MiB)
randwrite: Laying out IO file (1 file / 512MiB)
randwrite: Laying out IO file (1 file / 512MiB)
randwrite: Laying out IO file (1 file / 512MiB)
Jobs: 4 (f=4): [w(4)][100.0%][w=201MiB/s][w=51.5k IOPS][eta 00m:00s]
randwrite: (groupid=0, jobs=4): err= 0: pid=738: Tue May 24 09:39:54 2022
  write: IOPS=59.0k, BW=234MiB/s (246MB/s)(2048MiB/8742msec); 0 zone resets
    slat (usec): min=2, max=45198, avg=60.91, stdev=1030.00
    clat (nsec): min=678, max=12025k, avg=1918.96, stdev=45729.60
     lat (usec): min=3, max=45232, avg=63.07, stdev=1031.60
    clat percentiles (nsec):
     |  1.00th=[   700],  5.00th=[   708], 10.00th=[   732], 20.00th=[   844],
     | 30.00th=[   892], 40.00th=[  1020], 50.00th=[  1224], 60.00th=[  1496],
     | 70.00th=[  1784], 80.00th=[  1960], 90.00th=[  2128], 95.00th=[  2512],
     | 99.00th=[  4128], 99.50th=[  8096], 99.90th=[ 43264], 99.95th=[ 71168],
     | 99.99th=[897024]
   bw (  KiB/s): min=121592, max=1116624, per=100.00%, avg=250840.24, stdev=59610.23, samples=65
   iops        : min=30398, max=279155, avg=62709.69, stdev=14902.51, samples=65
  lat (nsec)   : 750=13.10%, 1000=26.08%
  lat (usec)   : 2=46.14%, 4=13.63%, 10=0.68%, 20=0.18%, 50=0.11%
  lat (usec)   : 100=0.06%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
  lat (msec)   : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%
  cpu          : usr=4.91%, sys=14.09%, ctx=5271, majf=0, minf=57
  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=0,524288,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):
  WRITE: bw=234MiB/s (246MB/s), 234MiB/s-234MiB/s (246MB/s-246MB/s), io=2048MiB (2147MB), run=8742-8742msec

Disk stats (read/write):
  sda: ios=0/126694, merge=0/845, ticks=0/232652, in_queue=232655, util=93.89%
```

#### Read

We lazen 2GB (4 jobs van 512MB):

```shell
sudo fio --name=randread --ioengine=libaio --iodepth=16 --rw=randread --bs=4k --direct=0 --size=512M --numjobs=4 --runtime=240 --group_reporting
```

Dat gaf dit resultaat:

```
randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=16
...
fio-3.25
Starting 4 processes
randread: Laying out IO file (1 file / 512MiB)
randread: Laying out IO file (1 file / 512MiB)
randread: Laying out IO file (1 file / 512MiB)
randread: Laying out IO file (1 file / 512MiB)
Jobs: 1 (f=1): [_(3),r(1)][100.0%][r=10.0MiB/s][r=2561 IOPS][eta 00m:00s]
randread: (groupid=0, jobs=4): err= 0: pid=748: Tue May 24 09:41:17 2022
  read: IOPS=13.8k, BW=54.0MiB/s (56.6MB/s)(2048MiB/37921msec)
    slat (usec): min=72, max=26831, avg=251.53, stdev=224.41
    clat (usec): min=3, max=31309, avg=3850.84, stdev=1376.21
     lat (usec): min=122, max=34147, avg=4102.97, stdev=1444.32
    clat percentiles (usec):
     |  1.00th=[ 2278],  5.00th=[ 2474], 10.00th=[ 2638], 20.00th=[ 2868],
     | 30.00th=[ 3097], 40.00th=[ 3294], 50.00th=[ 3523], 60.00th=[ 3818],
     | 70.00th=[ 4178], 80.00th=[ 4686], 90.00th=[ 5407], 95.00th=[ 5932],
     | 99.00th=[ 7832], 99.50th=[10683], 99.90th=[17695], 99.95th=[20055],
     | 99.99th=[30278]
   bw (  KiB/s): min=51280, max=74928, per=100.00%, avg=63027.97, stdev=1396.04, samples=267
   iops        : min=12820, max=18732, avg=15756.93, stdev=348.99, samples=267
  lat (usec)   : 4=0.01%, 10=0.01%, 250=0.01%, 500=0.01%, 750=0.01%
  lat (usec)   : 1000=0.01%
  lat (msec)   : 2=0.01%, 4=65.45%, 10=33.98%, 20=0.51%, 50=0.05%
  cpu          : usr=2.90%, sys=12.02%, ctx=525101, majf=0, minf=110
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.0%, 32=0.0%, >=64=0.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%
     issued rwts: total=524288,0,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=16

Run status group 0 (all jobs):
   READ: bw=54.0MiB/s (56.6MB/s), 54.0MiB/s-54.0MiB/s (56.6MB/s-56.6MB/s), io=2048MiB (2147MB), run=37921-37921msec

Disk stats (read/write):
  sda: ios=524118/50, merge=0/17, ticks=117035/17, in_queue=117053, util=99.86%
```

#### Random read/write

```shell
sudo fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --name=test --filename=random_read_write.fio --bs=4k --iodepth=64 --size=4G --readwrite=randrw --rwmixread=75
```

Dat gaf dit resultaat:

```
test: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=64
fio-3.25
Starting 1 process
test: Laying out IO file (1 file / 4096MiB)
Jobs: 1 (f=1): [m(1)][100.0%][r=151MiB/s,w=49.8MiB/s][r=38.6k,w=12.8k IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=756: Tue May 24 09:42:30 2022
  read: IOPS=36.9k, BW=144MiB/s (151MB/s)(3070MiB/21303msec)
   bw (  KiB/s): min=119000, max=179816, per=99.98%, avg=147538.93, stdev=13675.43, samples=42
   iops        : min=29750, max=44954, avg=36884.69, stdev=3418.87, samples=42
  write: IOPS=12.3k, BW=48.2MiB/s (50.5MB/s)(1026MiB/21303msec); 0 zone resets
   bw (  KiB/s): min=39736, max=59872, per=99.99%, avg=49313.76, stdev=4497.26, samples=42
   iops        : min= 9934, max=14968, avg=12328.38, stdev=1124.17, samples=42
  cpu          : usr=18.04%, sys=47.15%, ctx=24982, majf=0, minf=7
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=0.1%, >=64=100.0%
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.1%, >=64=0.0%
     issued rwts: total=785920,262656,0,0 short=0,0,0,0 dropped=0,0,0,0
     latency   : target=0, window=0, percentile=100.00%, depth=64

Run status group 0 (all jobs):
   READ: bw=144MiB/s (151MB/s), 144MiB/s-144MiB/s (151MB/s-151MB/s), io=3070MiB (3219MB), run=21303-21303msec
  WRITE: bw=48.2MiB/s (50.5MB/s), 48.2MiB/s-48.2MiB/s (50.5MB/s-50.5MB/s), io=1026MiB (1076MB), run=21303-21303msec

Disk stats (read/write):
  sda: ios=778983/260325, merge=0/35, ticks=829618/263407, in_queue=1093033, util=99.67%
```

### Netwerk

We voerden een speedtest uit vanaf een server in Falkenstein naar een server in Rosenheim (speedtest server ID 37516).

```shell
speedtest
```

Dat gaf dit resultaat:

```
Testing from Hetzner Online GmbH (168.119.178.2)...
Retrieving speedtest.net server list...
Retrieving information for the selected server...
Hosted by Komro GmbH (Rosenheim) [428.19 km]: 18.881 ms
Testing download speed............................................
Download: 1200.87 Mbit/s
Testing upload speed..............................................
Upload: 1046.51 Mbit/s
```

## Processor

We voerden een sysbench test uit met versie 1.0.20.

```shell
sysbench cpu --threads=2 run
```

Dat gaf dit resultaat:

```
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 2
Initializing random number generator from current time


Prime numbers limit: 10000

Initializing worker threads...

Threads started!

CPU speed:
    events per second:  1807.14

General statistics:
    total time:                          10.0006s
    total number of events:              18077

Latency (ms):
         min:                                    1.04
         avg:                                    1.10
         max:                                   12.67
         95th percentile:                        1.27
         sum:                                19974.38

Threads fairness:
    events (avg/stddev):           9038.5000/2.50
    execution time (avg/stddev):   9.9872/0.00
```

## Geheugen

We voerden een sysbench test uit met versie 1.0.20.

```shell
sysbench memory --threads=2 run
```

Dat gaf dit resultaat:

```
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 2
Initializing random number generator from current time


Running memory speed test with the following options:
  block size: 1KiB
  total size: 102400MiB
  operation: write
  scope: global

Initializing worker threads...

Threads started!

Total operations: 42084784 (4207444.09 per second)

41098.42 MiB transferred (4108.83 MiB/sec)


General statistics:
    total time:                          10.0004s
    total number of events:              42084784

Latency (ms):
         min:                                    0.00
         avg:                                    0.00
         max:                                    6.04
         95th percentile:                        0.00
         sum:                                13791.29

Threads fairness:
    events (avg/stddev):           21042392.0000/15556.00
    execution time (avg/stddev):   6.8956/0.01
```