Skip to content

Commit

Permalink
add support for custom keycloak images
Browse files Browse the repository at this point in the history
  • Loading branch information
slemke committed Dec 7, 2024
1 parent 1b44161 commit a2db909
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 3 deletions.
47 changes: 47 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,53 @@ const container = await new KeycloakContainer()

By default, every container is always a Keycloak in development mode.


### Starting a container with a custom version

You can start the container with a custom version by providing a tag (default: `latest`) to the constructor.
A list of possible values for the tag can be found on [Keycloaks repository page on quay.io](https://quay.io/repository/keycloak/keycloak?tab=tags).

```js
import KeycloakContainer from 'keycloak-testcontainer';

const container = await new KeycloakContainer({ tag: '26.0' })
.start();
```

Using the example above a Keycloak container should start with version 26.0 as long as the image with the tag is available on quay.io. If the tag you are using is not available you'll see an error similar to the error below:

```
Error: (HTTP code 404) unexpected - manifest for quay.io/keycloak/keycloak:21 not found: manifest unknown: manifest unknown
```

### Starting a container with a custom registry

If you want to run an image from a different registry you can provide a registry to the container like so:

```js
import KeycloakContainer from 'keycloak-testcontainer';

const container = await new KeycloakContainer({
registry: 'intern.org/keycloak/keycloak'
})
.start();
```

With the custom registry the testcontainer tries to start with the following image: `intern.org/keycloak/keycloak:latest`.
You also can combine this with a custom tag:

```js
import KeycloakContainer from 'keycloak-testcontainer';

const container = await new KeycloakContainer({
registry: 'intern.org/keycloak/keycloak',
tag: 'intern-rc-22'
})
.start();
```

This would result in the following image being used: `intern.org/keycloak/keycloak:intern-rc-22`

### Starting a container with Keycloak commands

You can run this testcontainer with a bunch of different commands to obtain different Keycloak functionality. For a deeper explaination and up to date documentation have a look at the [Keycloak guides](https://www.keycloak.org/guides).
Expand Down
16 changes: 14 additions & 2 deletions src/container/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,27 @@ import { Keycloak } from '../keycloak.js';
import { StartedKeycloakContainer } from './started-container.js';
import { Configuration } from './configuration.js';

interface KeycloakContainerOptions {
registry?: string
tag?: string
}

export class KeycloakContainer extends GenericContainer {

private configuration: Configuration;

constructor() {
super('quay.io/keycloak/keycloak:latest');
constructor(options?: KeycloakContainerOptions) {
const registry = options?.registry ?? 'quay.io/keycloak/keycloak';
const tag = options?.tag ?? 'latest';
const imageName = `${registry}:${tag}`;
super(imageName);
this.configuration = new Configuration();
}

public getImageName() {
return this.imageName;
}

public withHostname(hostname: string): this {
this.configuration.withHostName(hostname);
return this;
Expand Down
36 changes: 35 additions & 1 deletion test/container/container.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,48 @@ describe.sequential('Container', () => {

const managementPort = 9000;

it('should start new custom keycloak container', async () => {
it.only('should start new custom keycloak container', async () => {
const startedContainer = await initCustomKeycloakContainer().start();

await verifyHealthEndpointAvailability(startedContainer, managementPort);
await verifyMetricsEndpointAvailability(startedContainer, managementPort);
await startedContainer.stop({ timeout: 10000 });
});

it('should init new keycloak container with latest version', () => {
const container = new KeycloakContainer();
expect(container.getImageName()).toMatchObject({
"image": "keycloak/keycloak",
"registry": "quay.io",
"string": "quay.io/keycloak/keycloak:latest",
"tag": "latest"
});
});

it('should init new custom keycloak container with different tag', () => {
const container = new KeycloakContainer({ tag: '25' });

expect(container.getImageName()).toMatchObject({
"image": "keycloak/keycloak",
"registry": "quay.io",
"string": "quay.io/keycloak/keycloak:25",
"tag": "25"
});
});

it('should init new custom keycloak container based on a different registry', () => {
const container = new KeycloakContainer({
registry: 'intern.org/keycloak/keycloak',
tag: 'custom'
});
expect(container.getImageName()).toMatchObject({
"image": "keycloak/keycloak",
"registry": "intern.org",
"string": "intern.org/keycloak/keycloak:custom",
"tag": "custom"
});
})

it('should be able to use admin client', async () => {
const startedContainer = await initCustomKeycloakContainer().start();

Expand Down

0 comments on commit a2db909

Please sign in to comment.