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.
RequestError: unable to get local issuer certificate
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:
"ssl": "Amazon RDS"
- How was Ghost installed and configured? kubernetes
- What Node version, database, OS & browser are you using? Prior to upgrading, node was on v14.18.1. MySQL 8, OS is 5.3.0 alpine.
- What errors or information do you see in the console? See above
- What steps could someone else take to reproduce the issue you’re having? Deploy any version of ghost 4.x, then upgrade to 5.x
Are you using a FQDN? If so, that should be reflected in
However, it looks like you’re trying to do this for
localhost, and that’s not possible with a certificate authority.
Hi mjw, I’ve tried changing url to a FQDN which matches the environment variable “url”. However, I still receive the same error.
A little more information about your setup would help immensely, and a link the the site. How do you proxy Ghost? How have you setup SSL?
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.
However, 5.x prevents this setup from working.
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.
Sorry, I was too vague.
The ingress forwards to the service “postal”, which has this setup:
- name: http
The ingress forwards to the service like so:
So you’re correct, the ingress proxies to port 2368 (in this case the name is http) on the service.
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
"Unable to determine the authenticated user or integration. Check that cookies are being passed through if using session authentication."
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: 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.