Hello,
I’m running into a situation that I’m not quite understanding. I have attempted to deploy Ghost on a test machine successfully and a live production machine unsuccessfully, both with very similar Docker compose files. The error I am getting on the live production server is this:
Both servers are self-hosted.
Here is the Docker compose file of my working test machine that I used from Ghost’s web site:
version: '3.1'
services:
ghost:
image: ghost:latest
restart: always
ports:
- 8080:2368
environment:
# see https://ghost.org/docs/config/#configuration-options
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: example
database__connection__database: ghost
# this url value is just an example, and is likely wrong for your environment!
url: http://<myserveripaddress>:8080
# contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
#NODE_ENV: development
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: example
Here is the Docker compose file from my live production server that is giving me the error:
version: '3.1'
services:
ghost:
image: ghost:latest
restart: always
ports:
- 8080:2368
volumes:
- /path/to/docker/ghost/content:/var/lib/ghost/content
environment:
# see https://ghost.org/docs/config/#configuration-options
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: mypassword
database__connection__database: ghost
# this url value is just an example, and is likely wrong for your environment!
url: https://www.mydomain.info
# contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
#NODE_ENV: development
db:
image: mysql:8.0
restart: always
volumes:
- /path/to/docker/ghost/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: mypassword
The only things I changed in the production compose file was adding the volumes and changing the URL to point to my public domain.
What am I doing wrong? It has to be the volumes, right? Perhaps permissions issue since it seems it is having difficulty finding or connecting to the database? Ports need to be defined?
Thanks in advance for any assistance. This issue, for some reason, is knocking me for a loop. I have found similar threads on the same error but none using Docker or Docker compose file.
Update: I’ve tried a number of combinations - removing the volumes, adding MySQL ports, etc. - and nothing has changed. I’m still unable to deploy the latest Ghost with the latest MySQL.
Here is my latest compose file attempt:
version: '3.1'
services:
ghost:
image: ghost:latest
restart: always
ports:
- 8080:2368
volumes:
- /path/to/docker/ghost/content:/var/lib/ghost/content
environment:
# see https://ghost.org/docs/config/#configuration-options
database__client: mysql
database__connection__host: db
database__connection__user: root
database__connection__password: mystrongpassword
database__connection__database: ghost
# this url value is just an example, and is likely wrong for your environment!
url: https://www.mydomain.info
# contrary to the default mentioned in the linked documentation, this image defaults to NODE_ENV=production (so development mode needs to be explicitly specified if desired)
#NODE_ENV: development
db:
image: mysql:latest
restart: always
volumes:
- /path/to/docker/ghost/mysql:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: mystongpassword
MYSQL_DATABASE: ghost
MYSQL_USER: ghostuser
MYSQL_PASSWORD: mystongpassword
Here is a portion of the log that is repeating I am now seeing with this latest attempt (some sensitive data edited):
ghost-db-1 | 2023-05-16 10:09:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.33-1.el8 started.
ghost-db-1 | 2023-05-16 10:09:03+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’
ghost-db-1 | 2023-05-16 10:09:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.33-1.el8 started.
ghost-db-1 | 2023-05-16 10:09:04+00:00 [ERROR] [Entrypoint]: Database is uninitialized and password option is not specified
ghost-db-1 | You need to specify one of the following as an environment variable:
ghost-db-1 | - MYSQL_ROOT_PASSWORD
ghost-db-1 | - MYSQL_ALLOW_EMPTY_PASSWORD
ghost-db-1 | - MYSQL_RANDOM_ROOT_PASSWORD
ghost-db-1 exited with code 1
ghost-ghost-1 | [2023-05-16 10:09:04] INFO Ghost is running in production…
ghost-ghost-1 | [2023-05-16 10:09:04] INFO Your site is now available on https://www.mypublicdomain.info/
ghost-ghost-1 | [2023-05-16 10:09:04] INFO Ctrl+C to shut down
ghost-ghost-1 | [2023-05-16 10:09:04] INFO Ghost server started in 1.162s
ghost-db-1 | 2023-05-16 10:09:04+00:00 [Note] [Entrypoint]: Switching to dedicated user ‘mysql’
ghost-db-1 | 2023-05-16 10:09:04+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.33-1.el8 started.
ghost-ghost-1 | [2023-05-16 10:09:05] ERROR connect ECONNREFUSED 172.18.0.3:3306
ghost-ghost-1 |
ghost-ghost-1 | connect ECONNREFUSED 172.18.0.3:3306
ghost-ghost-1 |
ghost-ghost-1 | “Unknown database error”
ghost-ghost-1 |
ghost-ghost-1 | Error ID:
ghost-ghost-1 | 500
ghost-ghost-1 |
ghost-ghost-1 | Error Code:
ghost-ghost-1 | ECONNREFUSED
ghost-ghost-1 |
ghost-ghost-1 | ----------------------------------------
ghost-ghost-1 |
ghost-ghost-1 | Error: connect ECONNREFUSED 172.18.0.3:3306
ghost-ghost-1 | at /var/lib/ghost/versions/5.47.2/node_modules/knex-migrator/lib/database.js:57:19
ghost-ghost-1 | at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1278:16)
ghost-ghost-1 |
ghost-ghost-1 | [2023-05-16 10:09:05] WARN Ghost is shutting down
ghost-ghost-1 | [2023-05-16 10:09:05] WARN Ghost has shut down
ghost-ghost-1 | [2023-05-16 10:09:05] WARN Your site is now offline
ghost-ghost-1 | [2023-05-16 10:09:05] WARN Ghost was running for a few seconds
You used the mysql:latest image in production but mysql:8 in testing. Make it exactly the same in production (mysql:8) to eliminate that difference as a source of possible errors.
Docker has benefits, but is definitely more complicated to host and introduces a new layer where new an additional category of bugs and misconfigurations can be introduced.
While I support containers professionally at work, I have no regrets about using the officially supported non-containerized install method for my personal Ghost blogs.
I’ve made some progress and now have a MySQL container up and running without fault. However, now it seems the Ghost container is having issues connecting to the database with the designated user. Here is my updated Docker compose file:
version: '3.8'
services:
ghost:
image: ghost:latest
restart: always
ports:
- 8080:2368
depends_on:
- db
volumes:
- /path/to/docker/ghost/content:/var/lib/ghost/content
environment:
database__client: mysql
database__connection__host: db
database__connection__user: ghostuser
database__connection__password: mystrongpassword
database__connection__database: ghostdb
# this url value is just an example, and is likely wrong for your environment!
url: https://www.mypublicdomain.info
db:
image: mysql:latest
restart: always
ports:
- 3306:3306
volumes:
- /path/to/docker/ghost/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=mystrongpassword
- MYSQL_DATABASE=ghostdb
- MYSQL_USER=ghostuser
- MYSQL_PASSWORD=mystrongpassword
Here is the error I am not getting from Ghost in the Docker compose logs:
The variables in the Ghost container just tell it where to find the database. Setting variables in Ghost can’t force MySQL to give it access.
As for the environment variables you set in the mysql:8 container, you’ll have to read the documentation or the source code of the container to see how it works, but my expectation is that the container may grant access to those users from localhost, but it would be bad security to grant wide open access from any host by default.
Just a hunch here: when I first setup my Docker environment with Ghost, I ran into a similar issue.
My problem was that I used a password for the MySQL user that container lots of special characters. These led to the password string not being interpreted correctly.
I ended up wrapping all environment variables in my docker-compose.yml in “quotes”, which solved the issue:
Additionally, as you can see, I am explicitly setting the port to 3306, but I just tried and it also works without. So, my best guess is that there could be a special character in your password that is breaking.
@jannis You nailed it. That was the issue. I was able to get it working with this:
version: '3.8'
services:
ghost:
image: ghost:latest
restart: always
ports:
- 8080:2368
depends_on:
- db
volumes:
- /path/to/docker/ghost/content:/var/lib/ghost/content
environment:
database__client: mysql
database__connection__host: db
database__connection__user: "ghostuser"
database__connection__password: "mystrongpassword"
database__connection__database: "ghostdb"
# this url value is just an example, and is likely wrong for your environment!
url: https://www.mypublicdomain.info
db:
image: mysql:latest
restart: always
ports:
- 3306:3306
volumes:
- /path/to/docker/ghost/mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=mystrongpassword
- MYSQL_DATABASE=ghostdb
- MYSQL_USER=ghostuser
- MYSQL_PASSWORD=mystrongpassword
In my case it is not enough storage on the filesystem. I have 20GB but I think there is some limit in ghost regarding percentage of space left.
I had this issue once before, unfortunately with so many other services I had to re-learn it all again. Would be nice to see this requirement in the documentation and/or if error reporting were more accurate as it kept giving me a db authentication error making me investigate entirely different set of components.
The mysql:8.0 image works. I am using it in production environments on over 100 Ghost sites.
If you’re running into issues with the mysql:8.0 image, there might be a different issue underneath (have a look at your logs when starting Ghost and open a new topic, if you need help).
If you’re using mysql:latest, this is referring to MySQL 9.0 – so, a version that is not supported by Ghost.
Ghost only supports MySQL 8, so advising people to downgrade to an older version can have other side effects that might break functionality.
Had a typo there, instead of “Used” I wrote “Use”. I’m not trying to advise anyone just stating what worked for me. I am currently using ghost:latest with “mysql:5.7” not mysql:latest so you stating “Ghost only supports MySQL 8” isn’t the case for me. I couldn’t get mysql 8 or latest to work.
I confirmed through many trials that it is Portainer that is causing the issue and not docker or ghost. Unfortunately right now in Portainer running a ghost stack you can only use mysql 5.7, you can’t use 8.0 yet. I will ask the Portainer community as well about this but 8.0 just doesn’t work right now which is a shame because mysql 5.7 is now depreciated. I’ll post back if I find out something from Portainer.
Do you want to share your compose files for Portainer? I get a database error when I use 8.0, but no error with 5.7. Would be great to see your ghost Portainer yaml.