From 49bd3bcf3561b5f27b0fe055e2f6313896735987 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Mon, 6 Nov 2017 17:28:02 -0500 Subject: [PATCH] build docker compose and allow custom ports --- util/Setup/DockerComposeBuilder.cs | 170 +++++++++++++++++++++++++++++ util/Setup/NginxConfigBuilder.cs | 22 ++-- util/Setup/Program.cs | 40 ++++++- 3 files changed, 216 insertions(+), 16 deletions(-) create mode 100644 util/Setup/DockerComposeBuilder.cs diff --git a/util/Setup/DockerComposeBuilder.cs b/util/Setup/DockerComposeBuilder.cs new file mode 100644 index 0000000000..4db5e8510a --- /dev/null +++ b/util/Setup/DockerComposeBuilder.cs @@ -0,0 +1,170 @@ +using System; +using System.IO; + +namespace Bit.Setup +{ + public class DockerComposeBuilder + { + private const string CoreVersion = "1.13.1"; + private const string WebVersion = "1.19.0"; + + public DockerComposeBuilder(string os) + { + MssqlDataDockerVolume = os == "mac"; + } + + public bool MssqlDataDockerVolume { get; private set; } + public int HttpPort { get; private set; } = 80; + public int HttpsPort { get; private set; } = 443; + + public void BuildForInstaller(int httpPort, int httpsPort) + { + if(httpPort != default(int) && httpsPort != default(int)) + { + HttpPort = httpPort; + HttpsPort = httpsPort; + } + + Build(); + } + + public void BuildForUpdater() + { + if(File.Exists("/bitwarden/docker/docker-compose.yml")) + { + var fileLines = File.ReadAllLines("/bitwarden/docker/docker-compose.yml"); + foreach(var line in fileLines) + { + if(!line.StartsWith("# Parameter:")) + { + continue; + } + + var paramParts = line.Split("="); + if(paramParts.Length < 2) + { + continue; + } + + if(paramParts[0] == "# Parameter:HttpPort" && int.TryParse(paramParts[1], out int httpPort)) + { + HttpPort = httpPort; + continue; + } + + if(paramParts[0] == "# Parameter:HttpsPort" && int.TryParse(paramParts[1], out int httpsPort)) + { + HttpsPort = httpsPort; + continue; + } + } + } + + Build(); + } + + private void Build() + { + Console.WriteLine("Building docker-compose.yml."); + Directory.CreateDirectory("/bitwarden/docker/"); + using(var sw = File.CreateText("/bitwarden/docker/docker-compose.yml")) + { + sw.Write($@"# https://docs.docker.com/compose/compose-file/ +# Parameter:MssqlDataDockerVolume={MssqlDataDockerVolume} +# Parameter:HttpPort={HttpPort} +# Parameter:HttpsPort={HttpsPort} +# Parameter:CoreVersion={CoreVersion} +# Parameter:WebVersion={WebVersion} + +version: '3' + +services: + mssql: + image: bitwarden/mssql:{CoreVersion} + container_name: mssql + restart: always + volumes:"); + + if(MssqlDataDockerVolume) + { + sw.Write(@" + - mssql_data:/var/opt/mssql/data"); + } + else + { + sw.Write(@" + - ../mssql/data:/var/opt/mssql/data"); + } + + sw.Write($@" + - ../mssql/backups:/etc/bitwarden/mssql/backups + env_file: + - mssql.env + - ../env/mssql.override.env + + web: + image: bitwarden/web:{WebVersion} + container_name: web + restart: always + volumes: + - ../web:/etc/bitwarden/web + + attachments: + image: bitwarden/attachments:{CoreVersion} + container_name: attachments + restart: always + volumes: + - ../core/attachments:/etc/bitwarden/core/attachments + + api: + image: bitwarden/api:{CoreVersion} + container_name: api + restart: always + volumes: + - ../core:/etc/bitwarden/core + env_file: + - global.env + - ../env/global.override.env + + identity: + image: bitwarden/identity:{CoreVersion} + container_name: identity + restart: always + volumes: + - ../identity:/etc/bitwarden/identity + - ../core:/etc/bitwarden/core + env_file: + - global.env + - ../env/global.override.env + + icons: + image: bitwarden/icons:{CoreVersion} + container_name: icons + restart: always + + nginx: + image: bitwarden/nginx:{CoreVersion} + container_name: nginx + restart: always + ports: + - '{HttpPort}:80' + - '{HttpsPort}:443' + volumes: + - ../nginx:/etc/bitwarden/nginx + - ../letsencrypt:/etc/letsencrypt + - ../ssl:/etc/ssl"); + + if(MssqlDataDockerVolume) + { + sw.Write(@" +volumes: + mssql_data:"); + } + + // New line at end of file. + sw.Write(@" +"); + } + } + } +} diff --git a/util/Setup/NginxConfigBuilder.cs b/util/Setup/NginxConfigBuilder.cs index b070657dd0..0342df32db 100644 --- a/util/Setup/NginxConfigBuilder.cs +++ b/util/Setup/NginxConfigBuilder.cs @@ -59,23 +59,17 @@ namespace Bit.Setup public void BuildForUpdater() { - Build(); - } - - public bool UpdateContext() - { - if(!File.Exists("/bitwarden/nginx/default.conf")) + if(File.Exists("/bitwarden/nginx/default.conf")) { - return false; + var confContent = File.ReadAllText("/bitwarden/nginx/default.conf"); + Ssl = confContent.Contains("listen 443 ssl http2;"); + SelfSignedSsl = confContent.Contains("/etc/ssl/self/"); + LetsEncrypt = !SelfSignedSsl && confContent.Contains("/etc/letsencrypt/live/"); + DiffieHellman = confContent.Contains("/dhparam.pem;"); + Trusted = confContent.Contains("ssl_trusted_certificate "); } - var confContent = File.ReadAllText("/bitwarden/nginx/default.conf"); - Ssl = confContent.Contains("listen 443 ssl http2;"); - SelfSignedSsl = confContent.Contains("/etc/ssl/self/"); - LetsEncrypt = !SelfSignedSsl && confContent.Contains("/etc/letsencrypt/live/"); - DiffieHellman = confContent.Contains("/dhparam.pem;"); - Trusted = confContent.Contains("ssl_trusted_certificate "); - return true; + Build(); } private void Build() diff --git a/util/Setup/Program.cs b/util/Setup/Program.cs index b3396ef9fe..f0d7d2474e 100644 --- a/util/Setup/Program.cs +++ b/util/Setup/Program.cs @@ -14,11 +14,17 @@ namespace Bit.Setup private static IDictionary _parameters = null; private static Guid? _installationId = null; private static string _installationKey = null; + private static string _hostOs = "win"; public static void Main(string[] args) { _args = args; _parameters = ParseParameters(); + if(_parameters.ContainsKey("os")) + { + _hostOs = _parameters["os"]; + } + if(_parameters.ContainsKey("install")) { Install(); @@ -73,6 +79,30 @@ namespace Bit.Setup var nginxBuilder = new NginxConfigBuilder(domain, ssl, selfSignedSsl, letsEncrypt); nginxBuilder.BuildForInstaller(); + Console.Write("(!) Do you want to use the default HTTP (80) and HTTPS (443) ports? (y/n): "); + var defaultPorts = Console.ReadLine().ToLowerInvariant() == "y"; + int httpPort = default(int), httpsPort = default(int); + if(!defaultPorts) + { + Console.Write("(!) HTTP port: "); + if(int.TryParse(Console.ReadLine().ToLowerInvariant().Trim(), out httpPort)) + { + Console.Write("(!) HTTPS port: "); + if(int.TryParse(Console.ReadLine().ToLowerInvariant().Trim(), out httpsPort)) + { + url += (":" + httpsPort); + } + else + { + Console.WriteLine("Invalid HTTPS port."); + } + } + else + { + Console.WriteLine("Invalid HTTP port."); + } + } + Console.Write("(!) Do you want to use push notifications? (y/n): "); var push = Console.ReadLine().ToLowerInvariant() == "y"; @@ -94,6 +124,9 @@ namespace Bit.Setup var appIdBuilder = new AppIdBuilder(url); appIdBuilder.Build(); + + var dockerComposeBuilder = new DockerComposeBuilder(_hostOs); + dockerComposeBuilder.BuildForInstaller(httpPort, httpsPort); } private static void Update() @@ -115,7 +148,7 @@ namespace Bit.Setup Console.WriteLine("==================================================="); Console.WriteLine("\n- visit {0}", vaultUrl); Console.Write("- to update, run "); - if(_parameters.ContainsKey("env") && _parameters["env"] == "win") + if(_hostOs == "win") { Console.Write("'.\\bitwarden.ps1 -update'"); } @@ -223,10 +256,10 @@ namespace Bit.Setup Console.WriteLine("Unable to determine existing installation url."); return; } + var domain = uri.Host; var nginxBuilder = new NginxConfigBuilder(domain); - nginxBuilder.UpdateContext(); nginxBuilder.BuildForUpdater(); var appSettingsBuilder = new AppSettingsBuilder(url, domain); @@ -234,6 +267,9 @@ namespace Bit.Setup var appIdBuilder = new AppIdBuilder(url); appIdBuilder.Build(); + + var dockerComposeBuilder = new DockerComposeBuilder(_hostOs); + dockerComposeBuilder.BuildForUpdater(); } private static IDictionary ParseParameters()