EQVPS
DashboardAan de slag

MySQL installeren op een VPS: gebruikers, veilige toegang op afstand, minder RAM en back-ups

Installeer MySQL 8.0 op een Ubuntu 24.04-VPS, maak een database en een app-gebruiker aan, bereik hem vanaf je computer zonder poort 3306 te openen, verlaag het geheugen in rust van 383 MB naar 165 MB en maak elke nacht een back-up met een script dat luid faalt.

MySQL installeren is één commando. Het meeste werk komt daarna: een app-gebruiker, een manier om vanaf je computer bij de database te komen zonder poort 3306 op internet te zetten, geheugeninstellingen voor een kleine server en back-ups die zonder jou draaien. Deze handleiding behandelt alle vier op Ubuntu 24.04. Elke stap is uitgevoerd op onze Ubuntu 24.04-image, en de cijfers hieronder komen van die server.

Voer de commando's uit als gebruiker met sudo. De Ubuntu-installatiehandleiding maakt er een aan.

1. Installeren

sudo apt update
sudo apt install -y mysql-server
mysql --version

De installatie duurde op onze server 51 seconden en leverde MySQL 8.0.46 op. Het start meteen, start bij elke boot opnieuw en luistert alleen op de server zelf: 127.0.0.1:3306 voor gewone verbindingen en 127.0.0.1:33060 voor het nieuwere X-protocol van MySQL. Van buitenaf is nog niets bereikbaar.

2. Maak een database en een gebruiker aan

Het root-account van MySQL gebruikt op Ubuntu socket-authenticatie, dus sudo mysql logt je in zonder wachtwoord. Maak een database en een gebruiker voor je app aan:

sudo mysql
CREATE DATABASE app CHARACTER SET utf8mb4;
CREATE USER 'app'@'localhost' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'localhost';
EXIT;

Test het zoals je app gaat verbinden:

mysql -u app -p app -e "SELECT CURRENT_USER();"

Dit hoort app@localhost te tonen. Een verkeerd wachtwoord levert ERROR 1045 (28000): Access denied for user 'app'@'localhost' op. De gebruiker mag alles binnen app en niets daarbuiten.

3. Verbinden vanaf je computer: SSH-tunnel

Om een desktopclient als DBeaver, MySQL Workbench of de mysql-commandoregel op je eigen machine te gebruiken, open je geen poort. Stuur er een door via SSH:

ssh -L 3307:127.0.0.1:3306 deploy@YOUR.SERVER.IP

Op een NAT-pakket voeg je -p en de persoonlijke SSH-poort uit je dashboard toe. Zolang dat venster openstaat, richt je je client op host 127.0.0.1, poort 3307, gebruiker app. Lokaal namen we 3307, zodat het niet botst met een MySQL die je misschien op je eigen computer draait. In onze test antwoordde de server meteen via de tunnel, terwijl een directe verbinding met zijn adres op 3306 werd geweigerd.

4. Directe toegang voor één andere server

Soms draait de app op een tweede server en moet die direct verbinden. Daarvoor heeft de database een pakket met eigen IPv4 nodig, want een NAT-pakket stuurt alleen je SSH-poort door. Drie wijzigingen, allemaal beperkt tot het adres van de app-server (hier 203.0.113.20):

sudo sed -i 's/^bind-address.*/bind-address = 0.0.0.0/' /etc/mysql/mysql.conf.d/mysqld.cnf
sudo systemctl restart mysql
sudo ufw allow from 203.0.113.20 to any port 3306 proto tcp
CREATE USER 'app'@'203.0.113.20' IDENTIFIED BY 'a-long-random-password';
GRANT ALL PRIVILEGES ON app.* TO 'app'@'203.0.113.20';

Staat ufw nog niet aan, sta dan eerst SSH toe (sudo ufw allow OpenSSH) en voer daarna sudo ufw enable uit. De ufw-handleiding heeft de details.

We hebben beide sloten apart gecontroleerd. Met de firewallregel maar zonder passende MySQL-gebruiker weigerde de server met error 1130: Host '…' is not allowed to connect to this MySQL server. Met de gebruiker erbij ging de verbinding door. Zonder de firewallregel liep de verbinding gewoon in een time-out. Elk ander adres op internet krijgt die time-out.

5. Minder RAM gebruiken

In rust, zonder eigen data, gebruikte MySQL 8.0 op onze server 383 MB. Het grootste deel daarvan is het Performance Schema, een diagnosefunctie die vooraf geheugen reserveert. Zet het op een kleine VPS uit en bepaal zelf de grootte van de hoofdcache:

sudo tee /etc/mysql/mysql.conf.d/zz-small-vps.cnf >/dev/null <<'EOF'
[mysqld]
performance_schema = OFF
innodb_buffer_pool_size = 256M
max_connections = 50
EOF
sudo systemctl restart mysql
ps -o rss= -C mysqld

