De regel die de meeste schrikmomenten op Odoo.sh voorkomt, past in één zin: niets gaat naar productie zonder een groene build op een echte kopie van de database van de klant, met dezelfde commit die je gaat mergen. De documentatie legt het platform uit, niet de werkwijze van een partner. Hier is de onze.
Dit artikel vult Odoo.sh voor e-commerce aan en vervangt het; de samenvatting voor webshops staat onderaan.
Drie fases, en wat elke fase echt doet
Odoo.sh heeft drie fases: productie (maar één branch), staging en development. Het verschil zit in de database waarmee elke build start:
- Development: nieuwe database met demodata, installeert de modules van de branch en voert de tests uit; duurt ongeveer drie dagen. Het is de enige fase die test: de tests hangen af van de demodata.
- Staging: de build dupliceert de productiedatabase en neutraliseert die. De kopie wordt na een maand verwijderd.
- Productie: de push herstart de server; als je de moduleversie in
__manifest__.pyhebt verhoogd, voert die de update uit (gelijk aan-u) en gaat de instantie in onderhoudsmodus. Bij een fout keert hij terug naar de vorige revisie en herstelt de database.
Daaruit volgt iets wat bijna niemand leest: mergen brengt de code over, nooit wat je handmatig in de stagingdatabase hebt aangepast. Wat je wilt laten aankomen, hoort in de XML van de module, met de versie verhoogd.
Branchstructuur voor een partner
Met één klant volstaan dev, staging en productie. Met meerdere: een ontwikkelbranch per taak; een stagingbranch per klant en oplevering, opnieuw opgebouwd vóór elke validatie; de enige productiebranch die Odoo.sh oplegt; en, als de module naar de App Store gaat, een per Odoo-versie.
In onze repository staan nu 144 branches, waaronder 17.0, 18.0, 19.0 en production: 41 hebben het achtervoegsel -17, -18 of -19 (een connector, een versie) en 19 zijn production-pre-<cambio>-<fecha>: de commit die productie draaide vóór elke gevoelige uitrol. Terugkeren is een push.
Beproefde valkuil: een branch die via git wordt aangemaakt, wordt gebouwd met de standaardversie van het project, niet met die van de branch waar je van afsplitst. We splitsten een -17 af van 17.0 en Odoo.sh bouwde hem als 19.0: de manifest 17.0.x werd als niet installeerbaar gemarkeerd. De versie stel je in bij de instellingen, en alleen voor ontwikkelbranches.
De build als poort: wat hij controleert en wat niet
Een build is groen (geen fouten of waarschuwingen), geel (waarschuwingen) of rood (fouten); alleen groen wordt opgeleverd. Een development-build controleert of de modules van de branch installeren op een schone database met demodata en of hun tests slagen. Wat hij niet controleert:
- Modules buiten de branch. Standaard installeert hij alleen die van jou, zonder submodules. In de instellingen: volledige installatie (submodules en alle standaardmodules, maar zonder tests) of een lijst technische namen gescheiden door komma's, wat de nuttige optie is.
- De upgrade. Hij installeert vanaf nul; voert nooit
-uuit op een database met geschiedenis. - De echte data. Dat is staging, dat geen tests uitvoert.
Daarom heeft de poort twee vleugels: de development-build voert tests uit die installeren, niet alleen unittests; en de stagingbranch voert de echte upgrade uit op de kopie van productie, waarbij update.log tot het einde wordt gelezen. Kijk naar de regel 0 failed, 0 error(s) of N tests met N groter dan nul: een groene build met nul tests is leeg. Meer oorzaken in een Odoo 19-module compileert maar installeert niet.
Staging met data: wat de kopie oplost en wat niet
De neutralisatie lost het gevaarlijke op: er gaan geen e-mails de deur uit (je ziet ze op het tabblad Mails), geplande acties draaien niet, IAP's blijven buiten beeld, vervoerders en betaalgateways staan in testmodus, en neutralize.log vertelt wat er is uitgezet. Wat ze niet oplost:
- Anonimiseren blijft jouw taak. Het zet processen uit, maar wist geen persoonsgegevens. Als het team geen klantgegevens mag zien: Developer heeft geen toegang tot staging of productie, Tester wel tot staging en alleen Admin tot productie.
- De inloggegevens van externe API's reizen mee in de kopie. Een connector in staging met de productiesleutels praat met Amazon of Mirakl alsof hij de echte is: activeer de sandboxmodus of maak de sleutels leeg.
- De stagingdatabase ververst zichzelf niet. Standaard werkt de branch de vorige build bij en overleeft de database tussen pushes, met de al aangepaste data; met New build start elke push vanaf een verse kopie. De crons start je handmatig, en handmatige back-ups blijven drie dagen bewaard, met een maximum van vijf per dag.
SSH en psql in productie: wat je aanraakt en wat niet
Odoo.sh geeft een shell naar productie. We gaan erin om te lezen (psql, lnav ~/logs/odoo.log), te diagnosticeren met odoo-bin shell en de suite van een module in transactiemodus uit te voeren. Wat we niet doen: een handmatige UPDATE of modules installeren zonder de build. Details die je een middag kosten: scp en sftp zijn geblokkeerd, de Postgres-rol kan geen databases aanmaken en eigen modules staan onder ~/src/user. Een geluk bij een ongeluk: odoo-bin shell doet bij het afsluiten een rollback in 17, 18 en 19 (odoo/cli/shell.py).
Upgrade in productie: noupdate, base.group_system en migraties
Een upgrade start je door de versie in de manifest te verhogen; Odoo.sh maakt een back-up gemarkeerd als Update (ook als requirements.txt verandert) en voert de -u uit. Hier zit de duurste valkuil die we hebben gehad. Het gebruikelijke idioom om de beheerder jouw groep te laten erven is:
<record id="base.group_system" model="res.groups">
<field name="implied_ids" eval="[(4, ref('group_mi_manager'))]"/>
</record>Het werkt in een nieuwe installatie en wordt bij een upgrade stilzwijgend genegeerd. De reden zit in de database van de klant: noupdate staat in de rij van ir_model_data. Bij het bijwerken herschrijft de loader alleen het record if not (update and d_noupdate) (odoo/orm/models.py in 19, odoo/models.py in 17 en 18), en de upsert die die tabel bijhoudt, ververst model en res_id maar nooit de kolom noupdate: eenmaal gezet, wordt hij niet meer weggehaald. En het valt niet af te leiden uit de addon: in alle drie de versies staat het record van base.group_system in een <data> zonder noupdate en toch kan het gemarkeerd aankomen:
select name, noupdate from ir_model_data
where module='base' and name in ('group_system','group_user');In onze Odoo.sh-productie geeft het t terug in beide; in de 69 databases die onze testomgeving vanaf nul heeft aangemaakt, is group_user t en group_system, f. Dezelfde XML, twee uitkomsten.
Het overkwam ons met onze Mirakl-connector 16.15.0: de inloggegevens werden naar een groep "Mirakl Manager" verplaatst. In nieuwe installaties erfde de beheerder die; in de bijgewerkte bleef ze zonder leden en kon niemand de sleutels aanraken. De tests waren groen omdat een schone installatie het record wel toepast. De oplossing, in 16.15.1: de XML laten staan en migrations/19.0.16.15.1/post-migrate.py toevoegen, dat de implicatie in SQL wegschrijft op res_groups_implied_rel en res_groups_users_rel met ON CONFLICT DO NOTHING, plus een test die faalt als de groep leeg blijft.
De migraties: map migrations/<versión>/ met bestanden pre-*.py, post-*.py en end-*.py, elk met migrate(cr, version), waarbij version de geïnstalleerde versie is. Odoo voert ze alleen uit als de module is gemarkeerd om bij te werken: in een nieuwe installatie draait er geen enkele, daarom is de XML nodig. Als de hoofdversie verandert, is het proces anders: migratiefouten naar Odoo 19 en de go-live-checklist.
Valkuilen die niet in de documentatie staan
- Builds die in slaap vallen. Een ongebruikte development-build gaat in slaapstand en zijn crons draaien niet. Als je hem als testomgeving gebruikt, houd hem wakker: wij hebben een launchd-agent die elke 240 seconden
curl /web/healthenssh -n … trueuitvoert tegen elke build. - De build die je valideert, kan de oude zijn. De identificatie verandert bij elke push en de vorige wordt pas na een tijd gerecycled: via SSH bestaan er twee naast elkaar. Voordat je iets goedkeurt:
grepvan wat je zojuist hebt gewijzigd in~/src/user. - De reeks van de manifest faalt anders in elke richting. In 19 laat een manifest
18.0.xof17.0.xhet niet crashen: de server waarschuwt has an incompatible version, setting installable=False. Omgekeerd onderbreekt in 17 of 18 een19.0.x.y.zhet inlezen met invalid manifest.
Checklist voor oplevering aan de klant
- Groene build (niet geel) in development, met tests die installeren en N groter dan nul.
- Staging vandaag opnieuw opgebouwd vanuit productie; externe inloggegevens in sandbox of leeg.
- Versie verhoogd in de manifest en
update.logtot het einde gelezen, migraties inbegrepen. - Validatie door de klant in staging, met de crons handmatig en de e-mails nagekeken in Mails.
- Branch
production-pre-<cambio>-<fecha>vanaf de commit die in productie draait, en een handmatige back-up als er data wordt aangeraakt. - Merge buiten de piekuren en daarna
odoo.log, de rechtengroep met leden en de crons actief.
Deze werkwijze bieden we aan als Odoo-engineering voor adviesbureaus en gebruiken we bij elke implementatie en migratie naar Odoo 19. Ben je partner of softwarehuis, dan legt het programma voor technologiepartners uit hoe we werken.
Als je een e-commerce hebt
Een marketplace-connector of een voorraadregel in productie aanraken is spelen met echte bestellingen: dubbele labels, twee keer geïmporteerde bestellingen, half afgeronde synchronisaties. Via staging gaan de nieuwe modules, de voorraadwijzigingen en de connectorupdates (Amazon, Mirakl, ManoMano, SEUR, MRW, Correos Express), en daar staan vervoerders en betaalgateways in testmodus: daar test je een label zonder dat de bestelwagen vertrekt.
Veelgestelde vragen
Voert Odoo.sh de tests uit in staging of in productie?
Nee. Alleen in de development-builds, op een nieuwe database met demodata. Staging valideert met echte data zonder tests; productie laadt geen demodata en test niet.
Garandeert een groene build dat de module installeert in de Odoo van de klant?
Hij garandeert dat de module installeert op een schone database van die versie. Hij garandeert niet de upgrade op een database met geschiedenis, noch het samengaan met modules buiten de branch: dat dek je af in de staging van de klant.
Nuttige links binnen FlexigoTech
Wat wij hierover doen
Lever je projecten op Odoo.sh op en wil je een testomgeving die niet van geluk afhangt?
We zetten de branchflow, de build als poort en de migraties op voor je klanten, of we beoordelen de flow die je al hebt. Schrijf naar comercial@flexigobe.com of bel +34 616 809 504.

