Error when changing database port : ERROR connect ECONNREFUSED

Hello,

I’m trying to deploy ghost with Docker. For that I deploy two container’s one for ghost app and one for my database.

On my server another container is running on port 3306 (default port for mysql database), so I changed the port to 3307 for my ghost database.

I also added the database__connection__port to port 3307 to matches the change.

But when I deploy it… I’ve got the folowing error:

[2024-03-17 22:47:20] WARN Ghost is shutting down
[2024-03-17 22:47:20] WARN Ghost has shut down
[2024-03-17 22:47:20] WARN Ghost was running for a few seconds
[2024-03-17 22:47:47] INFO Ghost is running in development...
[2024-03-17 22:47:47] INFO Listening on: :::2368
[2024-03-17 22:47:47] INFO Url configured as: https://ghost.domain/
[2024-03-17 22:47:47] INFO Ctrl+C to shut down
[2024-03-17 22:47:47] INFO Ghost server started in 0.431s
[2024-03-17 22:47:47] ERROR connect ECONNREFUSED 172.19.0.3:3307

connect ECONNREFUSED 172.19.0.3:3307

"Unknown database error"

Error ID:
    500

Error Code:
    ECONNREFUSED

----------------------------------------

Error: connect ECONNREFUSED 172.19.0.3:3307
    at /var/lib/ghost/versions/5.80.3/node_modules/knex-migrator/lib/database.js:57:19
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1555:16)

Here is my config (deployed with ansible that’s why the syntax is not like docker compose but it’s the same principle):

- name: Make sure the {{ container_database_name }} container is created and running
  docker_container:
    name: "{{ container_database_name }}"
    image: mysql:8.0-debian
    ports:
      - "3307:3306"
    env:
      MYSQL_ROOT_PASSWORD: "{{ ghost_mysql_root_password }}"
      MYSQL_DATABASE: "{{ ghost_mysql_database}}"
      MYSQL_USER: "{{ ghost_mysql_user }}"
      MYSQL_PASSWORD: "{{ ghost_mysql_password}}"
    volumes:
      - "{{ docker_dir }}/{{ container_database_name }}:/var/lib/mysql"
    restart_policy: unless-stopped

- name: Make sure the {{ container_name }} container is created and running
  docker_container:
    name: "{{ container_name }}"
    image: ghost:latest
    # ports:
    #   - "2368:2368"
    env:
      url: "https://ghost.{{ domain }}"
      NODE_ENV: "production"
      database__client: "mysql"
      database__connection__host: "{{ container_database_name }}"
      database__connection__port: "3307"
      database__connection__database: "{{ ghost_mysql_database}}"
      database__connection__user: "{{ ghost_mysql_user }}"
      database__connection__password: "{{ ghost_mysql_password }}"
    volumes:
      - "{{ docker_dir }}/{{ container_name }}/content:/var/lib/ghost/content"
    restart_policy: unless-stopped

Of course my two containers are in the same network.

I don’t know why it’s not working here… I’ve tried many things to make it work but always got the same result.

NOTE: When I let the port to default (3306) for my ghost database and stop my other container that was already using the 3306 port everything work well…

Thanks in advance to anyone who can help me!
Have a nice day.

Your Ansible syntax doesn’t show that them being added to the same network. If so, they would contain a network directive, like network: mysql:

https://docs.ansible.com/ansible/latest/collections/community/docker/docker_container_module.html#parameter-networks

Share the output of a command that confirms that the containers are on the same network.

It’s because I do it in another task, they are in a specific network named ghost.

It work perfectly when I use the default port 3306, that why I don’t think it’s due to the docker networking…

(Gonna post the output to prove they are on the same network later, actually on my phone)

EDIT: Code where I’m adding the two container to the same network

- name: Add {{ container_name }} to the ghost network
  docker_network:
    name: ghost
    connected:
      - "{{ container_name }}"
    appends: yes

- name: Add {{ container_database_name }} to the ghost network
  docker_network:
    name: ghost
    connected:
      - "{{ container_database_name }}"
    appends: yes

Try: docker ps -a to list containers and their ports.

Try: sudo netstat -atlpn to see all connections on the Docker bridge.

Try: docker port <container_name_or_id> on both containers.

I’m creating an Ansible role now to automate setting up Ghost with containers, perhaps you would be interested. Although, I’m using Podman and not Docker.

$ docker port ghost_db
3306/tcp -> 0.0.0.0:3307

$docker port ghost
no result

$ docker ps -a
67e8c8ae352e   ghost:latest                           "docker-entrypoint.s…"   4 hours ago    Up Less than a second   0.0.0.0:2368->2368/tcp              ghost
5b5e61c5c8bf   mysql:8.0-debian                       "docker-entrypoint.s…"   4 hours ago    Up 4 hours              33060/tcp, 0.0.0.0:3307->3306/tcp   ghost_db

The ghost container restarts in a loop due to database connection error.

I think the error comes from the container, has anyone managed to get ghost and the database working with a modified port (different that default 3306)?

Why not for your ansible code, it might help me ;)

So far you’ve shown how ports are mapped from containers to the host, but now how the containers can connect to each other.

Use commands like:

## See what's attached to the network you recreated
docker network inspect <network_name_or_id>

## See what network each container is attache dto.
docker container inspect <container_name_or_id>

To confirm how your containers are networked with each other.

Or you could enable host networking for the containers, where they could use port 3307

As I said before, my containers are on the same network:

$ docker network inspect ghost
[
    {
        "Name": "ghost",
        "Id": "078dba34465841055b0b994d7efeb52c69167f8c21e62c9193accb30898b15f2",
        "Created": "2024-03-17T19:34:39.786483539+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "310e247cc3439bbde6234566dce500efeef1e2ffa2c1f3364c78e4c7d87b93a7": {
                "Name": "ghost_db",
                "EndpointID": "92d816e423fc940c11cea9e820a90a453177660d6314944ff73a4705b354ec93",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            },
            "c21409c7c6baf0906c5fe66dde284b5b1a012427c8903c0530c8cbcd38916e9b": {
                "Name": "ghost",
                "EndpointID": "b5f7c96e36b7ec17da83b1d095a57eb50783ed22ff9559f5eca1d6cd709d4e58",
                "MacAddress": "02:42:ac:13:00:03",
                "IPv4Address": "172.19.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

They can even ping each other!

Any change made to the environnement variable “database__connection__port” made the whole thing broken… But everything is working when I use the default port 3306.

I think it’s a more likely to be a bug of the ghost container.

I think you should not do this port mapping, because both the host and the Ghost containers can access MySQL by IP address on the bridge networking you have created for it.

  • Use the -ip option with MySQL to assign it an IP address within the private network, like 172.19.33.06.
  • Update Ghost connection string to connect to 172.19.33.06.

The result should be that your main MySQL will be running on the host at port 3306 and your MySQL container will be running on this private IP at port 3306.

It’s not good security for containers to be able to access the host, which is why it’s better to run MySQL on a private IP that both the containers and the host can access than run on a custom port on the host that the containers are supposed to connect back to.