Na de herstart gebruikte het 165 MB. De buffer pool cachet je data en indexen, en 256 MB past bij een server van 2 GB die ook de app draait. Verhoog hem als de database het belangrijkste op de server is en groter is geworden dan de cache. max_connections = 50 is ruim genoeg voor één app met een connectiepool. Je verliest de statistieken van performance_schema. Zet het weer aan als je ooit trage query's tot in detail moet uitzoeken.

6. Nachtelijke back-ups

mysqldump --single-transaction maakt een consistente kopie van InnoDB-tabellen zonder de app buiten te sluiten. Stop het in een klein script:

sudo tee /usr/local/bin/mysql-backup >/dev/null <<'EOF'
#!/bin/bash
set -euo pipefail
umask 077
mkdir -p /var/backups/mysql
mysqldump --single-transaction --routines --triggers app | gzip > /var/backups/mysql/app-$(date +%F).sql.gz
find /var/backups/mysql -name 'app-*.sql.gz' -mtime +14 -delete
EOF
sudo chmod 755 /usr/local/bin/mysql-backup
echo '0 3 * * * root /usr/local/bin/mysql-backup' | sudo tee /etc/cron.d/mysql-backup
sudo /usr/local/bin/mysql-backup && sudo ls -l /var/backups/mysql

Elke regel heeft een reden:

  • umask 077 maakt de dump alleen leesbaar voor root (-rw-------), want hij bevat al je data.
  • pipefail laat het hele script falen als mysqldump faalt. Zonder dit zou gzip een piepklein leeg archief schrijven en succes melden. We hebben het commando expres kapotgemaakt, en het script stopte zoals het hoort met code 2.
  • find … -mtime +14 -delete bewaart twee weken aan kopieën.
  • Het script draait als root, dus mysqldump logt in via de socket en er staat nergens een wachtwoord in een bestand.

Een back-up die je nooit hebt teruggezet, telt nog niet. Zet hem terug in een tijdelijke database en bekijk de data:

sudo mysql -e "CREATE DATABASE app_restore"
gunzip -c /var/backups/mysql/app-2026-10-25.sql.gz | sudo mysql app_restore
sudo mysql -e "SHOW TABLES FROM app_restore"
sudo mysql -e "DROP DATABASE app_restore"

In onze test had de teruggezette tabel dezelfde rijen als het origineel. Kopieën op dezelfde schijf beschermen je niet als je de server kwijtraakt, dus haal ze af en toe naar een andere machine met scp of restic. Managed Backups voegt daar dagelijkse herstelpunten van de hele server aan toe.

Welk pakket

Micro (2 vCPU, 2 GB, 25 GB, $5/maand) draagt MySQL met deze afstelling plus een webapp. Groeit de database zelf voorbij een paar gigabyte, dan kun je met Small, 4 GB en 35 GB voor $8/maand, de buffer pool 1 GB of meer geven. Beide zijn NAT-pakketten, en de SSH-tunnel uit stap 3 werkt daarop. Stap 4 vraagt een eigen IPv4: Micro-IP kost $10/maand.

Liever PostgreSQL? De PostgreSQL-handleiding volgt hetzelfde plan. Alle pakketten staan onder VPS, en betalen gaat in USDT, USDC of ETH op Base, Ethereum of Polygon.

FAQ

MySQL of MariaDB?

Beide staan in de eigen pakketbronnen van Ubuntu 24.04: mysql-server installeert MySQL 8.0 en mariadb-server installeert MariaDB 10.11. De meeste apps die om "MySQL" vragen, werken met allebei. Gebruik wat de documentatie van je app noemt, en MySQL 8.0 als het niet uitmaakt. Deze handleiding gebruikt MySQL.

Wat is het root-wachtwoord van MySQL?

Dat is er niet. Op Ubuntu gebruikt het root-account van MySQL socket-authenticatie: met sudo mysql log je in als root, en niemand kan via het netwerk als root inloggen. Laat dat zo en maak aparte gebruikers aan voor je apps.

Moet ik poort 3306 openzetten naar internet?

Nee. Open databasepoorten worden voortdurend gescand en met wachtwoordpogingen bestookt. Verbind vanaf je computer via een SSH-tunnel. Moet een andere server direct verbinden, sta dan alleen het IP van die server toe, zowel in MySQL als in de firewall.

Hoeveel RAM heeft MySQL nodig?

Direct na installatie gebruikte MySQL 8.0 op onze testserver 383 MB, zonder eigen databases. Met het Performance Schema uit en een bescheiden buffer pool werd dat 165 MB. Het Micro-pakket met 2 GB draait MySQL en een app met gemak; na die afstelling volstaat 1 GB voor een kleine site.

Moet ik mysql_secure_installation draaien?

Op Ubuntu 24.04 is het meeste werk daarvan al gedaan. Onze verse installatie had geen anonieme gebruikers en geen testdatabase, en root kan alleen via de lokale socket inloggen. Draai het als je de wachtwoordsterkte-controle wilt die het aanbiedt; anders kun je het overslaan.

Reacties

Nog geen reacties. Wees de eerste.

Laat een reactie achter

Reacties worden gemodereerd voordat ze verschijnen.