Testcontainers-java: New MySQL version 1.15.1 works only with docker image mysql:latest

Created on 17 Dec 2020  路  5Comments  路  Source: testcontainers/testcontainers-java

Hi,
We were using an older version (1.14.3) that stopped working due to ryuk:0.3.0 issue last week, and we had to upgrade our version to 1.15.1, after this upgrade it continued to fail on:

Failed to verify that image 'mysql-server:5.7' is a compatible substitute for 'mysql'. This generally means that you are trying to use an image that Testcontainers has not been designed to use. If this is deliberate, and if you are confident that the image is compatible, you should declare compatibility in code using the `asCompatibleSubstituteFor` method. For example:
   DockerImageName myImage = DockerImageName.parse("mysql-server:5.7").asCompatibleSubstituteFor("mysql");
and then use `myImage` instead.
java.lang.IllegalStateException: Failed to verify that image 'mysql-server:5.7' is a compatible substitute for 'mysql'. This generally means that you are trying to use an image that Testcontainers has not been designed to use. If this is deliberate, and if you are confident that the image is compatible, you should declare compatibility in code using the `asCompatibleSubstituteFor` method. For example:
   DockerImageName myImage = DockerImageName.parse("mysql-server:5.7").asCompatibleSubstituteFor("mysql");
and then use `myImage` instead.

I debugged the code and found that in your class DockerImageName, the method assertCompatibleWith, is comparing only to docker image version: "mysql:latest".

When I tried to use this specific version in my test it passed this initiation, but still the container failed to start.
In my code I used to define the username and password, but it seemed they arrived to the docker as empty values, when I removed my user/password definition, my test finally passed again.

My original code:

        mysqlContainer = new MySQLContainer<>("mysql/mysql-server:5.7")
                .withInitScript(MYSQL_INIT_SCRIPT_NAME)
                .withDatabaseName(MYSQL_DATABASE_NAME)
                .withUsername("root")
                .withPassword("test");

My currently working code:

       mysqlContainer = new MySQLContainer<>("mysql:latest")
                .withInitScript(MYSQL_INIT_SCRIPT_NAME)
                .withDatabaseName(MYSQL_DATABASE_NAME);

I would like to still use a specific docker image and not latest, I would also like to be able to define my user/password.

Thanks!
Happy Holidays :)

Most helpful comment

Hmm, assuming that mysql/mysql-server:5.7 is the image you want to use, I think you need to do:

mysqlContainer = new MySQLContainer<>(DockerImageName.parse("mysql/mysql-server:5.7").asCompatibleSubstituteFor("mysql"))
                .withInitScript(MYSQL_INIT_SCRIPT_NAME)
                .withDatabaseName(MYSQL_DATABASE_NAME)
                .withUsername("root")
                .withPassword("test");

Did you try this? I'm not sure whether you're trying to use mysql/mysql-server:5.7 or mysql-server:5.7 - it's a bit unclear from your description.

You shouldn't need to use mysql:latest at all, and that's not what the error message is asking you to do.

Please be aware of https://github.com/testcontainers/testcontainers-java/issues/2627, but I would think that if your tests were working with 1.14.3 then you may not be affected by that issue.

All 5 comments

Hmm, assuming that mysql/mysql-server:5.7 is the image you want to use, I think you need to do:

mysqlContainer = new MySQLContainer<>(DockerImageName.parse("mysql/mysql-server:5.7").asCompatibleSubstituteFor("mysql"))
                .withInitScript(MYSQL_INIT_SCRIPT_NAME)
                .withDatabaseName(MYSQL_DATABASE_NAME)
                .withUsername("root")
                .withPassword("test");

Did you try this? I'm not sure whether you're trying to use mysql/mysql-server:5.7 or mysql-server:5.7 - it's a bit unclear from your description.

You shouldn't need to use mysql:latest at all, and that's not what the error message is asking you to do.

Please be aware of https://github.com/testcontainers/testcontainers-java/issues/2627, but I would think that if your tests were working with 1.14.3 then you may not be affected by that issue.

Thanks for your answer, yes, I tried this, as this is what the exception explains to do :)
It kept failing on the same exception, so I debugged and found that in your class DockerImageName, the method assertCompatibleWith, is comparing only to docker image version: "mysql:latest".
This is why I deiced to try using the latest image, to be sure my code passes this assert method.

I'm not sure if it matters to use the MySQL server or just MySQL, I just need the MySQL DB to insert into then query... The old code (before upgrading to 1.15.1) used the MySQL-server, but I'm not sure this is a must. Also it did work when I used the MySQL...

Hi again, I'm still using the workaround I described here.
I use "latest" only because during debugging your code I found it is the only image that passes the validation.
Can you assist?

The same issue happened to me but with another image. They are not using mysql:latest like you say, this is because you are using

.asCompatibleSubstituteFor("mysql")

instead of

.asCompatibleSubstituteFor("mysql:5.7")

to compare with the same MySQL version that you want to use in your tests

Is this still an issue? I apologise for not following up, but I'm unclear if this is still actively a problem or not, and if it is, how it is happening. If it is still actively a problem, it would be helpful if somebody could construct a repro example in code - we have a template for this: https://github.com/testcontainers/testcontainers-java-repro

Was this page helpful?
0 / 5 - 0 ratings