Docker container "blocked because of many connection errors"

I am trying to install the Passbolt Docker container on an Ubuntu 20.04 server, and it is failing with an error. The first error is:

Host '172.17.0.4' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

Then if I run it again (and if I haven’t run mysqladmin flush-hosts in the meantime) the error changes to:

Exception: Connection to Mysql could not be established: SQLSTATE[HY000] [2006] MySQL server has gone away.

The passbolt container is connecting to the host’s MySQL (172.17.0.1) from the internal Docker address 172.17.0.4 (verified using Docker inspect), so I have ensured that I allowed remote MySQL access from that IP. I have also checked that the password and username are correct. So I’ve eliminated all the possible reasons for MySQL connection errors that I can think of.

Here are the relevant environment variables:

DATASOURCES_DEFAULT_HOST = 172.17.0.1
DATASOURCES_DEFAULT_PASSWORD = [omitted]
DATASOURCES_DEFAULT_USERNAME = passbolt
DATASOURCES_DEFAULT_DATABASE = passbolt

Any suggestions for how I might troubleshoot this further? Thanks!

Hi @terminus :wave:

You shouldn’t use the IP address of your docker gateway but the service name of your mysql container.

If you look at the docker-compose.yaml file provided by our official documentation, the used host is db, because this name resolve to the mysql container.

Cheers,

I am not using a MySQL container, I’m using the host system’s MySQL. There’s no way to do it like that?

@terminus Can you provide your modified yaml file?

No because the hosting service that I’m using (Cyberpanel) doesn’t support Docker Compose. I thought I could just configure the passbolt Docker image from hub.docker.com to work by itself, but guess I was mistaken. Never mind, since I was trying to do something non-standard, it’s not worth spending more time on getting the image to work. Thanks!

@terminus It should still be possible I think. We offer docker compose files to make it easy but GitHub - passbolt/passbolt_docker: Get started with Passbolt CE using docker! readme has one line docker command that shows environment variables as an example.

Complete list of env variables here.

That’s what I thought: based on the documentation then the environment variables that I’m using should work: DATASOURCES_DEFAULT_HOST is set to the IP address of the Docker host where MySQL is running, and MySQL is configured to allow connections from the IP address of the Passbolt Docker container. So I got stuck at the point of figuring out why it’s failing with connection errors. Is database SSL compulsory, perhaps?

@terminus I am not a Docker expert, but I think the problem is that without a docker compose file, you are missing the port configuration it would normally offer. You will need something like the following as part of your run command to bind your host mysql port to the container’s internal network:

-p 172.17.0.1:3306:3306

The goal would be that the container sends db requests to it’s local port 3306 which would then get passed to your host port. I would not list the DATASOURCES_DEFAULT_HOST variable in the command.

Docker run commandline reference is here.

Edit: a security concern would be opening the 3306 port up to the outside of your host…we wouldn’t want that. By noting the local ip and not just the port (ie not 3306:3306) we are binding it to local-only.

I think the above example I provided is incorrect. That would permit incoming calls to the passbolt db. Sorry about that, it’s been about a year since I’ve done docker in my daily work. :joy:

Is your external db in a Docker container also? If so, you will need to create a Docker bridge network so they can talk to each other.

If not, and your db is installed on the host itself, then I think you will need to run the passbolt container with host networking, but that introduces another issue as it’s no longer isolated from a network standpoint. Do you have another webserver running on your host? or any other services that use 80 and 443? Passbolt container has NGINX so this could cause a conflict of you already have a service running on those ports.

Thanks Garrett, and sorry for failing to reply earlier as I hadn’t had a chance to try your suggestion.

My external db is not in a Docker container, it’s on the host. Based on experience with another Docker container using a similar configuration, there doesn’t seem to be any problem with Docker connecting to MySQL on the host on the default port 3306. The trick is just to use the Docker-ified host IP address (in my case 172.17.0.1), and to ensure that MySQL is listening on the Docker interface (rather than, per default, just the local network interface).

As for the web ports, yes they are blocked by ports on the host. I am planning to run passbolt on high ports (eg. 8080 and 4043), and then to put them behind a reverse proxy that maps them to a dedicated domain using ports 80 and 443.

@terminus So you are saying that you are having your host db listen on 172.17.0.1:3306 and this works for another Docker container already but one which does not use host networking? Maybe share more about your network address setup if you are still having trouble.

For example, how you are running the other Docker container? What are its settings with regards to the host db?

Yes, the setup for the other Docker container looks like this (env variables are a little different than for Passbolt of course):

DB_HOST = 172.17.0.1
DB_PORT = 3306
DB_CONNECTION = mysql
DB_DATABASE = fireflydb
DB_USERNAME = fireflyuser
DB_PASSWORD = secret

After ensuring that fireflyuser is allowed to connect to MySQL from the Docker IP address (127.17.0.2), it just works. No special command line arguments, no Docker Compose.

@terminus Ok, that makes sense as it matches what you are saying. When you run the container, how are you starting it with network and/or port designations? Or, how are you configuring mysql regarding ip and port?

It’s not entirely satisfactory but MySQL has an “all or nothing” setting for interfaces to listen on. So you need to set bind-address to 0.0.0.0 in order to include the Docker network interface. To reduce the attack footprint you need to firewall off the interfaces that you don’t want to have access to MySQL. Other than that, nothing special is required.

Interesting. I can understand why you would think it should work. It’s different than I’ve considered before so I’m not sure I can tell you exactly what to do to fix it.

Some more ideas:

  • have you confirmed with a 2nd method that mysql is in fact running on 0.0.0.0? Something like ss | grep 3306
  • is the passbolt db user restricted to the wrong address?
  • have you restarted mysql after any changes, or rebooted to see if it makes any difference?
  • can you run an interactive internal command line on the 2nd container and manually try to reach the db?