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 077maakt de dump alleen leesbaar voor root (-rw-------), want hij bevat al je data.pipefaillaat het hele script falen alsmysqldumpfaalt. Zonder dit zougzipeen 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 -deletebewaart twee weken aan kopieën.- Het script draait als root, dus
mysqldumplogt 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.
Reacties
Nog geen reacties. Wees de eerste.