Use docker, docker-compose local and remote in tests and your .NET core/full framework apps via a FluentAPI
Support for docker-compose
v2 when using "standard" docker daemon. This is due to that docker-compose v2 do not support -H (uses docker context instead).
Fixed CVE-2021-39208 by upgrading SharpCompress.
This requires to drop the support for netstandard1.6 since SharpCompress did drop it.
Please file an Issue if any problems occur due to this!
Cheers, Mario :)
DeleteIfExists(bool removeVolumes = true, bool force = false, string removeLink = null)
It ensures that a container is deleted before creating. Hence the inverse ReuseIfExists()
.
var name = Guid.NewGuid().ToString();
var container = Fd.UseContainer()
.UseImage("postgres:9.6-alpine")
.WithName($"name-{name}")
.Build();
var id = container.Id;
using (var c = Fd
.UseContainer()
.DeleteIfExists()
.UseImage("postgres:9.6-alpine")
.WithName($"name-{name}")
.Build())
{
// Ids should not be equal - since deleted and then created.
AreNotEqual(id, c.Id);
}
This exposes the DateTime
when the container was created.
It is now possible to do UseProjectDirectory()
in the CompositeBuilder
to specify a project directory. This was implemented in PR #217 and brought up in Issue #216.
Added a Example
solution to start showing some simple solutions instead of, possibly, complex unit test to understand how to use this library.
Simplified Trace and support for routing to any logging framework. For example, like this.
Fixed bug: On macOS, tests running the envtest.sh
script would fail with a permission denied exception because the script is not exectuable
Allow to PublishAllPorts
instead of explicit portmappings as a shorthand. Added ExposeAllPorts
.
Hide real exeption when throwOnError
in a container export is fixed.
Fixes many typos
Added a Ductus.FluentDocker.XUnit NuGet package to be used when doing XUnit testing instead of mstest.
This is a fix for the CVE-2018-8292. See GitHUB Advisory for more information.
You're strongly advised to update to this release!
This release fixes the COPY
command in the docker file builder that did not double quote filenames in the JSON array.
Added a limited support to use the FluentAPI to talk to a remote docker daemon without using docker-machine. This is done either by manually creating a instance of a DockerHostService
or use FromUri
on HostBuilder
.
using(var container = Fd.UseHost().
FromUri(Settings.DockerUri, isWindowsHost: true).
UseContainer().
Build())
{
}
The above sample connects to a custom DockerUri
from a setting and is a windows container docker daemon.
FromUri
that uses a DockerUri
to create a IHostService
. This uri is arbitrary. It also support other properties (see below). public HostBuilder FromUri(
DockerUri uri,
string name = null,
bool isNative = true,
bool stopWhenDisposed = false,
bool isWindowsHost = false,
string certificatePath = null) {/*...*/}
It will use "sensible" defaults on all parameters. Most of the case the uri is sufficient. For example if not providing the certificatePath it will try to get it from the environment DOCKER_CERT_PATH. If not found in the environment, it will default to none.
UseHost
that takes a instantiated IHostService
implementation.This release just adds a single functionality - Ability to provide with a custome endpoint resolver on a ContainerBuilder
. This solves issue #107.
If the resolver returns null
or is null on the container service, it will use the default mechanism to resolve the IP endpoint.
It can be used in the following manner.
using (
var container =
Fd.UseContainer()
.UseImage("postgres:9.6-alpine")
.WithEnvironment("POSTGRES_PASSWORD=mysecretpassword")
.ExposePort(5432)
.UseCustomResolver((
ports, portAndProto, dockerUri) =>
{
if (null == ports || string.IsNullOrEmpty(portAndProto))
return null;
if (!ports.TryGetValue(portAndProto, out var endpoints))
return null;
if (null == endpoints || endpoints.Length == 0)
return null;
if (CommandExtensions.IsNative())
return endpoints[0];
if (CommandExtensions.IsEmulatedNative())
return CommandExtensions.IsDockerDnsAvailable()
? new IPEndPoint(CommandExtensions.EmulatedNativeAddress(), endpoints[0].Port)
: new IPEndPoint(IPAddress.Loopback, endpoints[0].Port);
if (Equals(endpoints[0].Address, IPAddress.Any) && null != dockerUri)
return new IPEndPoint(IPAddress.Parse(dockerUri.Host), endpoints[0].Port);
return endpoints[0];
})
.WaitForPort("5432/tcp", 30000 /*30s*/)
.Build()
.Start())
{
var state = container.GetConfiguration(true/*force*/).State.ToServiceState();
Assert.AreEqual(ServiceRunningState.Running, state);
}
This release adds a few features and a handful of bugfixes.
This Release adds a few enhancements to the FileBuilder
to support all dockerfile
commands an fixes a few bugs .
This adds the following commands:
Modified:
Issues: #177 #178 and #179 via PR #180
It is now possible, in ImageBuilder
to do From(string imageAndTag, string asName)
and hence render a FROM image:label AS myimage.
Added simple support to provide an URL instead of a local filepath when using FileBuilder
. It will download the resource and add it to a COPY instruction.
var dockerfile = Fd.Dockerfile()
.UseParent("node:12.18.1")
.Environment("NODE_ENV=production")
.Run("npm install --production")
.Copy(
"https://www.my.com/path/myresource.js",
"/server.js")
.Copy("Resources/Issue/111/server.py", "/server.py")
.Command("node", "server.js").ToDockerfileString();
The above example, copies the myresource.js from https://www.my.com/path to the docker container root /server.js.
Fd().UseContainer()
.UseImage("kiasaki/alpine-postgres")
.WithEnvironment($"POSTGRES_PASSWORD={PostgresPassword}")
.ExposePort(5432)
.ExposePort(8192,8800,"udp")
.WaitForPort("5432/tcp", 30000 /*30s*/);
The ExposePort(int hostPort, int containerPort, string protocol = "tcp")
defaults to tcp but can accept any protocol. Currently docker only support udp.
New Features
Bug FIxes:
This is a minor update release with some new functionality and a few bugfixes. Most noably:
Added
WithHostName("my custom hostname")
on the ContainerBuilder
.
Added SHELL and COPY on filebuilder to build a Dockerfile. Therefore it is now possible
to write e.g. this in a FileBuilder
Fd.DefineImage("mariotoffia/issue111").ReuseIfAlreadyExists()
.From("microsoft/windowsservercore:1607")
.Shell("powershell", "-Command", "$ErrorActionPreference = 'Stop';")
.Run("powershell [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; exit 0")
.Run(
"Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))")
.Run("choco feature enable --name=allowGlobalConfirmation")
.Run("choco install python3")
.Copy("Resources/Issue/111/server.py", "C:/")
.ExposePorts(8000)
.Command("python", "server.py")
.Builder().UseContainer().UseImage("mariotoffia/issue111")
.WaitForProcess("python.exe", (long) TimeSpan.FromSeconds(30).TotalMilliseconds)
.Builder()
.Build()
.Start()
Added support in TemplateString
to distinguish from http(s) URLS and filepaths when doing modifications on windows systems.
Added IEngineScope
to allow for using a certain docker engine within a IDisposable
clause. It will switch to the engine choosen
and switch back (if needed) to the old engine upon Dispose()
. This is useful in windows environment where a set of images of both
Linux and Windows may be executed. An example:
using (var scope = Fd.EngineScope(EngineScopeType.Windows))
{
using(var win = Fd...)
{
}
}
Fixed bug where WaitForProcess
did not work for Windows containers.
Altered Behaviour on ContainerServiceRemove
where it will not Stop()
the container unless force = true
Added support for Pause
and Resume
(invoke Start
again) on both IContainerService´ and
ICompositeContainerService`
and therefore allow for a single docker container or all containers to be paused and resumed. For example:
using (
var container =
Fd.UseContainer()
.UseImage("postgres:9.6-alpine")
.ExposePort(40001, 5432)
.WithEnvironment("POSTGRES_PASSWORD=mysecretpassword")
.Build()
.Start())
{
AreEqual(ServiceRunningState.Running, container.State);
container.Pause();
AreEqual(ServiceRunningState.Paused, container.State);
var config = container.GetConfiguration(true);
AreEqual(ServiceRunningState.Paused, config.State.ToServiceState());
container.Start();
AreEqual(ServiceRunningState.Running, container.State);
config = container.GetConfiguration(true);
AreEqual(ServiceRunningState.Running, config.State.ToServiceState());
}
Added support for netstandard2.1 and therefore works in netcoreapp3.x
Added ability to keep containers and keeprunning in composite services. Earlier those where all killed. For example keep containers (but stop) on dispose may look like this
var file = Path.Combine(Directory.GetCurrentDirectory(),
(TemplateString) "Resources/ComposeTests/WordPress/docker-compose.yml");
ICompositeService svc = null;
IContainerService c1 = null;
IContainerService c2 = null;
try
{
svc = Fd
.UseContainer()
.UseCompose()
.FromFile(file)
.RemoveOrphans()
.KeepContainer()
.Build().Start();
c1 = svc.Containers.First();
c2 = svc.Containers.Skip(1).First();
svc.Dispose();
Assert.AreEqual(ServiceRunningState.Stopped, c1.State);
Assert.AreEqual(ServiceRunningState.Stopped, c2.State);
}
finally
{
svc?.Dispose();
c1?.Remove(true);
c2?.Remove(true);
}