Reputation: 21
I'm trying to create a local Docker registry using Testcontainers and push an image programatically to it. However, I'm getting a connection refused error when attempting to push the image. The first test which checks if the registry is running works, so i know the registry is running.
Here’s my test class:
class DockerRegistryTest {
@Rule
public static GenericContainer registry;
private static String registryAddress;
private static DockerClient dockerClient;
@BeforeAll
static void startRegistry() {
registry = new GenericContainer(DockerImageName.parse("registry:2"))
.withExposedPorts(5000)
.waitingFor(Wait.forHttp("/v2/").forStatusCode(200));
registry.start();
assertTrue(registry.isRunning(), "Registry is running");
registryAddress = registry.getHost() + ":" + registry.getMappedPort(5000);
System.out.println("Registry available at: " + registryAddress);
DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build();
dockerClient = DockerClientImpl.getInstance(config, new ApacheDockerHttpClient.Builder()
.dockerHost(config.getDockerHost())
.sslConfig(config.getSSLConfig())
.build());
}
@AfterAll
static void tearDown() {
if (registry != null) {
registry.stop();
}
}
@Test
void testPushImageToRegistry() throws InterruptedException {
String localImage = "busybox:latest";
dockerClient.pullImageCmd(localImage).start().awaitCompletion();
String registryImageTag = registryAddress + "/busybox:latest";
dockerClient.tagImageCmd(localImage, registryAddress + "/busybox", "latest").exec();
dockerClient.pushImageCmd(registryImageTag)
.withAuthConfig(new AuthConfig()) // No authentication needed
.start()
.awaitCompletion();
System.out.println("Successfully pushed image to registry: " + registryImageTag);
assertTrue(true);
}
}
However, when I run the test, I get this error:
com.github.dockerjava.api.exception.DockerClientException: Could not push image: failed to do request:
Head "https://localhost:57244/v2/busybox/blobs/sha256:31311c5853a22c04d692f6581b4faa25771d915c1ba056c74e5ec82606eefdfa":
dial tcp [::1]:57244: connect: connection refused
Things I tried
C:\Users\codex>curl http://localhost:<mappedPortIgotFromLogs>/v2/_catalog
{"repositories":[]}
so I know the repository is up and running
I also added this in testcontainers.properties
ryuk.container.image=testcontainersofficial/ryuk
to get my test container to work in the first place.
And here is a screenshot from my docker desktop
Update 1:
i changed
`registryAddress = registry.getHost() + ":" + registry.getMappedPort(5000);`
to registryAddress = "0.0.0.0" + ":" + registry.getMappedPort(5000);
but now i get
`com.github.dockerjava.api.exception.DockerClientException: Could not push image: failed to do request: Head "https://0.0.0.0:60075/v2/busybox/blobs/sha256:9c0abc9c5bd3a7854141800ba1f4a227baa88b11b49d8207eadc483c3f2496de": http: server gave HTTP response to HTTPS client`
Upvotes: 0
Views: 49
Reputation: 11
By default, Docker assumes that private registries use HTTPS. Since Testcontainers is running an HTTP registry, you need to configure Docker to allow HTTP.
Modify your Docker daemon configuration (for Windows, macOS, or Linux): Open the Docker Daemon settings (found in Docker Desktop under Settings → Docker Engine). Add the following entry under "insecure-registries":
{
"insecure-registries": ["localhost:57244"]
}
(Replace 57244 with the mapped port from Testcontainers).
Restart Docker Desktop after saving the changes.
Alternatively, use the environment variable for Docker:
System.setProperty("com.github.dockerjava.insecure", "true");
Before running your test, try the following manual push in the terminal:
docker tag busybox:latest localhost:<your_testcontainer_mapped_port>/busybox:latest
docker push localhost:<your_testcontainer_mapped_port>/busybox:latest
Upvotes: 1