diff --git a/Directory.Packages.props b/Directory.Packages.props
index a226bec96..3a429505b 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -31,6 +31,7 @@
+
diff --git a/Testcontainers.sln b/Testcontainers.sln
index 9595905ed..e36ab545c 100644
--- a/Testcontainers.sln
+++ b/Testcontainers.sln
@@ -195,6 +195,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Tests", "tes
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.WebDriver.Tests", "tests\Testcontainers.WebDriver.Tests\Testcontainers.WebDriver.Tests.csproj", "{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Camunda", "src\Testcontainers.Camunda\Testcontainers.Camunda.csproj", "{D1291B24-EED1-431C-B7CE-606A1D1B5AE8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Testcontainers.Camunda.Tests", "tests\Testcontainers.Camunda.Tests\Testcontainers.Camunda.Tests.csproj", "{E49BEB22-7719-4006-ACB9-90046D1F8526}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -568,6 +572,14 @@ Global
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1291B24-EED1-431C-B7CE-606A1D1B5AE8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D1291B24-EED1-431C-B7CE-606A1D1B5AE8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D1291B24-EED1-431C-B7CE-606A1D1B5AE8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D1291B24-EED1-431C-B7CE-606A1D1B5AE8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E49BEB22-7719-4006-ACB9-90046D1F8526}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E49BEB22-7719-4006-ACB9-90046D1F8526}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E49BEB22-7719-4006-ACB9-90046D1F8526}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E49BEB22-7719-4006-ACB9-90046D1F8526}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{5365F780-0E6C-41F0-B1B9-7DC34368F80C} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
@@ -661,5 +673,7 @@ Global
{1A1983E6-5297-435F-B467-E8E1F11277D6} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{27CDB869-A150-4593-958F-6F26E5391E7C} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
{EBA72C3B-57D5-43FF-A5B4-3D55B3B6D4C2} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
+ {D1291B24-EED1-431C-B7CE-606A1D1B5AE8} = {673F23AE-7694-4BB9-ABD4-136D6C13634E}
+ {E49BEB22-7719-4006-ACB9-90046D1F8526} = {7164F1FB-7F24-444A-ACD2-2C329C2B3CCF}
EndGlobalSection
EndGlobal
diff --git a/src/Testcontainers.Camunda/.editorconfig b/src/Testcontainers.Camunda/.editorconfig
new file mode 100644
index 000000000..6f066619d
--- /dev/null
+++ b/src/Testcontainers.Camunda/.editorconfig
@@ -0,0 +1 @@
+root = true
\ No newline at end of file
diff --git a/src/Testcontainers.Camunda/CamundaBuilder.cs b/src/Testcontainers.Camunda/CamundaBuilder.cs
new file mode 100644
index 000000000..8abf5f5b4
--- /dev/null
+++ b/src/Testcontainers.Camunda/CamundaBuilder.cs
@@ -0,0 +1,66 @@
+namespace Testcontainers.Camunda;
+
+///
+[PublicAPI]
+public sealed class CamundaBuilder : ContainerBuilder
+{
+ public const string CamundaImage = "camunda/camunda-bpm-platform:7.22.0-SNAPSHOT";
+
+ public const ushort CamundaPort = 8080;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CamundaBuilder()
+ : this(new CamundaConfiguration())
+ {
+ DockerResourceConfiguration = Init().DockerResourceConfiguration;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ private CamundaBuilder(CamundaConfiguration resourceConfiguration)
+ : base(resourceConfiguration)
+ {
+ DockerResourceConfiguration = resourceConfiguration;
+ }
+
+ ///
+ protected override CamundaConfiguration DockerResourceConfiguration { get; }
+
+ ///
+ public override CamundaContainer Build()
+ {
+ Validate();
+ return new CamundaContainer(DockerResourceConfiguration);
+ }
+
+ ///
+ protected override CamundaBuilder Init()
+ {
+ return base.Init()
+ .WithImage(CamundaImage)
+ .WithPortBinding(CamundaPort, true)
+ .WithWaitStrategy(Wait.ForUnixContainer().UntilMessageIsLogged("(?s).*Engine created.*$"));
+ }
+
+ ///
+ protected override CamundaBuilder Clone(IResourceConfiguration resourceConfiguration)
+ {
+ return Merge(DockerResourceConfiguration, new CamundaConfiguration(resourceConfiguration));
+ }
+
+ ///
+ protected override CamundaBuilder Clone(IContainerConfiguration resourceConfiguration)
+ {
+ return Merge(DockerResourceConfiguration, new CamundaConfiguration(resourceConfiguration));
+ }
+
+ ///
+ protected override CamundaBuilder Merge(CamundaConfiguration oldValue, CamundaConfiguration newValue)
+ {
+ return new CamundaBuilder(new CamundaConfiguration(oldValue, newValue));
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.Camunda/CamundaConfiguration.cs b/src/Testcontainers.Camunda/CamundaConfiguration.cs
new file mode 100644
index 000000000..7de9d661c
--- /dev/null
+++ b/src/Testcontainers.Camunda/CamundaConfiguration.cs
@@ -0,0 +1,54 @@
+namespace Testcontainers.Camunda;
+
+///
+[PublicAPI]
+public sealed class CamundaConfiguration : ContainerConfiguration
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CamundaConfiguration()
+ {
+
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ public CamundaConfiguration(IResourceConfiguration resourceConfiguration)
+ : base(resourceConfiguration)
+ {
+ // Passes the configuration upwards to the base implementations to create an updated immutable copy.
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ public CamundaConfiguration(IContainerConfiguration resourceConfiguration)
+ : base(resourceConfiguration)
+ {
+ // Passes the configuration upwards to the base implementations to create an updated immutable copy.
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The Docker resource configuration.
+ public CamundaConfiguration(CamundaConfiguration resourceConfiguration)
+ : this(new CamundaConfiguration(), resourceConfiguration)
+ {
+ // Passes the configuration upwards to the base implementations to create an updated immutable copy.
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The old Docker resource configuration.
+ /// The new Docker resource configuration.
+ public CamundaConfiguration(CamundaConfiguration oldValue, CamundaConfiguration newValue)
+ : base(oldValue, newValue)
+ {
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.Camunda/CamundaContainer.cs b/src/Testcontainers.Camunda/CamundaContainer.cs
new file mode 100644
index 000000000..fa481fda4
--- /dev/null
+++ b/src/Testcontainers.Camunda/CamundaContainer.cs
@@ -0,0 +1,25 @@
+namespace Testcontainers.Camunda;
+
+///
+[PublicAPI]
+public sealed class CamundaContainer : DockerContainer
+{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The container configuration.
+ public CamundaContainer(IContainerConfiguration configuration) : base(configuration)
+ {
+ }
+
+ ///
+ /// Gets the Camunda connection string.
+ ///
+ /// The Camunda connection string.
+ public string GetConnectionString()
+ {
+ var endpoint = new UriBuilder(Uri.UriSchemeHttp, Hostname, GetMappedPublicPort(CamundaBuilder.CamundaPort));
+ endpoint.Path = "engine-rest";
+ return endpoint.ToString();
+ }
+}
\ No newline at end of file
diff --git a/src/Testcontainers.Camunda/Testcontainers.Camunda.csproj b/src/Testcontainers.Camunda/Testcontainers.Camunda.csproj
new file mode 100644
index 000000000..0bc118e7c
--- /dev/null
+++ b/src/Testcontainers.Camunda/Testcontainers.Camunda.csproj
@@ -0,0 +1,12 @@
+
+
+ net6.0;net8.0;netstandard2.0;netstandard2.1
+ latest
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Testcontainers.Camunda/Usings.cs b/src/Testcontainers.Camunda/Usings.cs
new file mode 100644
index 000000000..79fd3af9b
--- /dev/null
+++ b/src/Testcontainers.Camunda/Usings.cs
@@ -0,0 +1,6 @@
+global using System;
+global using Docker.DotNet.Models;
+global using DotNet.Testcontainers.Builders;
+global using DotNet.Testcontainers.Configurations;
+global using DotNet.Testcontainers.Containers;
+global using JetBrains.Annotations;
\ No newline at end of file
diff --git a/tests/Testcontainers.Camunda.Tests/.editorconfig b/tests/Testcontainers.Camunda.Tests/.editorconfig
new file mode 100644
index 000000000..6f066619d
--- /dev/null
+++ b/tests/Testcontainers.Camunda.Tests/.editorconfig
@@ -0,0 +1 @@
+root = true
\ No newline at end of file
diff --git a/tests/Testcontainers.Camunda.Tests/CamundaContainerTest.cs b/tests/Testcontainers.Camunda.Tests/CamundaContainerTest.cs
new file mode 100644
index 000000000..d7ce89d69
--- /dev/null
+++ b/tests/Testcontainers.Camunda.Tests/CamundaContainerTest.cs
@@ -0,0 +1,31 @@
+namespace Testcontainers.Camunda;
+
+public sealed class CamundaContainerTest : IAsyncLifetime
+{
+ private readonly CamundaContainer _camundaContainer = new CamundaBuilder().Build();
+
+ public Task InitializeAsync()
+ {
+ return _camundaContainer.StartAsync();
+ }
+
+ public Task DisposeAsync()
+ {
+ return _camundaContainer.DisposeAsync().AsTask();
+ }
+
+ [Fact]
+ [Trait(nameof(DockerCli.DockerPlatform), nameof(DockerCli.DockerPlatform.Linux))]
+ public async Task EstablishesConnection()
+ {
+ // Given
+ var client = CamundaClient.Create(_camundaContainer.GetConnectionString());
+
+ // When
+ var response = (await client.ProcessDefinitions.Query(new ProcessDefinitionQuery()).List())
+ .Select(x => x.Resource);
+
+ // Then
+ Assert.Equal(new[] { "reviewInvoice.bpmn", "invoice.v1.bpmn", "invoice.v2.bpmn" }, response);
+ }
+}
\ No newline at end of file
diff --git a/tests/Testcontainers.Camunda.Tests/Testcontainers.Camunda.Tests.csproj b/tests/Testcontainers.Camunda.Tests/Testcontainers.Camunda.Tests.csproj
new file mode 100644
index 000000000..b187bc095
--- /dev/null
+++ b/tests/Testcontainers.Camunda.Tests/Testcontainers.Camunda.Tests.csproj
@@ -0,0 +1,18 @@
+
+
+ net8.0
+ false
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/Testcontainers.Camunda.Tests/Usings.cs b/tests/Testcontainers.Camunda.Tests/Usings.cs
new file mode 100644
index 000000000..c090a7b57
--- /dev/null
+++ b/tests/Testcontainers.Camunda.Tests/Usings.cs
@@ -0,0 +1,7 @@
+global using System;
+global using System.Linq;
+global using System.Threading.Tasks;
+global using Camunda.Api.Client;
+global using Camunda.Api.Client.ProcessDefinition;
+global using DotNet.Testcontainers.Commons;
+global using Xunit;