9-course Dutch e-learning platform fused onto atlasacademy.nl via Caddy reverse proxy. Odoo 19 Community as course engine (website_slides), static HTML for marketing front. Single Odoo account system. - static/: 8 marketing pages (index, pricing, coaching, leerpad, over, shop, bisl, esf) - backend/odoo_relay.py: lead relay Flask service (POST /academy-lead → Odoo CRM) - caddy/academy.caddyfile: full Caddy config with Odoo proxy + auth rewrites - docs/: ARCHITECTURE, USERFLOW, COURSES, DEPLOYMENT, SECURITY, ODOO Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.7 KiB
Odoo eLearning Setup — Atlas Academy
Installatie
website_slides is geïnstalleerd als onderdeel van Odoo 19 Community op atlas-01.
# Verificatie
ssh atlas-01 "docker exec atlas-odoo odoo --list-db 2>/dev/null"
# DB: atlas
# Module status
ssh atlas-01 "docker exec -i atlas-odoo odoo shell -d atlas --no-http" <<'EOF'
m = env['ir.module.module'].sudo().search([('name','=','website_slides')])
print(m.name, m.state) # verwacht: website_slides installed
EOF
Multi-website configuratie
Atlas Academy draait op website 3 (apart van de Atlas Corporation-website op website 1).
| Website 1 | Website 3 | |
|---|---|---|
| Naam | Atlas Corporation | Atlas Academy |
| Domein | (default) | https://atlasacademy.nl |
| Signup | b2b (gesloten) |
b2c (open) |
| Taal | NL | NL |
| Logo | Atlas Corp | Atlas Academy icon |
Kritische gotcha's
1. Caching van website-routing
_get_current_website_id is ORM-gecached. Na aanmaken/wijzigen van een website:
ssh atlas-01 "docker restart atlas-odoo"
2. X-Forwarded-Host verplicht
Caddy moet X-Forwarded-Host {host} doorgeven, anders serveert Odoo altijd website 1:
reverse_proxy 100.93.16.81:8069 {
header_up Host {host}
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Proto https
}
3. proxy_mode = True
Controleer /opt/atlas-odoo/config/odoo.conf:
proxy_mode = True
4. Signup is per-website, niet globaal
De globale auth_signup.allow_uninvited parameter wordt genegeerd als website module actief is. Gebruik altijd:
env['website'].sudo().browse(3).write({'auth_signup_uninvited': 'b2c'})
env.cr.commit()
Website 3 aanmaken (referentie)
env = env # Odoo shell
w3 = env['website'].sudo().create({
'name': 'Atlas Academy',
'domain': 'https://atlasacademy.nl',
'company_id': env.company.id,
'language_ids': [(4, env.ref('base.lang_nl').id)],
'default_lang_id': env.ref('base.lang_nl').id,
'auth_signup_uninvited': 'b2c',
})
# Stel logo in
import base64, requests
logo_data = requests.get('https://atlasacademy.nl/atlas-icon.png').content
w3.write({'logo': base64.b64encode(logo_data).decode()})
env.cr.commit()
print(f"Website aangemaakt: ID={w3.id}")
# Vervolgens: docker restart atlas-odoo
Cursus website-toewijzing
Alle cursussen (slide.channel) moeten website_id=3 hebben:
channels = env['slide.channel'].sudo().search([])
for c in channels:
if not c.website_id or c.website_id.id != 3:
c.sudo().write({'website_id': 3})
env.cr.commit()
print(f"{len(channels)} cursussen toegewezen aan website 3")
Email base-URL
Odoo gebruikt website.get_base_url() voor links in e-mails (wachtwoord reset etc.).
Dankzij multi-website:
- Website 3 →
get_base_url()=https://atlasacademy.nl✅ - Website 1 →
get_base_url()= corp-domein ✅
De globale web.base.url parameter wordt niet gewijzigd (zou corp-emails breken).
Odoo backend bereikbaarheid
| Route | Bereikbaar? | Via |
|---|---|---|
atlasacademy.nl/slides |
✅ Publiek | Caddy proxy |
atlasacademy.nl/web/login |
✅ Publiek | Caddy proxy |
atlasacademy.nl/web (backend) |
❌ Niet geproxied | — |
http://100.93.16.81:8069 |
✅ Tailnet only | Direct |
odoo.atlascorporation.nl |
✅ SSO only | Authentik + Caddy |
Veelgebruikte ORM-commando's
# Shell openen
ssh atlas-01 "docker exec -i atlas-odoo odoo shell -d atlas --no-http"
# Alle cursussen tonen
for c in env['slide.channel'].sudo().search([]): print(c.id, c.name, c.website_slug)
# Cursuspagina URL genereren
c = env['slide.channel'].sudo().browse(2)
print(f"https://atlasacademy.nl/slides/{c.website_slug}")
# Lessen van een cursus tonen
slides = env['slide.slide'].sudo().search([('channel_id','=',2),('is_category','=',False)])
for s in slides: print(s.sequence, s.name, len(s.question_ids), 'vragen')
# Website-instellingen inspecteren
w = env['website'].sudo().browse(3)
print(w.name, w.domain, w.auth_signup_uninvited, w.get_base_url())
Bekende issues & oplossingen
| Issue | Oorzaak | Oplossing |
|---|---|---|
/web/signup → 404 |
auth_signup_uninvited niet op b2c |
ORM shell: w.write({'auth_signup_uninvited':'b2c'}) |
| Courses tonen op corp-website | website_id=None op channels |
Script: set alle channels op website_id=3 |
| Wachtwoord-reset e-mail heeft wrong URL | web.base.url verkeerd OF website 3 geen domein |
Controleer w3.domain en w3.get_base_url() |
| Odoo toont corp-logo op academy-domein | Website-cache niet geleegd | docker restart atlas-odoo |
/slides geeft 502 |
Odoo container down | docker start atlas-odoo && docker logs atlas-odoo |