The ``pre_deploy`` hook reassigns every object of the outline database (tables, sequences, views, materialized views, standalone types, functions, procedures) to the application role before the container runs its migrations. Historical provisioning or restores running as the ``postgres`` superuser leave objects owned by ``postgres``, so any later ``ALTER`` on them fails with "must be owner of ..." and puts outline in a crash-loop at migration time. Seen on elabore.coop when upgrading 1.6.1 -> 1.10.0: migration ``20260714000000-add-mcp-to-search-queries-source.js`` failed on ``enum_search_queries_source``. Extensions are excluded from the realignment (they are managed by the ``postgres`` charm). The hook is idempotent, silent when there is no drift, and blocks the deployment (``exit 1``) if any drift remains, so the problem surfaces at deploy time instead of as a cryptic crash-loop.
118 lines
4.2 KiB
Org Mode
118 lines
4.2 KiB
Org Mode
# -*- ispell-local-dictionary: "english" -*-
|
||
|
||
* Info
|
||
|
||
From: https://docs.getoutline.com/s/hosting/doc/docker-7pfeLP5a8t
|
||
|
||
|
||
* Usage
|
||
|
||
Config info: https://github.com/outline/outline/blob/main/.env.sample
|
||
|
||
Odoo config: if you configure odoo OIDC connector, the callback url
|
||
should be like this : https://<YOUR_OUTLINE>:443/auth/oidc.callback
|
||
|
||
|
||
#Requires a =smtp-server= provider to be functional, you can use
|
||
#=smtp-stub= charm to provide information to externally managed =SMTP=.
|
||
|
||
#+begin_src yaml
|
||
outline:
|
||
options:
|
||
sender-email: #the sender email (beware the conf of your SMTP server)
|
||
oidc-client-id: #the client id of your OIDC provider
|
||
oidc-client-secret: #the client
|
||
oidc-auth-uri: #the host of your OIDC provider
|
||
oidc-token-uri: #the token uri of your OIDC provider
|
||
oidc-user-info-uri: #the user info uri of your OIDC provider
|
||
oidc-logout-uri: #the login uri of your OIDC provider
|
||
|
||
#smtp-stub:
|
||
# options:
|
||
# host: smtp.myhost.com
|
||
# port: 465
|
||
# connection-security: "ssl/tls"
|
||
# auth-method: password #IMPORTANT: if not present login password doesn’t work
|
||
# login: myuser
|
||
# password: myp4ssw0rd
|
||
|
||
#+end_src
|
||
|
||
** Odoo 14
|
||
|
||
We monkey-patch odoo in order to make it work, be sure to use latest version in 14.0 of galicea openIDConnection module
|
||
|
||
* Database ownership alignment
|
||
|
||
The =pre_deploy= hook ensures that every object of the database
|
||
(tables, sequences, views, materialized views, standalone types,
|
||
functions, procedures) is owned by the application role before the
|
||
container starts and runs its migrations.
|
||
|
||
Historical provisioning or restores executed as the =postgres=
|
||
superuser leave objects owned by =postgres=, which makes any later
|
||
=ALTER= on these objects fail with "must be owner of ..." and puts
|
||
outline in a crash-loop at migration time. This was seen on
|
||
2026-09-11 when upgrading elabore.coop from 1.6.1 to 1.10.0:
|
||
migration =20260714000000-add-mcp-to-search-queries-source.js=
|
||
failed on =enum_search_queries_source=. The same drift was found
|
||
on every managed server (lokavaluto.fr, lagemme.org, moneko.org).
|
||
|
||
Extensions are excluded from the realignment (they are managed by
|
||
the =postgres= charm). The hook is idempotent and silent when
|
||
there is no drift, and blocks the deployment (=exit 1=) if the
|
||
realignment fails, so the problem is visible at deploy time instead
|
||
of as a cryptic crash-loop.
|
||
|
||
* Building a new image
|
||
|
||
We use the official image with an added patch due to 2 bugs:
|
||
- https://github.com/outline/outline/issues/6859
|
||
- second was not reported yet
|
||
|
||
Note that a PR was pushed with a fix on the first bug. But this was not yet tested.
|
||
|
||
The fix are on 1.6.1
|
||
|
||
** Fix
|
||
|
||
Upon calling "/oidc" url, outline will return "Set-Cookie" header
|
||
with a "domain:" value that is incorrect (still the inner docker
|
||
domain: "outline" instead of the outer proxy domain from the frontend.)
|
||
|
||
Fortunately we can simply remove the value "domain" from the cookie by
|
||
commenting only 2 lines in ~build/server/utils/passport.js~.
|
||
|
||
The patches will change the "build/" files, so this is a very temporary and brittle fix.
|
||
|
||
|
||
#+begin_src bash
|
||
IMAGE=docker.0k.io/outline:1.6.1-elabore
|
||
|
||
echo 'apt update && apt install patch' | dupd -u "$IMAGE" -- -u 0
|
||
cat <<'EOF1' | dupd -u "$IMAGE" -- -u 0
|
||
patch -p 1 <<'EOF2'
|
||
--- a/build/server/utils/passport.js.orig
|
||
+++ b/build/server/utils/passport.js
|
||
@@ -56,7 +56,7 @@
|
||
const state = buildState(host, token, client);
|
||
ctx.cookies.set(this.key, state, {
|
||
expires: (0, _dateFns.addMinutes)(new Date(), 10),
|
||
- domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
|
||
+ //domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
|
||
});
|
||
callback(null, token);
|
||
});
|
||
@@ -73,7 +73,7 @@
|
||
// Destroy the one-time pad token and ensure it matches
|
||
ctx.cookies.set(this.key, "", {
|
||
expires: (0, _dateFns.subMinutes)(new Date(), 1),
|
||
- domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
|
||
+ //domain: (0, _domains.getCookieDomain)(ctx.hostname, _env.default.isCloudHosted)
|
||
});
|
||
if (!token || token !== providedToken) {
|
||
return callback((0, _errors.OAuthStateMismatchError)(), false, token);
|
||
EOF2
|
||
EOF1
|
||
#+end_src
|