1
0

Add script and instruction to build all the docker images by yourself

This commit is contained in:
nicolas.dorier
2018-12-02 13:32:01 +09:00
parent a52b65e459
commit c9a0454034
11 changed files with 630 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace DockerFileBuildHelper
{
public class DockerFile
{
public string DockerFileName { get; private set; }
public string DockerFilePath { get; private set; }
public static DockerFile Parse(string str)
{
var file = new DockerFile();
var lastPart = str.LastIndexOf('/');
file.DockerFileName = str.Substring(lastPart + 1);
if (lastPart == -1)
{
file.DockerFilePath = ".";
}
else
{
file.DockerFilePath = str.Substring(0, lastPart);
}
return file;
}
}
}

View File

@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="5.2.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace DockerFileBuildHelper
{
public class DockerInfo
{
public string DockerFilePath { get; set; }
public string DockerFilePathARM32v7 { get; set; }
public string DockerFilePathARM64v8 { get; set; }
public string DockerHubLink { get; set; }
public string GitLink { get; set; }
public string GitRef { get; set; }
public Image Image { get; internal set; }
public string GetGithubLinkOf(string path)
{
return $"https://raw.githubusercontent.com/{GitLink.Substring("https://github.com/".Length)}/{GitRef}/{path}";
}
}
}

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Text;
using YamlDotNet.RepresentationModel;
namespace DockerFileBuildHelper
{
public static class Extensions
{
public static YamlNode TryGet(this YamlNode node, string key)
{
try
{
return node[key];
}
catch (KeyNotFoundException) { return null; }
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
namespace DockerFileBuildHelper
{
public class Image
{
public string User { get; private set; }
public string Name { get; private set; }
public string Tag { get; private set; }
public string DockerHubLink
{
get
{
return User == string.Empty ?
$"https://hub.docker.com/_/{Name}" :
$"https://hub.docker.com/r/{User}/{Name}";
}
}
public static Image Parse(string str)
{
//${BTCPAY_IMAGE: -btcpayserver / btcpayserver:1.0.3.21}
var variableMatch = Regex.Match(str, @"\$\{[^-]+-([^\}]+)\}");
if(variableMatch.Success)
{
str = variableMatch.Groups[1].Value;
}
Image img = new Image();
var match = Regex.Match(str, "([^/]*/)?([^:]+):?(.*)");
if (!match.Success)
throw new FormatException();
img.User = match.Groups[1].Length == 0 ? string.Empty : match.Groups[1].Value.Substring(0, match.Groups[1].Value.Length - 1);
img.Name = match.Groups[2].Value;
img.Tag = match.Groups[3].Value;
if (img.Tag == string.Empty)
img.Tag = "latest";
return img;
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
if (!String.IsNullOrWhiteSpace(User))
builder.Append($"{User}/");
builder.Append($"{Name}");
if (!String.IsNullOrWhiteSpace(Tag))
builder.Append($":{Tag}");
return builder.ToString();
}
}
}

View File

@@ -0,0 +1,271 @@
using System;
using YamlDotNet;
using YamlDotNet.Helpers;
using System.Linq;
using System.Collections.Generic;
using System.IO;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
using System.Net.Http;
using System.Threading.Tasks;
using System.Text;
namespace DockerFileBuildHelper
{
class Program
{
static int Main(string[] args)
{
string outputFile = null;
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "-o")
outputFile = args[i + 1];
}
return new Program().Run(outputFile) ? 0 : 1;
}
private bool Run(string outputFile)
{
var fragmentDirectory = Path.GetFullPath(Path.Combine(FindRoot("contrib"), "..", "docker-compose-generator", "docker-fragments"));
List<Task<bool>> downloading = new List<Task<bool>>();
List<DockerInfo> dockerInfos = new List<DockerInfo>();
foreach(var image in new[]
{
Image.Parse("btcpayserver/docker-compose-generator"),
Image.Parse("btcpayserver/docker-compose-builder:1.23.2"),
}.Concat(GetImages(fragmentDirectory)))
{
Console.WriteLine($"Image: {image.ToString()}");
var info = GetDockerInfo(image);
if (info == null)
{
Console.WriteLine($"Missing image info: {image}");
return false;
}
dockerInfos.Add(info);
downloading.Add(CheckLink(info, info.DockerFilePath));
downloading.Add(CheckLink(info, info.DockerFilePathARM32v7));
downloading.Add(CheckLink(info, info.DockerFilePathARM64v8));
}
Task.WaitAll(downloading.ToArray());
var canDownloadEverything = downloading.All(o => o.Result);
if (!canDownloadEverything)
return false;
StringBuilder builder = new StringBuilder();
builder.AppendLine("#!/bin/bash");
builder.AppendLine();
builder.AppendLine("# This file is automatically generated by the DockerFileBuildHelper tool, run DockerFileBuildHelper/update-repo.sh to update it");
builder.AppendLine("set -e");
foreach (var info in dockerInfos)
{
builder.AppendLine($"# Build {info.Image.Name}");
builder.AppendLine($"git clone {info.GitLink} {info.Image.Name}");
var dockerFile = DockerFile.Parse($"{info.DockerFilePath ?? info.DockerFilePathARM32v7 ?? info.DockerFilePathARM64v8}");
builder.AppendLine($"cd {info.Image.Name}");
builder.AppendLine($"git checkout {info.GitRef}");
builder.AppendLine($"cd {dockerFile.DockerFilePath}");
builder.AppendLine($"docker build -f \"{dockerFile.DockerFileName}\" -t \"{info.Image}\" .");
builder.AppendLine($"cd - && cd ..");
builder.AppendLine();
builder.AppendLine();
}
var script = builder.ToString().Replace("\r\n", "\n");
if (string.IsNullOrEmpty(outputFile))
outputFile = "build-all.sh";
File.WriteAllText(outputFile, script);
Console.WriteLine($"Generated file \"{Path.GetFullPath(outputFile)}\"");
return true;
}
HttpClient client = new HttpClient();
private async Task<bool> CheckLink(DockerInfo info, string path)
{
if (path == null)
return true;
var link = info.GetGithubLinkOf(path);
var resp = await client.GetAsync(link);
if(!resp.IsSuccessStatusCode)
{
Console.WriteLine($"\tBroken link detected for image {info.Image} ({link})");
return false;
}
return true;
}
private IEnumerable<Image> GetImages(string fragmentDirectory)
{
var deserializer = new DeserializerBuilder().Build();
var serializer = new SerializerBuilder().Build();
foreach (var file in Directory.EnumerateFiles(fragmentDirectory, "*.yml"))
{
var root = ParseDocument(file);
if (root.TryGet("services") == null)
continue;
foreach (var service in ((YamlMappingNode)root["services"]).Children)
{
var imageStr = service.Value.TryGet("image");
if (imageStr == null)
continue;
var image = Image.Parse(imageStr.ToString());
yield return image;
}
}
}
private DockerInfo GetDockerInfo(Image image)
{
DockerInfo dockerInfo = new DockerInfo();
switch (image.Name)
{
case "btglnd":
dockerInfo.DockerFilePath = "BTCPayServer.Dockerfile";
dockerInfo.GitLink = "https://github.com/vutov/lnd";
dockerInfo.GitRef = "master";
break;
case "docker-compose-builder":
dockerInfo.DockerFilePathARM32v7 = "linuxarm32v7.Dockerfile";
dockerInfo.GitLink = "https://github.com/btcpayserver/docker-compose-builder";
dockerInfo.GitRef = $"v{image.Tag}";
break;
case "docker-compose-generator":
dockerInfo.DockerFilePath = "docker-compose-generator/linuxamd64.Dockerfile";
dockerInfo.DockerFilePathARM32v7 = "docker-compose-generator/linuxarm32v7.Dockerfile";
dockerInfo.GitLink = "https://github.com/btcpayserver/btcpayserver-docker";
dockerInfo.GitRef = $"dcg-latest";
break;
case "docker-bitcoingold":
dockerInfo.DockerFilePath = $"bitcoingold/{image.Tag}/Dockerfile";
dockerInfo.GitLink = "https://github.com/Vutov/docker-bitcoin";
dockerInfo.GitRef = "master";
break;
case "clightning":
dockerInfo.DockerFilePath = $"Dockerfile";
dockerInfo.GitLink = "https://github.com/NicolasDorier/lightning";
dockerInfo.GitRef = $"basedon-{image.Tag}";
break;
case "lnd":
dockerInfo.DockerFilePath = "BTCPayServer.Dockerfile";
dockerInfo.GitLink = "https://github.com/btcpayserver/lnd";
dockerInfo.GitRef = $"basedon-v{image.Tag}";
break;
case "bitcoin":
dockerInfo.DockerFilePath = $"Bitcoin/{image.Tag}/linuxamd64.Dockerfile";
dockerInfo.DockerFilePathARM32v7 = $"Bitcoin/{image.Tag}/linuxarm32v7.Dockerfile";
dockerInfo.DockerFilePathARM64v8 = $"Bitcoin/{image.Tag}/linuxarm64v8.Dockerfile";
dockerInfo.GitLink = "https://github.com/btcpayserver/dockerfile-deps";
dockerInfo.GitRef = $"Bitcoin/{image.Tag}";
break;
case "btcpayserver":
dockerInfo.DockerFilePath = "Dockerfile.linuxamd64";
dockerInfo.DockerFilePathARM32v7 = "Dockerfile.linuxarm32v7";
dockerInfo.GitLink = "https://github.com/btcpayserver/btcpayserver";
dockerInfo.GitRef = $"v{image.Tag}";
break;
case "nbxplorer":
dockerInfo.DockerFilePath = "Dockerfile.linuxamd64";
dockerInfo.DockerFilePathARM32v7 = "Dockerfile.linuxarm32v7";
dockerInfo.GitLink = "https://github.com/dgarage/nbxplorer";
dockerInfo.GitRef = $"v{image.Tag}";
break;
case "dogecoin":
dockerInfo.DockerFilePath = $"dogecoin/{image.Tag}/Dockerfile";
dockerInfo.GitLink = "https://github.com/rockstardev/docker-bitcoin";
dockerInfo.GitRef = "feature/dogecoin";
break;
case "docker-feathercoin":
dockerInfo.DockerFilePath = $"feathercoin/{image.Tag}/Dockerfile";
dockerInfo.GitLink = "https://github.com/ChekaZ/docker";
dockerInfo.GitRef = "master";
break;
case "docker-groestlcoin":
dockerInfo.DockerFilePath = $"groestlcoin/{image.Tag}/Dockerfile";
dockerInfo.GitLink = "https://github.com/NicolasDorier/docker-bitcoin";
dockerInfo.GitRef = "master";
break;
case "docker-viacoin":
dockerInfo.DockerFilePath = $"viacoin/{image.Tag}/docker-viacoin";
dockerInfo.GitLink = "https://github.com/viacoin/docker-viacoin";
dockerInfo.GitRef = "master";
break;
case "docker-litecoin":
dockerInfo.DockerFilePath = $"litecoin/{image.Tag}/Dockerfile";
dockerInfo.GitLink = "https://github.com/NicolasDorier/docker-bitcoin";
dockerInfo.GitRef = "master";
break;
case "docker-monacoin":
dockerInfo.DockerFilePath = $"monacoin/{image.Tag}/Dockerfile";
dockerInfo.GitLink = "https://github.com/wakiyamap/docker-bitcoin";
dockerInfo.GitRef = "master";
break;
case "nginx":
dockerInfo.DockerFilePath = $"stable/stretch/Dockerfile";
dockerInfo.GitLink = "https://github.com/nginxinc/docker-nginx";
dockerInfo.GitRef = $"master";
break;
case "docker-gen":
dockerInfo.DockerFilePath = $"linuxamd64.Dockerfile";
dockerInfo.DockerFilePathARM32v7 = $"linuxarm32v7.Dockerfile";
dockerInfo.GitLink = "https://github.com/btcpayserver/docker-gen";
dockerInfo.GitRef = $"v{image.Tag}";
break;
case "letsencrypt-nginx-proxy-companion":
dockerInfo.DockerFilePath = $"linuxamd64.Dockerfile";
dockerInfo.DockerFilePathARM32v7 = $"linuxarm32v7.Dockerfile";
dockerInfo.GitLink = "https://github.com/btcpayserver/docker-letsencrypt-nginx-proxy-companion";
dockerInfo.GitRef = $"v{image.Tag}";
break;
case "postgres":
dockerInfo.DockerFilePath = $"9.6/Dockerfile";
dockerInfo.DockerFilePathARM32v7 = $"9.6/Dockerfile";
dockerInfo.GitLink = "https://github.com/docker-library/postgres";
dockerInfo.GitRef = $"b7cb3c6eacea93be2259381033be3cc435649369";
break;
case "traefik":
dockerInfo.DockerFilePath = $"scratch/amd64/Dockerfile";
dockerInfo.DockerFilePathARM32v7 = $"scratch/arm/Dockerfile";
dockerInfo.GitLink = "https://github.com/containous/traefik-library-image";
dockerInfo.GitRef = $"master";
break;
default:
return null;
}
dockerInfo.DockerHubLink = image.DockerHubLink;
dockerInfo.Image = image;
return dockerInfo;
}
private YamlMappingNode ParseDocument(string fragment)
{
var input = new StringReader(File.ReadAllText(fragment));
YamlStream stream = new YamlStream();
stream.Load(input);
return (YamlMappingNode)stream.Documents[0].RootNode;
}
private static void DeleteDirectory(string outputDirectory)
{
try
{
Directory.Delete(outputDirectory, true);
}
catch
{
}
}
private static string FindRoot(string rootDirectory)
{
string directory = Directory.GetCurrentDirectory();
int i = 0;
while (true)
{
if (i > 10)
throw new DirectoryNotFoundException(rootDirectory);
if (directory.EndsWith(rootDirectory))
return directory;
directory = Path.GetFullPath(Path.Combine(directory, ".."));
i++;
}
}
}
}

View File

@@ -0,0 +1,16 @@
# DockerFile build helper
By default, when you use docker deployment, you are fetching pre-built docker images hosted on dockerhub.
While this bring the advantage that deployment is fast and reliable, this also mean that you are ultimately trusting the owner of the docker images.
This repository generate a script that you can use to build all images from the sources by yourself.
## How to use?
Install [.NET Core SDK](https://dotnet.microsoft.com/download) and run:
```bash
./run.sh
```
This will build a `build-all.sh` file.
Note that the

View File

@@ -0,0 +1,3 @@
#!/bin/bash
dotnet run --no-launch-profile -c Release -- $@

View File

@@ -0,0 +1 @@
dotnet run --no-launch-profile -c Release -- -o "../build-all-images.sh"

View File

@@ -0,0 +1,3 @@
#!/bin/bash
dotnet run --no-launch-profile -c Release -- -o "../build-all-images.sh"