我有一个Dockerfile字符串_dockerfile
,用作生成其他Dockerfile的模板。我正在尝试使用生成的模板_dockerfile
字符串并将其打包在内存中,作为Docker API的流。 Docker守护程序要求流是/build
端点上的documentation的tar流:
输入流必须是使用以下算法之一压缩的tar归档文件:身份(无压缩),gzip,bzip2,xz
我目前正在使用SharpZipLib库来构建它:
public async Task BuildAsync() {
using (var inputMs = new MemoryStream(Encoding.ASCII.GetBytes(_dockerfile))) {
var outputMs = new MemoryStream() as Stream;
// Docker.DotNet.DockerClient.BuildImageFromDockerfileAsync requires a Stream in order to send it to the Docker daemon.
var builderStream = await _client.Images.BuildImageFromDockerfileAsync(CreateContext(inputMs, outputMs), new ImageBuildParameters() { Dockerfile = ".", Tags = new string[] { "test/test:latest" } });
using (var sr = new StreamReader(builderStream)) {
while (sr.Peek() > -1) {
var output = await sr.ReadLineAsync();
Console.WriteLine(output);
}
}
}
}
private Stream CreateContext(Stream input, Stream output) {
var tarOutputStream = new TarOutputStream(output);
var entry = TarEntry.CreateTarEntry("Dockerfile");
entry.Size = input.Length;
tarOutputStream.PutNextEntry(entry);
// read from the input stream, write to the local buffer,
// then write to the file.
var buffer = new byte[32 * 1024];
while (true) {
int numRead = input.Read(buffer, 0, buffer.Length);
if (numRead <= 0)
break;
tarOutputStream.Write(buffer, 0, numRead);
}
tarOutputStream.CloseEntry();
return tarOutputStream;
}
当我运行它时,出现此错误:
Docker.DotNet.DockerApiException: Docker API responded with status code=InternalServerError, response={"message":"unexpected error reading Dockerfile: read /var/lib/docker/tmp/docker-builder534485209: is a directory"}
我认为发生的事情是因为我尚未关闭tar存档流,而是试图从守护程序的内存中读取?无论哪种方式,我都知道我必须更好地处理流管道。
如何在不写入磁盘的情况下将内存中的字符串转换为tar流?