I’m running ghost in kubernetes and I just upgraded from the latest version of 4.x.x-alpine to 5.0.0-alpine. I updated the ‘url’ environment variable to https, however I’m getting the following error:
[2022-07-13 21:52:44] ERROR The server has encountered an error.
The server has encountered an error.
Error ID:
20318500-02f6-11ed-a6cb-356b7ff82f2b
Error Code:
UNABLE_TO_GET_ISSUER_CERT_LOCALLY
----------------------------------------
RequestError: unable to get local issuer certificate
at /var/lib/ghost/versions/5.3.0/core/server/adapters/scheduling/SchedulingDefault.js:319:23
at ClientRequest.<anonymous> (/var/lib/ghost/versions/5.3.0/node_modules/got/source/request-as-event-emitter.js:178:14)
at Object.onceWrapper (node:events:642:26)
at ClientRequest.emit (node:events:539:35)
at ClientRequest.origin.emit (/var/lib/ghost/versions/5.3.0/node_modules/@szmarczak/http-timer/source/index.js:37:11)
at TLSSocket.socketErrorListener (node:_http_client:454:9)
at TLSSocket.emit (node:events:527:28)
at emitErrorNT (node:internal/streams/destroy:157:8)
at emitErrorCloseNT (node:internal/streams/destroy:122:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
I also tried the latest version but the same error.
Our URL is not public facing. Here is my config.production.json:
sadly I can’t link to the site, it’s running internally only. Besides, it can’t run because of the cert issue.
To answer the other questions, we’re running this in kubernetes and in 4.x the url environment variable in our deployment was http://ghost.dev.local. The config.production.json had url: http://localhost:2368 and everything worked great.
SSL was handled through an ingress, with the cert being issued by letsencrypt tied to the ingress. So users would connect via https ghost.dev.local which would then point to ghost running on port 80 (targetPort 2368).
Since 5.x, we had to change the url environment variable to https://ghost.dev.local and this is where all the pain started.
Since you’re using config.production.json, I assume you’ve not done a local install, so url should be the public URL, not localhost. Then use Nginx to proxy 443 or 80 to the port Ghost runs on.
ghost.dev.local is not a FQDN, so Let’s Encrypt will fail, and the error message alludes to this. Therefore, either use port 80 if it is a intranet site, or port 443 and a self issued certificate.
Incidentally, I use a FQDN for my intranet sites, overriding DNS on the DHCP server, and simply control access on the perimeter firewall.
The problem is, if I use http://ghost.dev.local in the URL environment variable and in the config.production.json, Ghost gives a 301 permanent redirect to HTTPS followed by the cert issue.
Then use Nginx to proxy 443 or 80 to the port Ghost runs on.
This is how it was setup in 4.x. Ghost was running on port 80, then instead of nginx, we had a kubernetes ingress that was proxying 443 to 80. Let’s encrypt works in this case because the issuer for “.dev.local” is our internal CA. So as long as the user is on VPN and has the root CA installed on their machine, there are no cert issues.
It should proxy to the Ghost port, i.e., 2368, not 80. The redirects are handled by your proxy, not Ghost, so I think this is where things are misconfigured.
Hello again,
I decided to start from scratch with a brand new 5.3.0 image, empty database, etc. Ghost installed correctly, initialized the database and was running. I went to the /ghost page to setup the admin user and did so correctly. Except when I try to login as that user I just created I get:
[2022-07-14 18:49:53] ERROR "GET /ghost/api/admin/users/me/?include=roles" 403 2ms
Authorization failed
"Unable to determine the authenticated user or integration. Check that cookies are being passed through if using session authentication."
Error ID:
bfacbf50-03a5-11ed-8e77-c97f2078f1b2
----------------------------------------
NoPermissionError: Authorization failed
at authorizeAdminApi (/var/lib/ghost/versions/5.3.0/core/server/services/auth/authorize.js:33:25)
at Layer.handle [as handle_request] (/var/lib/ghost/versions/5.3.0/node_modules/express/lib/router/layer.js:95:5)
at next (/var/lib/ghost/versions/5.3.0/node_modules/express/lib/router/route.js:144:13)
at authenticate (/var/lib/ghost/versions/5.3.0/core/server/services/auth/session/middleware.js:28:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
So I can’t login as the user and re-import everything.
Sounds like Kubernetes Ingress isn’t passing the authentication cookies. Indeed, it seems that your choice of infrastructure, and removing Nginx, is the cause of your problems.
The ingress doesn’t strip headers. I changed the image to 5.0.0 and I can actually login to the admin console. However, I’m met with a new error when trying to upload redirects from the previous installation:
EACCES: permission denied, open '/var/lib/ghost/content/data/redirects.json'
Error ID:
fae31370-03ab-11ed-bdc3-69044444ce1b
Error Code:
EACCES
----------------------------------------
Error: EACCES: permission denied, open '/var/lib/ghost/content/data/redirects.json'
at module.exports.prepareError (/var/lib/ghost/versions/5.0.0/node_modules/@tryghost/mw-error-handler/lib/mw-error-handler.js:79:19)
I tried port-forwarding to the pod so I’d be skipping the ingress and I get the same error. Again, none of this happened in 4.x, even the latest 4.48.2 I believe.