Cronjob werkt niet op je VPS? Zo vind je de oorzaak
Een geplande taak die stilletjes stopt, merk je vaak te laat. Met deze checklist controleer je waarom je cronjob op een Linux VPS niet werkt.
Je voorraadimport loopt iedere nacht. Tenminste, dat dacht je. Tot een klant iets bestelt dat al uitverkocht is. Een cronjob die niet werkt geeft lang niet altijd een duidelijke foutmelding. Soms start de taak niet, soms stopt het script halverwege en soms draait alles keurig onder het verkeerde gebruikersaccount.
Ga niet meteen meer CPU of geheugen bestellen. Controleer eerst of de taak wordt gestart, onder welke gebruiker hij draait en wat het script teruggeeft. Hieronder vind je een praktische volgorde voor een Linux VPS waarop je zelf het beheer doet.
1. Bepaal eerst wat er precies misgaat
Maak onderscheid tussen drie situaties: de taak start helemaal niet, de taak start maar mislukt, of de taak slaagt technisch maar levert niet het gewenste resultaat op. Een import die zonder foutmelding nul producten verwerkt, is voor je bedrijf nog steeds een mislukte import.
- Noteer wanneer de taak voor het laatst aantoonbaar goed liep.
- Controleer wat er sindsdien veranderde: een deployment, wachtwoord, bestandspad of update.
- Kijk of de geplande tijd inmiddels voorbij is in de tijdzone van de server.
- Controleer het resultaat zelf, bijvoorbeeld de bijgewerkte voorraad of het aangemaakte rapport.
Start een import of betaaltaak niet zomaar nog eens. Controleer eerst of een tweede uitvoering dubbele bestellingen, berichten of betalingen kan veroorzaken.
2. Controleer de juiste crontab en de cronservice
Een gebruikerscrontab hoort bij één account. Als je tijdens de installatie als root werkte, kan de taak in de crontab van root staan terwijl je nu met je normale beheeraccount kijkt. Met crontab -l bekijk je de taken van de huidige gebruiker. Met de juiste beheerrechten kun je via sudo crontab -u appuser -l de taken van je applicatiegebruiker bekijken. Vervang appuser door het echte account.
Let ook op de plek waar de taak staat. Een gebruikerscrontab heeft vijf tijdvelden gevolgd door het commando. In /etc/crontab en bestanden onder /etc/cron.d/ staat daarnaast een gebruikersveld. Als je die formaten door elkaar haalt, kan cron je taak verkeerd interpreteren.
Op veel Debian- en Ubuntu-installaties controleer je de service met systemctl status cron. Op andere distributies heet die vaak crond. Niet iedere minimale serverinstallatie heeft cron al geïnstalleerd. Controleer dus eerst welke scheduler jouw systeem gebruikt.
3. Kijk in de logs, niet alleen naar het script
De scheduler kan melden dat een commando gestart is, zonder te weten of jouw voorraadimport inhoudelijk geslaagd is. Controleer daarom zowel de servicelogs als de uitvoer van het script.
Bij een systeem met systemd kun je bijvoorbeeld journalctl -u cron --since today gebruiken, of dezelfde opdracht met crond als dat jouw servicenaam is. Afhankelijk van de configuratie staan cronmeldingen ook in /var/log/syslog of /var/log/cron. Die bestanden zijn niet op elke distributie aanwezig.
Laat je taak tijdelijk standaarduitvoer en foutmeldingen naar een logbestand schrijven. Een cronregel kan bijvoorbeeld eindigen op >> /var/log/mijn-app/import.log 2>&1. De map moet bestaan en de gebruiker die de taak uitvoert moet er kunnen schrijven. Bewaar geen wachtwoorden, tokens of volledige klantgegevens in die logs en regel logrotatie.
4. Gebruik absolute paden en een expliciete werkmap
Een script dat via SSH werkt, hoeft niet vanuit cron te werken. Je interactieve shell heeft vaak een andere PATH, andere omgevingsvariabelen en een andere werkmap. Cron laadt niet automatisch dezelfde shellconfiguratie als jouw terminal.
- Gebruik het volledige pad naar het script, bijvoorbeeld /srv/mijn-app/import.py.
- Gebruik het volledige pad naar de interpreter, bijvoorbeeld /srv/mijn-app/.venv/bin/python.
- Stel de werkmap expliciet in als je applicatie relatieve paden gebruikt.
- Controleer waar de applicatie haar configuratie en omgevingsvariabelen vandaan haalt.
Bij een Python-applicatie met een virtual environment is alleen python aanroepen vaak niet genoeg. Je kunt daarmee de systeemversie starten in plaats van de versie met jouw dependencies. Hetzelfde probleem zie je bij Node.js dat via een versiebeheerder in je interactieve shell beschikbaar is.
5. Test onder dezelfde gebruiker
Root kan bestanden lezen die je applicatiegebruiker niet mag openen. Een geslaagde handmatige test als root bewijst daarom weinig. Test onder hetzelfde account als de cronjob, met dezelfde interpreter, werkmap en benodigde configuratie. Doe dat alleen wanneer een extra uitvoering veilig is.
Controleer bestandsrechten en toegang tot de bovenliggende mappen. Als je een script rechtstreeks uitvoert, moet het uitvoerbaar zijn en een passende interpreterregel hebben. Roep je het via een interpreter aan, dan moet die interpreter het script kunnen lezen. Controleer daarnaast toegang tot databases, netwerkdiensten en configuratiebestanden.
Los een rechtenprobleem niet op met overal volledige schrijfrechten of door iedere taak als root te draaien. Geef het account alleen de toegang die voor die taak nodig is.
6. Controleer tijdzone en bijzondere cronregels
Een taak die om twee uur hoort te draaien, kan op een server met UTC op een ander lokaal moment starten dan je verwacht. Controleer de servertijdzone met timedatectl als jouw systeem dat ondersteunt. Leg vast welke tijdzone je planning gebruikt.
Wees extra voorzichtig rond de overgang tussen zomer- en wintertijd. Lokale tijden kunnen wegvallen of dubbel voorkomen. Hoe de scheduler daarmee omgaat, hangt af van de implementatie. Voor bedrijfskritische taken wil je daarom niet alleen een planning, maar ook een controle op het verwachte resultaat.
Ook de syntax kan verrassen. In veel cronimplementaties heeft een procentteken in het commando een speciale betekenis en moet je het escapen. Een commando met datumopmaak kan daardoor via SSH wel werken en in de crontab misgaan. Zet ingewikkelde logica liever in een apart script dat je kunt testen.
7. Voorkom overlappende uitvoeringen
Als een import iedere vijf minuten start maar soms tien minuten duurt, kunnen meerdere uitvoeringen tegelijk draaien. Dat kan databasevergrendelingen, dubbele verwerking of onnodige belasting veroorzaken.
Met een lockingmechanisme, bijvoorbeeld flock op systemen waar dat beschikbaar is, kun je voorkomen dat een tweede uitvoering tegelijk begint. Zorg wel dat de locklocatie toegankelijk is voor de juiste gebruiker. Registreer ook wanneer een uitvoering vanwege een bestaande lock wordt overgeslagen.
Een lock is geen vervanging voor een degelijk script. Maak de verwerking waar mogelijk idempotent: dezelfde invoer nogmaals verwerken mag niet opnieuw dezelfde betaling of bestelling aanmaken. Stel ook een passende timeout in, zodat een vastgelopen taak niet onbeperkt blijft hangen.
8. Bewaak succes, niet alleen bereikbaarheid
Je VPS kan prima bereikbaar zijn terwijl je nachtelijke import al een week niet meer werkt. Controleer daarom apart wanneer de taak voor het laatst succesvol klaar was. Laat een melding versturen als die bevestiging te lang uitblijft.
- Leg starttijd, eindtijd en uitkomst vast.
- Controleer waar mogelijk het aantal verwerkte records of een ander inhoudelijk resultaat.
- Waarschuw bij fouten én als een verwachte uitvoering ontbreekt.
- Spreek af wie op de melding reageert.
Voor taken waarbij logging en beheer centraal moeten staan, kan een systemd-timer een alternatief zijn. Je koppelt de planning dan aan een service met expliciete instellingen. Met de juiste configuratie kun je ook gemiste uitvoeringen na uitval laten inhalen. Dat is niet voor iedere taak wenselijk: een verouderd rapport opnieuw maken is iets anders dan een oude betaalopdracht alsnog versturen.
Wanneer helpt een eigen Cloud VPS?
Voor een simpele geplande taak heb je niet automatisch een VPS nodig. Als je huidige hosting de juiste interpreter, planning en toegang ondersteunt, kan dat voldoende zijn. Een eigen VPS wordt interessant wanneer je zelf runtimes wilt installeren, achtergrondprocessen nodig hebt of meer controle wilt over gebruikersrechten, logging en de scheduler.
Op onze pagina over Cloud VPS met root-toegang vind je de beschikbare configuraties. Je krijgt de vrijheid om je applicatie en planning zelf in te richten. Die vrijheid betekent ook dat iemand verantwoordelijk moet zijn voor updates, beveiliging, back-ups en controle op de taken. Lees bij de afweging tussen zelf beheren en uitbesteden wat je hoster bij VPS-beheer overneemt en wat je zelf blijft doen. Leg apart vast wie je cronjobs en het resultaat van je applicatie bewaakt.
Wil je eerst laten beoordelen of jouw import of koppeling een eigen server nodig heeft? Neem contact op en vertel wat de taak doet, hoe vaak hij draait en wat er gebeurt als hij een keer mislukt. Dan kijken we mee naar een passende oplossing, zonder een groter pakket als eerste antwoord.