mirror of
https://github.com/Retropex/btcpayserver-docker.git
synced 2025-05-13 05:20:40 +02:00
Refactor docker-compose-generator so that generation can be dynamic
This commit is contained in:
parent
bbb0d650b1
commit
045debafec
1
.gitignore
vendored
1
.gitignore
vendored
@ -295,3 +295,4 @@ BTCPayServer/wwwroot/bundles/*
|
|||||||
Production/.env
|
Production/.env
|
||||||
.env
|
.env
|
||||||
.vscode/
|
.vscode/
|
||||||
|
/docker-compose.generated.yml
|
||||||
|
@ -13,6 +13,8 @@ RUN mkdir /datadir
|
|||||||
ENV APP_DATADIR=/datadir
|
ENV APP_DATADIR=/datadir
|
||||||
VOLUME /datadir
|
VOLUME /datadir
|
||||||
|
|
||||||
|
ENV INSIDE_CONTAINER=1
|
||||||
|
|
||||||
COPY --from=builder "/app" .
|
COPY --from=builder "/app" .
|
||||||
COPY docker-fragments docker-fragments
|
COPY docker-fragments docker-fragments
|
||||||
|
|
||||||
|
44
docker-compose-generator/src/CryptoDefinition.cs
Normal file
44
docker-compose-generator/src/CryptoDefinition.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace DockerGenerator
|
||||||
|
{
|
||||||
|
public class CryptoDefinition
|
||||||
|
{
|
||||||
|
public string Crypto
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
public string CryptoFragment
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
public string CLightningFragment
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static CryptoDefinition[] GetDefinitions()
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
new CryptoDefinition()
|
||||||
|
{
|
||||||
|
Crypto = "ltc",
|
||||||
|
CryptoFragment = "litecoin",
|
||||||
|
CLightningFragment = "litecoin-clightning",
|
||||||
|
},
|
||||||
|
new CryptoDefinition()
|
||||||
|
{
|
||||||
|
Crypto = "btc",
|
||||||
|
CryptoFragment = "bitcoin",
|
||||||
|
CLightningFragment = "bitcoin-clightning",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
41
docker-compose-generator/src/DockerComposition.cs
Normal file
41
docker-compose-generator/src/DockerComposition.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace DockerGenerator
|
||||||
|
{
|
||||||
|
public class DockerComposition
|
||||||
|
{
|
||||||
|
public HashSet<string> SelectedCryptos
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
public string SelectedProxy
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
public string SelectedLN
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DockerComposition FromEnvironmentVariables()
|
||||||
|
{
|
||||||
|
DockerComposition composition = new DockerComposition();
|
||||||
|
composition.SelectedCryptos = new HashSet<string>();
|
||||||
|
for(int i = 1; i < 10; i++)
|
||||||
|
{
|
||||||
|
var selectedCrypto = Environment.GetEnvironmentVariable("BTCPAYGEN_CRYPTO" + i);
|
||||||
|
if(string.IsNullOrEmpty(selectedCrypto))
|
||||||
|
break;
|
||||||
|
composition.SelectedCryptos.Add(selectedCrypto.ToLowerInvariant());
|
||||||
|
}
|
||||||
|
composition.SelectedProxy = (Environment.GetEnvironmentVariable("BTCPAYGEN_REVERSEPROXY") ?? "").ToLowerInvariant();
|
||||||
|
composition.SelectedLN = (Environment.GetEnvironmentVariable("BTCPAYGEN_LIGHTNING") ?? "").ToLowerInvariant();
|
||||||
|
return composition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,108 +8,99 @@ namespace DockerGenerator
|
|||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
new Program().Run();
|
var root = Environment.GetEnvironmentVariable("INSIDE_CONTAINER") == "1" ? FindRoot("app")
|
||||||
|
: Path.GetFullPath(Path.Combine(FindRoot("docker-compose-generator"), ".."));
|
||||||
|
|
||||||
|
if(args.Any(a => a == "pregen"))
|
||||||
|
{
|
||||||
|
var productionLocation = Path.GetFullPath(Path.Combine(root, "Production"));
|
||||||
|
var testLocation = Path.GetFullPath(Path.Combine(root, "Production-NoReverseProxy"));
|
||||||
|
|
||||||
|
foreach(var proxy in new[] { "nginx", "no-reverseproxy" })
|
||||||
|
{
|
||||||
|
foreach(var lightning in new[] { "clightning", "" })
|
||||||
|
{
|
||||||
|
foreach(var btc in new[] { "btc", "" })
|
||||||
|
{
|
||||||
|
foreach(var ltc in new[] { "ltc", "" })
|
||||||
|
{
|
||||||
|
if(btc == "" && ltc == "")
|
||||||
|
continue;
|
||||||
|
string name = $"{btc}-{ltc}-{lightning}".Replace("--", "-");
|
||||||
|
if(name.EndsWith("-"))
|
||||||
|
name = name.Substring(0, name.Length - 1);
|
||||||
|
if(name.StartsWith("-"))
|
||||||
|
name = name.Substring(1, name.Length - 1);
|
||||||
|
var composition = new DockerComposition();
|
||||||
|
composition.SelectedCryptos = new HashSet<string>();
|
||||||
|
composition.SelectedCryptos.Add(btc);
|
||||||
|
composition.SelectedCryptos.Add(ltc);
|
||||||
|
composition.SelectedLN = lightning;
|
||||||
|
composition.SelectedProxy = proxy;
|
||||||
|
new Program().Run(composition, name, proxy == "nginx" ? productionLocation : testLocation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var composition = DockerComposition.FromEnvironmentVariables();
|
||||||
|
Console.WriteLine("Crypto: " + string.Join(", ", composition.SelectedCryptos.ToArray()));
|
||||||
|
Console.WriteLine("Lightning: " + composition.SelectedLN);
|
||||||
|
Console.WriteLine("ReverseProxy: " + composition.SelectedProxy);
|
||||||
|
new Program().Run(composition, "generated", root);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Run()
|
private void Run(DockerComposition composition, string name, string output)
|
||||||
{
|
{
|
||||||
var fragmentLocation = FindLocation("docker-fragments");
|
var fragmentLocation = Environment.GetEnvironmentVariable("INSIDE_CONTAINER") == "1" ? "app" : "docker-compose-generator";
|
||||||
var productionLocation = FindLocation("Production");
|
fragmentLocation = FindRoot(fragmentLocation);
|
||||||
var testLocation = FindLocation("Production-NoReverseProxy");
|
fragmentLocation = Path.GetFullPath(Path.Combine(fragmentLocation, "docker-fragments"));
|
||||||
|
|
||||||
HashSet<string> processed = new HashSet<string>();
|
var fragments = new List<string>();
|
||||||
foreach(var permutation in ItemCombinations(new[] { "btc", "ltc", "clightning" }.ToList()))
|
if(composition.SelectedProxy == "nginx")
|
||||||
{
|
{
|
||||||
if(permutation.Count == 1 && permutation.First() == "clightning")
|
|
||||||
continue;
|
|
||||||
permutation.Sort();
|
|
||||||
if(permutation.Remove("clightning"))
|
|
||||||
permutation.Add("clightning"); // ensure clightning at the end
|
|
||||||
string id = string.Join('-', permutation);
|
|
||||||
if(!processed.Add(id))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
var fragments = new List<string>();
|
|
||||||
fragments.Add("nginx");
|
fragments.Add("nginx");
|
||||||
fragments.Add("btcpayserver");
|
|
||||||
|
|
||||||
if(permutation.Contains("ltc"))
|
|
||||||
{
|
|
||||||
fragments.Add("litecoin");
|
|
||||||
if(permutation.Contains("clightning"))
|
|
||||||
fragments.Add("litecoin-clightning");
|
|
||||||
}
|
|
||||||
if(permutation.Contains("btc"))
|
|
||||||
{
|
|
||||||
fragments.Add("bitcoin");
|
|
||||||
if(permutation.Contains("clightning"))
|
|
||||||
fragments.Add("bitcoin-clightning");
|
|
||||||
}
|
|
||||||
|
|
||||||
var def = new DockerComposeDefinition(id, fragments);
|
|
||||||
def.FragmentLocation = fragmentLocation;
|
|
||||||
def.BuildOutputDirectory = productionLocation;
|
|
||||||
def.Build();
|
|
||||||
|
|
||||||
|
|
||||||
def.Fragments.Remove("nginx");
|
|
||||||
def.Fragments.Add("btcpayserver-noreverseproxy");
|
|
||||||
def.BuildOutputDirectory = testLocation;
|
|
||||||
def.Build();
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Method to create lists containing possible combinations of an input list of items. This is
|
|
||||||
/// basically copied from code by user "jaolho" on this thread:
|
|
||||||
/// http://stackoverflow.com/questions/7802822/all-possible-combinations-of-a-list-of-values
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T">type of the items on the input list</typeparam>
|
|
||||||
/// <param name="inputList">list of items</param>
|
|
||||||
/// <param name="minimumItems">minimum number of items wanted in the generated combinations,
|
|
||||||
/// if zero the empty combination is included,
|
|
||||||
/// default is one</param>
|
|
||||||
/// <param name="maximumItems">maximum number of items wanted in the generated combinations,
|
|
||||||
/// default is no maximum limit</param>
|
|
||||||
/// <returns>list of lists for possible combinations of the input items</returns>
|
|
||||||
public static List<List<T>> ItemCombinations<T>(List<T> inputList, int minimumItems = 1,
|
|
||||||
int maximumItems = int.MaxValue)
|
|
||||||
{
|
|
||||||
int nonEmptyCombinations = (int)Math.Pow(2, inputList.Count) - 1;
|
|
||||||
List<List<T>> listOfLists = new List<List<T>>(nonEmptyCombinations + 1);
|
|
||||||
|
|
||||||
if(minimumItems == 0) // Optimize default case
|
|
||||||
listOfLists.Add(new List<T>());
|
|
||||||
|
|
||||||
for(int i = 1; i <= nonEmptyCombinations; i++)
|
|
||||||
{
|
{
|
||||||
List<T> thisCombination = new List<T>(inputList.Count);
|
fragments.Add("btcpayserver-noreverseproxy");
|
||||||
for(int j = 0; j < inputList.Count; j++)
|
}
|
||||||
{
|
fragments.Add("btcpayserver");
|
||||||
if((i >> j & 1) == 1)
|
foreach(var crypto in CryptoDefinition.GetDefinitions())
|
||||||
thisCombination.Add(inputList[j]);
|
{
|
||||||
}
|
if(!composition.SelectedCryptos.Contains(crypto.Crypto))
|
||||||
|
continue;
|
||||||
|
|
||||||
if(thisCombination.Count >= minimumItems && thisCombination.Count <= maximumItems)
|
fragments.Add(crypto.CryptoFragment);
|
||||||
listOfLists.Add(thisCombination);
|
if(composition.SelectedLN == "clightning" && crypto.CLightningFragment != null)
|
||||||
|
{
|
||||||
|
fragments.Add(crypto.CLightningFragment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return listOfLists;
|
var def = new DockerComposeDefinition(name, fragments);
|
||||||
|
def.FragmentLocation = fragmentLocation;
|
||||||
|
def.BuildOutputDirectory = output;
|
||||||
|
def.Build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private string FindLocation(string path)
|
private static string FindRoot(string rootDirectory)
|
||||||
{
|
{
|
||||||
string directory = path;
|
string directory = Directory.GetCurrentDirectory();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(i > 10)
|
if(i > 10)
|
||||||
throw new DirectoryNotFoundException(directory);
|
throw new DirectoryNotFoundException(rootDirectory);
|
||||||
if(Directory.Exists(path))
|
if(directory.EndsWith(rootDirectory))
|
||||||
return path;
|
return directory;
|
||||||
path = Path.Combine("..", path);
|
directory = Path.GetFullPath(Path.Combine(directory, ".."));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
docker-compose-generator/src/Properties/launchSettings.json
Normal file
14
docker-compose-generator/src/Properties/launchSettings.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"docker-compose-generator": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"commandLineArgs": "pregen",
|
||||||
|
"environmentVariables": {
|
||||||
|
"BTCPAYGEN_LIGHTNING": "clightning",
|
||||||
|
"BTCPAYGEN_CRYPTO2": "ltc",
|
||||||
|
"BTCPAYGEN_CRYPTO1": "btc",
|
||||||
|
"BTCPAYGEN_REVERSEPROXY": "nginx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
# This script will run docker-compose-generator in a container to generate the yml files
|
# This script will run docker-compose-generator in a container to generate the yml files
|
||||||
|
|
||||||
docker build -t btcpayserver/docker-compose-generator "$(Get-Location)\docker-compose-generator"
|
docker build -t btcpayserver/docker-compose-generator "$(Get-Location)\docker-compose-generator"
|
||||||
docker run -v "$(Get-Location)\Production:/app/Production" -v "$(Get-Location)\Production-NoReverseProxy:/app/Production-NoReverseProxy" --rm btcpayserver/docker-compose-generator
|
docker run -v "$(Get-Location)\Production:/app/Production" -v "$(Get-Location)\Production-NoReverseProxy:/app/Production-NoReverseProxy" --rm btcpayserver/docker-compose-generator pregen
|
@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
# This script will run docker-compose-generator in a container to generate the yml files
|
# This script will run docker-compose-generator in a container to generate the yml files
|
||||||
docker build -t btcpayserver/docker-compose-generator "$(pwd)/docker-compose-generator"
|
docker build -t btcpayserver/docker-compose-generator "$(pwd)/docker-compose-generator"
|
||||||
docker run -v "$(pwd)/Production:/app/Production" -v "$(pwd)/Production-NoReverseProxy:/app/Production-NoReverseProxy" --rm btcpayserver/docker-compose-generator
|
docker run -v "$(pwd)/Production:/app/Production" -v "$(pwd)/Production-NoReverseProxy:/app/Production-NoReverseProxy" --rm btcpayserver/docker-compose-generator pregen
|
Loading…
Reference in New Issue
Block a user