4 changed files with 54 additions and 940 deletions
@ -1,171 +1,3 @@ |
|||||||
param ( |
|
||||||
[switch] $install, |
|
||||||
[switch] $start, |
|
||||||
[switch] $restart, |
|
||||||
[switch] $stop, |
|
||||||
[switch] $update, |
|
||||||
[switch] $rebuild, |
|
||||||
[switch] $updateconf, |
|
||||||
[switch] $renewcert, |
|
||||||
[switch] $updatedb, |
|
||||||
[switch] $updaterun, |
|
||||||
[switch] $updateself, |
|
||||||
[switch] $uninstall, |
|
||||||
[switch] $help, |
|
||||||
[string] $output = "" |
|
||||||
) |
|
||||||
|
|
||||||
# Setup |
|
||||||
|
|
||||||
$scriptPath = $MyInvocation.MyCommand.Path |
$scriptPath = $MyInvocation.MyCommand.Path |
||||||
$dir = Split-Path -Parent $MyInvocation.MyCommand.Path |
Invoke-RestMethod -OutFile $scriptPath -Uri "https://go.btwrdn.co/bw-ps" |
||||||
if ($output -eq "") { |
Write-Output "We have moved our self-hosted scripts to their own repository (https://github.com/bitwarden/self-host). Your 'bitwarden.ps1' script has been automatically upgraded. Please run it again." |
||||||
$output = "${dir}\bwdata" |
|
||||||
} |
|
||||||
|
|
||||||
$scriptsDir = "${output}\scripts" |
|
||||||
$githubBaseUrl = "https://raw.githubusercontent.com/bitwarden/server/master" |
|
||||||
|
|
||||||
# Please do not create pull requests modifying the version numbers. |
|
||||||
$coreVersion = "1.46.2" |
|
||||||
$webVersion = "2.26.1" |
|
||||||
$keyConnectorVersion = "1.0.1" |
|
||||||
|
|
||||||
# Functions |
|
||||||
|
|
||||||
function Get-Self { |
|
||||||
Invoke-RestMethod -OutFile $scriptPath -Uri "${githubBaseUrl}/scripts/bitwarden.ps1" |
|
||||||
} |
|
||||||
|
|
||||||
function Get-Run-File { |
|
||||||
if (!(Test-Path -Path $scriptsDir)) { |
|
||||||
New-Item -ItemType directory -Path $scriptsDir | Out-Null |
|
||||||
} |
|
||||||
Invoke-RestMethod -OutFile $scriptsDir\run.ps1 -Uri "${githubBaseUrl}/scripts/run.ps1" |
|
||||||
} |
|
||||||
|
|
||||||
function Test-Output-Dir-Exists { |
|
||||||
if (!(Test-Path -Path $output)) { |
|
||||||
throw "Cannot find a Bitwarden installation at $output." |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function Test-Output-Dir-Not-Exists { |
|
||||||
if (Test-Path -Path "$output\docker") { |
|
||||||
throw "Looks like Bitwarden is already installed at $output." |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function Show-Commands { |
|
||||||
Write-Line " |
|
||||||
Available commands: |
|
||||||
|
|
||||||
-install |
|
||||||
-start |
|
||||||
-restart |
|
||||||
-stop |
|
||||||
-update |
|
||||||
-updatedb |
|
||||||
-updaterun |
|
||||||
-updateself |
|
||||||
-updateconf |
|
||||||
-uninstall |
|
||||||
-renewcert |
|
||||||
-rebuild |
|
||||||
-help |
|
||||||
|
|
||||||
See more at https://bitwarden.com/help/article/install-on-premise/#script-commands-reference |
|
||||||
" |
|
||||||
} |
|
||||||
|
|
||||||
function Write-Line($str) { |
|
||||||
if($env:BITWARDEN_QUIET -ne "true") { |
|
||||||
Write-Host $str |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
# Intro |
|
||||||
|
|
||||||
$year = (Get-Date).year |
|
||||||
|
|
||||||
Write-Line @' |
|
||||||
_ _ _ _ |
|
||||||
| |__ (_) |___ ____ _ _ __ __| | ___ _ __ |
|
||||||
| '_ \| | __\ \ /\ / / _` | '__/ _` |/ _ \ '_ \ |
|
||||||
| |_) | | |_ \ V V / (_| | | | (_| | __/ | | | |
|
||||||
|_.__/|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| |
|
||||||
'@ |
|
||||||
|
|
||||||
Write-Line " |
|
||||||
Open source password management solutions |
|
||||||
Copyright 2015-${year}, 8bit Solutions LLC |
|
||||||
https://bitwarden.com, https://github.com/bitwarden |
|
||||||
|
|
||||||
=================================================== |
|
||||||
" |
|
||||||
|
|
||||||
if($env:BITWARDEN_QUIET -ne "true") { |
|
||||||
Write-Line "bitwarden.ps1 version ${coreVersion}" |
|
||||||
docker --version |
|
||||||
docker-compose --version |
|
||||||
} |
|
||||||
|
|
||||||
Write-Line "" |
|
||||||
|
|
||||||
# Commands |
|
||||||
|
|
||||||
if ($install) { |
|
||||||
Test-Output-Dir-Not-Exists |
|
||||||
New-Item -ItemType directory -Path $output -ErrorAction Ignore | Out-Null |
|
||||||
Get-Run-File |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -install -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($start -Or $restart) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -restart -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($update) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Get-Run-File |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -update -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($rebuild) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -rebuild -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($updateconf) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -updateconf -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($updatedb) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -updatedb -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($stop) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -stop -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($renewcert) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -renewcert -outputDir `"$output`" -coreVersion $coreVersion -webVersion $webVersion -keyConnectorVersion $keyConnectorVersion" |
|
||||||
} |
|
||||||
elseif ($updaterun) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Get-Run-File |
|
||||||
} |
|
||||||
elseif ($updateself) { |
|
||||||
Get-Self |
|
||||||
Write-Line "Updated self." |
|
||||||
} |
|
||||||
elseif ($uninstall) { |
|
||||||
Test-Output-Dir-Exists |
|
||||||
Invoke-Expression "& `"$scriptsDir\run.ps1`" -uninstall -outputDir `"$output`" " |
|
||||||
} |
|
||||||
elseif ($help) { |
|
||||||
Show-Commands |
|
||||||
} |
|
||||||
else { |
|
||||||
Write-Line "No command found." |
|
||||||
Write-Line "" |
|
||||||
Show-Commands |
|
||||||
} |
|
||||||
|
|||||||
@ -1,293 +1,16 @@ |
|||||||
param ( |
$scriptPath = $MyInvocation.MyCommand.Path |
||||||
[string]$outputDir = "../.", |
$bitwardenPath = Split-Path $scriptPath | Split-Path | Split-Path |
||||||
[string]$coreVersion = "latest", |
$files = Get-ChildItem $bitwardenPath |
||||||
[string]$webVersion = "latest", |
$scriptFound = $false |
||||||
[string]$keyConnectorVersion = "latest", |
foreach ($file in $files) { |
||||||
[switch] $install, |
if ($file.Name -eq "bitwarden.ps1") { |
||||||
[switch] $start, |
$scriptFound = $true |
||||||
[switch] $restart, |
Invoke-RestMethod -OutFile "$($bitwardenPath)/bitwarden.ps1" -Uri "https://go.btwrdn.co/bw-ps" |
||||||
[switch] $stop, |
Write-Output "We have moved our self-hosted scripts to their own repository (https://github.com/bitwarden/self-host). Your 'bitwarden.ps1' script has been automatically upgraded. Please run it again." |
||||||
[switch] $pull, |
break |
||||||
[switch] $updateconf, |
|
||||||
[switch] $uninstall, |
|
||||||
[switch] $renewcert, |
|
||||||
[switch] $updatedb, |
|
||||||
[switch] $update |
|
||||||
) |
|
||||||
|
|
||||||
# Setup |
|
||||||
|
|
||||||
$dockerDir = "${outputDir}\docker" |
|
||||||
$setupQuiet = 0 |
|
||||||
$qFlag = "" |
|
||||||
$quietPullFlag = "" |
|
||||||
$certbotHttpPort = "80" |
|
||||||
$certbotHttpsPort = "443" |
|
||||||
if ($env:BITWARDEN_QUIET -eq "true") { |
|
||||||
$setupQuiet = 1 |
|
||||||
$qFlag = " -q" |
|
||||||
$quietPullFlag = " --quiet-pull" |
|
||||||
} |
|
||||||
if ("${env:BITWARDEN_CERTBOT_HTTP_PORT}" -ne "") { |
|
||||||
$certbotHttpPort = $env:BITWARDEN_CERTBOT_HTTP_PORT |
|
||||||
} |
|
||||||
if ("${env:BITWARDEN_CERTBOT_HTTPS_PORT}" -ne "") { |
|
||||||
$certbotHttpsPort = $env:BITWARDEN_CERTBOT_HTTPS_PORT |
|
||||||
} |
|
||||||
|
|
||||||
# Functions |
|
||||||
|
|
||||||
function Install() { |
|
||||||
[string]$letsEncrypt = "n" |
|
||||||
Write-Host "(!) " -f cyan -nonewline |
|
||||||
[string]$domain = $( Read-Host "Enter the domain name for your Bitwarden instance (ex. bitwarden.example.com)" ) |
|
||||||
echo "" |
|
||||||
|
|
||||||
if ($domain -eq "") { |
|
||||||
$domain = "localhost" |
|
||||||
} |
|
||||||
|
|
||||||
if ($domain -ne "localhost") { |
|
||||||
Write-Host "(!) " -f cyan -nonewline |
|
||||||
$letsEncrypt = $( Read-Host "Do you want to use Let's Encrypt to generate a free SSL certificate? (y/n)" ) |
|
||||||
echo "" |
|
||||||
|
|
||||||
if ($letsEncrypt -eq "y") { |
|
||||||
Write-Host "(!) " -f cyan -nonewline |
|
||||||
[string]$email = $( Read-Host ("Enter your email address (Let's Encrypt will send you certificate " + |
|
||||||
"expiration reminders)") ) |
|
||||||
echo "" |
|
||||||
|
|
||||||
$letsEncryptPath = "${outputDir}/letsencrypt" |
|
||||||
if (!(Test-Path -Path $letsEncryptPath )) { |
|
||||||
New-Item -ItemType directory -Path $letsEncryptPath | Out-Null |
|
||||||
} |
|
||||||
Invoke-Expression ("docker pull{0} certbot/certbot" -f "") #TODO: qFlag |
|
||||||
$certbotExp = "docker run -it --rm --name certbot -p ${certbotHttpsPort}:443 -p ${certbotHttpPort}:80 " + ` |
|
||||||
"-v ${outputDir}/letsencrypt:/etc/letsencrypt/ certbot/certbot " + ` |
|
||||||
"certonly{0} --standalone --noninteractive --agree-tos --preferred-challenges http " + ` |
|
||||||
"--email ${email} -d ${domain} --logs-dir /etc/letsencrypt/logs" |
|
||||||
Invoke-Expression ($certbotExp -f $qFlag) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
Write-Host "(!) " -f cyan -nonewline |
|
||||||
[string]$database = $( Read-Host "Enter the database name for your Bitwarden instance (ex. vault): ") |
|
||||||
echo "" |
|
||||||
|
|
||||||
if ($database -eq "") { |
|
||||||
$database = "vault" |
|
||||||
} |
|
||||||
|
|
||||||
Pull-Setup |
|
||||||
docker run -it --rm --name setup -v ${outputDir}:/bitwarden bitwarden/setup:$coreVersion ` |
|
||||||
dotnet Setup.dll -install 1 -domain ${domain} -letsencrypt ${letsEncrypt} ` |
|
||||||
-os win -corev $coreVersion -webv $webVersion -keyconnectorv $keyConnectorVersion -q $setupQuiet -dbname "$database" |
|
||||||
} |
|
||||||
|
|
||||||
function Docker-Compose-Up { |
|
||||||
Docker-Compose-Files |
|
||||||
Docker-Compose-Volumes |
|
||||||
Invoke-Expression ("docker-compose up -d{0}" -f $quietPullFlag) |
|
||||||
} |
|
||||||
|
|
||||||
function Docker-Compose-Down { |
|
||||||
Docker-Compose-Files |
|
||||||
if ((Invoke-Expression ("docker-compose ps{0}" -f "") | Measure-Object -Line).lines -gt 2 ) { |
|
||||||
Invoke-Expression ("docker-compose down{0}" -f "") #TODO: qFlag |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function Docker-Compose-Pull { |
|
||||||
Docker-Compose-Files |
|
||||||
Invoke-Expression ("docker-compose pull{0}" -f $qFlag) |
|
||||||
} |
|
||||||
|
|
||||||
function Docker-Compose-Files { |
|
||||||
if (Test-Path -Path "${dockerDir}\docker-compose.override.yml" -PathType leaf) { |
|
||||||
$env:COMPOSE_FILE = "${dockerDir}\docker-compose.yml;${dockerDir}\docker-compose.override.yml" |
|
||||||
} |
|
||||||
else { |
|
||||||
$env:COMPOSE_FILE = "${dockerDir}\docker-compose.yml" |
|
||||||
} |
|
||||||
$env:COMPOSE_HTTP_TIMEOUT = "300" |
|
||||||
} |
|
||||||
|
|
||||||
function Docker-Compose-Volumes { |
|
||||||
Create-Dir "core" |
|
||||||
Create-Dir "core/attachments" |
|
||||||
Create-Dir "logs" |
|
||||||
Create-Dir "logs/admin" |
|
||||||
Create-Dir "logs/api" |
|
||||||
Create-Dir "logs/events" |
|
||||||
Create-Dir "logs/icons" |
|
||||||
Create-Dir "logs/identity" |
|
||||||
Create-Dir "logs/mssql" |
|
||||||
Create-Dir "logs/nginx" |
|
||||||
Create-Dir "logs/notifications" |
|
||||||
Create-Dir "logs/sso" |
|
||||||
Create-Dir "logs/portal" |
|
||||||
Create-Dir "mssql/backups" |
|
||||||
Create-Dir "mssql/data" |
|
||||||
} |
|
||||||
|
|
||||||
function Create-Dir($str) { |
|
||||||
$outPath = "${outputDir}/$str" |
|
||||||
if (!(Test-Path -Path $outPath )) { |
|
||||||
Write-Line "Creating directory $outPath" |
|
||||||
New-Item -ItemType directory -Path $outPath | Out-Null |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function Docker-Prune { |
|
||||||
docker image prune --all --force --filter="label=com.bitwarden.product=bitwarden" ` |
|
||||||
--filter="label!=com.bitwarden.project=setup" |
|
||||||
} |
|
||||||
|
|
||||||
function Update-Lets-Encrypt { |
|
||||||
if (Test-Path -Path "${outputDir}\letsencrypt\live") { |
|
||||||
Invoke-Expression ("docker pull{0} certbot/certbot" -f "") #TODO: qFlag |
|
||||||
$certbotExp = "docker run -it --rm --name certbot -p ${certbotHttpsPort}:443 -p ${certbotHttpPort}:80 " + ` |
|
||||||
"-v ${outputDir}/letsencrypt:/etc/letsencrypt/ certbot/certbot " + ` |
|
||||||
"renew{0} --logs-dir /etc/letsencrypt/logs" -f $qFlag |
|
||||||
Invoke-Expression $certbotExp |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function Force-Update-Lets-Encrypt { |
|
||||||
if (Test-Path -Path "${outputDir}\letsencrypt\live") { |
|
||||||
Invoke-Expression ("docker pull{0} certbot/certbot" -f "") #TODO: qFlag |
|
||||||
$certbotExp = "docker run -it --rm --name certbot -p ${certbotHttpsPort}:443 -p ${certbotHttpPort}:80 " + ` |
|
||||||
"-v ${outputDir}/letsencrypt:/etc/letsencrypt/ certbot/certbot " + ` |
|
||||||
"renew{0} --logs-dir /etc/letsencrypt/logs --force-renew" -f $qFlag |
|
||||||
Invoke-Expression $certbotExp |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function Update-Database { |
|
||||||
Pull-Setup |
|
||||||
Docker-Compose-Files |
|
||||||
$mssqlId = docker-compose ps -q mssql |
|
||||||
docker run -it --rm --name setup --network container:$mssqlId ` |
|
||||||
-v ${outputDir}:/bitwarden bitwarden/setup:$coreVersion ` |
|
||||||
dotnet Setup.dll -update 1 -db 1 -os win -corev $coreVersion -webv $webVersion ` |
|
||||||
-keyconnectorv $keyConnectorVersion -q $setupQuiet |
|
||||||
Write-Line "Database update complete" |
|
||||||
} |
|
||||||
|
|
||||||
function Update([switch] $withpull) { |
|
||||||
if ($withpull) { |
|
||||||
Pull-Setup |
|
||||||
} |
|
||||||
docker run -it --rm --name setup -v ${outputDir}:/bitwarden bitwarden/setup:$coreVersion ` |
|
||||||
dotnet Setup.dll -update 1 -os win -corev $coreVersion -webv $webVersion ` |
|
||||||
-keyconnectorv $keyConnectorVersion -q $setupQuiet |
|
||||||
} |
|
||||||
|
|
||||||
function Uninstall() { |
|
||||||
$keepDatabase = $(Write-Host "(WARNING: UNINSTALL STARTED) Would you like to save the database files? (y/n)" -f red -nonewline) + $(Read-host) |
|
||||||
if ($keepDatabase -eq "y") { |
|
||||||
Write-Host "Saving database." |
|
||||||
Compress-Archive -Path "${outputDir}\mssql" -DestinationPath ".\bitwarden_database.zip" |
|
||||||
Write-Host "(SAVED DATABASE FILES: YES) `n(WARNING: ALL DATA WILL BE REMOVED, INCLUDING THE FOLDER $outputDir) " -f red -nonewline |
|
||||||
$uninstallAction = $( Read-Host "Are you sure you want to uninstall Bitwarden? (y/n)" ) |
|
||||||
} else { |
|
||||||
Write-Host "(WARNING: ALL DATA WILL BE REMOVED, INCLUDING THE FOLDER $outputDir) " -f red -nonewline |
|
||||||
$uninstallAction = $( Read-Host "Are you sure you want to uninstall Bitwarden? (y/n)" ) |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
if ($uninstallAction -eq "y") { |
|
||||||
Write-Host "uninstalling Bitwarden..." |
|
||||||
Docker-Compose-Down |
|
||||||
Write-Host "Removing $outputDir" |
|
||||||
Remove-Item -Path $outputDir -Force -Recurse |
|
||||||
Write-Host "Bitwarden uninstall complete!" |
|
||||||
} else { |
|
||||||
Write-Host "Bitwarden uninstall canceled." |
|
||||||
Exit |
|
||||||
} |
|
||||||
|
|
||||||
Write-Host "(!) " -f red -nonewline |
|
||||||
$purgeAction = $( Read-Host "Would you like to purge all local Bitwarden container images? (y/n)" ) |
|
||||||
|
|
||||||
if ($purgeAction -eq "y") { |
|
||||||
Docker-Prune |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function Print-Environment { |
|
||||||
Pull-Setup |
|
||||||
docker run -it --rm --name setup -v ${outputDir}:/bitwarden bitwarden/setup:$coreVersion ` |
|
||||||
dotnet Setup.dll -printenv 1 -os win -corev $coreVersion -webv $webVersion ` |
|
||||||
-keyconnectorv $keyConnectorVersion -q $setupQuiet |
|
||||||
} |
|
||||||
|
|
||||||
function Restart { |
|
||||||
Docker-Compose-Down |
|
||||||
Docker-Compose-Pull |
|
||||||
Update-Lets-Encrypt |
|
||||||
Docker-Compose-Up |
|
||||||
Print-Environment |
|
||||||
} |
|
||||||
|
|
||||||
function Cert-Restart { |
|
||||||
Docker-Compose-Down |
|
||||||
Docker-Compose-Pull |
|
||||||
Force-Update-Lets-Encrypt |
|
||||||
Docker-Compose-Up |
|
||||||
Print-Environment |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
function Pull-Setup { |
|
||||||
Invoke-Expression ("docker pull{0} bitwarden/setup:${coreVersion}" -f "") #TODO: qFlag |
|
||||||
} |
|
||||||
|
|
||||||
function Write-Line($str) { |
|
||||||
if ($env:BITWARDEN_QUIET -ne "true") { |
|
||||||
Write-Host $str |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
# Commands |
if (-not $scriptFound) { |
||||||
|
Write-Output "We have moved our self-hosted scripts to their own repository (https://github.com/bitwarden/self-host). Please run 'bitwarden.ps1 -updateself' before updating." |
||||||
if ($install) { |
|
||||||
Install |
|
||||||
} |
|
||||||
elseif ($start -Or $restart) { |
|
||||||
Restart |
|
||||||
} |
|
||||||
elseif ($pull) { |
|
||||||
Docker-Compose-Pull |
|
||||||
} |
|
||||||
elseif ($stop) { |
|
||||||
Docker-Compose-Down |
|
||||||
} |
|
||||||
elseif ($renewcert) { |
|
||||||
Cert-Restart |
|
||||||
} |
|
||||||
elseif ($updateconf) { |
|
||||||
Docker-Compose-Down |
|
||||||
Update -withpull |
|
||||||
} |
|
||||||
elseif ($updatedb) { |
|
||||||
Update-Database |
|
||||||
} |
|
||||||
elseif ($update) { |
|
||||||
Docker-Compose-Down |
|
||||||
Update -withpull |
|
||||||
Restart |
|
||||||
Docker-Prune |
|
||||||
Write-Line "Pausing 60 seconds for database to come online. Please wait..." |
|
||||||
Start-Sleep -s 60 |
|
||||||
Update-Database |
|
||||||
} |
|
||||||
elseif ($uninstall) { |
|
||||||
Docker-Compose-Down |
|
||||||
Uninstall |
|
||||||
} |
|
||||||
elseif ($rebuild) { |
|
||||||
Docker-Compose-Down |
|
||||||
Update |
|
||||||
} |
} |
||||||
|
|||||||
@ -1,343 +1,45 @@ |
|||||||
#!/usr/bin/env bash |
#!/usr/bin/env bash |
||||||
set -e |
set -e |
||||||
|
|
||||||
# Setup |
cat << "EOF" |
||||||
if command -v docker-compose &> /dev/null |
_ _ _ _ |
||||||
then |
| |__ (_) |___ ____ _ _ __ __| | ___ _ __ |
||||||
dccmd='docker-compose' |
| '_ \| | __\ \ /\ / / _` | '__/ _` |/ _ \ '_ \ |
||||||
else |
| |_) | | |_ \ V V / (_| | | | (_| | __/ | | | |
||||||
dccmd='docker compose' |
|_.__/|_|\__| \_/\_/ \__,_|_| \__,_|\___|_| |_| |
||||||
fi |
EOF |
||||||
|
|
||||||
CYAN='\033[0;36m' |
cat << EOF |
||||||
RED='\033[1;31m' |
Open source password management solutions |
||||||
NC='\033[0m' # No Color |
Copyright 2015-$(date +'%Y'), 8bit Solutions LLC |
||||||
|
https://bitwarden.com, https://github.com/bitwarden |
||||||
|
=================================================== |
||||||
|
EOF |
||||||
|
|
||||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" |
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" |
||||||
|
BITWARDEN_SCRIPT_URL="https://go.btwrdn.co/bw-sh" |
||||||
|
|
||||||
OUTPUT_DIR=".." |
cd $DIR |
||||||
if [ $# -gt 1 ] |
cd ../../ |
||||||
then |
|
||||||
OUTPUT_DIR=$2 |
|
||||||
fi |
|
||||||
|
|
||||||
COREVERSION="latest" |
|
||||||
if [ $# -gt 2 ] |
|
||||||
then |
|
||||||
COREVERSION=$3 |
|
||||||
fi |
|
||||||
|
|
||||||
WEBVERSION="latest" |
|
||||||
if [ $# -gt 3 ] |
|
||||||
then |
|
||||||
WEBVERSION=$4 |
|
||||||
fi |
|
||||||
|
|
||||||
KEYCONNECTORVERSION="latest" |
|
||||||
if [ $# -gt 4 ] |
|
||||||
then |
|
||||||
KEYCONNECTORVERSION=$5 |
|
||||||
fi |
|
||||||
|
|
||||||
OS="lin" |
|
||||||
[ "$(uname)" == "Darwin" ] && OS="mac" |
|
||||||
ENV_DIR="$OUTPUT_DIR/env" |
|
||||||
DOCKER_DIR="$OUTPUT_DIR/docker" |
|
||||||
|
|
||||||
# Initialize UID/GID which will be used to run services from within containers |
|
||||||
if ! grep -q "^LOCAL_UID=" $ENV_DIR/uid.env 2>/dev/null || ! grep -q "^LOCAL_GID=" $ENV_DIR/uid.env 2>/dev/null |
|
||||||
then |
|
||||||
LUID="LOCAL_UID=`id -u $USER`" |
|
||||||
[ "$LUID" == "LOCAL_UID=0" ] && LUID="LOCAL_UID=65534" |
|
||||||
LGID="LOCAL_GID=`id -g $USER`" |
|
||||||
[ "$LGID" == "LOCAL_GID=0" ] && LGID="LOCAL_GID=65534" |
|
||||||
mkdir -p $ENV_DIR |
|
||||||
echo $LUID >$ENV_DIR/uid.env |
|
||||||
echo $LGID >>$ENV_DIR/uid.env |
|
||||||
fi |
|
||||||
|
|
||||||
# Functions |
|
||||||
|
|
||||||
function install() { |
|
||||||
LETS_ENCRYPT="n" |
|
||||||
echo -e -n "${CYAN}(!)${NC} Enter the domain name for your Bitwarden instance (ex. bitwarden.example.com): " |
|
||||||
read DOMAIN |
|
||||||
echo "" |
|
||||||
|
|
||||||
if [ "$DOMAIN" == "" ] |
|
||||||
then |
|
||||||
DOMAIN="localhost" |
|
||||||
fi |
|
||||||
|
|
||||||
if [ "$DOMAIN" != "localhost" ] |
|
||||||
then |
|
||||||
echo -e -n "${CYAN}(!)${NC} Do you want to use Let's Encrypt to generate a free SSL certificate? (y/n): " |
|
||||||
read LETS_ENCRYPT |
|
||||||
echo "" |
|
||||||
|
|
||||||
if [ "$LETS_ENCRYPT" == "y" ] |
|
||||||
then |
|
||||||
echo -e -n "${CYAN}(!)${NC} Enter your email address (Let's Encrypt will send you certificate expiration reminders): " |
|
||||||
read EMAIL |
|
||||||
echo "" |
|
||||||
|
|
||||||
mkdir -p $OUTPUT_DIR/letsencrypt |
|
||||||
docker pull certbot/certbot |
|
||||||
docker run -it --rm --name certbot -p 80:80 -v $OUTPUT_DIR/letsencrypt:/etc/letsencrypt/ certbot/certbot \ |
|
||||||
certonly --standalone --noninteractive --agree-tos --preferred-challenges http \ |
|
||||||
--email $EMAIL -d $DOMAIN --logs-dir /etc/letsencrypt/logs |
|
||||||
fi |
|
||||||
fi |
|
||||||
|
|
||||||
echo -e -n "${CYAN}(!)${NC} Enter the database name for your Bitwarden instance (ex. vault): " |
|
||||||
read DATABASE |
|
||||||
echo "" |
|
||||||
|
|
||||||
if [ "$DATABASE" == "" ] |
|
||||||
then |
|
||||||
DATABASE="vault" |
|
||||||
fi |
|
||||||
|
|
||||||
pullSetup |
|
||||||
docker run -it --rm --name setup -v $OUTPUT_DIR:/bitwarden \ |
|
||||||
--env-file $ENV_DIR/uid.env bitwarden/setup:$COREVERSION \ |
|
||||||
dotnet Setup.dll -install 1 -domain $DOMAIN -letsencrypt $LETS_ENCRYPT -os $OS \ |
|
||||||
-corev $COREVERSION -webv $WEBVERSION -dbname "$DATABASE" -keyconnectorv $KEYCONNECTORVERSION |
|
||||||
} |
|
||||||
|
|
||||||
function dockerComposeUp() { |
|
||||||
dockerComposeFiles |
|
||||||
dockerComposeVolumes |
|
||||||
$dccmd up -d |
|
||||||
} |
|
||||||
|
|
||||||
function dockerComposeDown() { |
|
||||||
dockerComposeFiles |
|
||||||
if [ $($dccmd ps | wc -l) -gt 2 ]; then |
|
||||||
$dccmd down |
|
||||||
fi |
|
||||||
} |
|
||||||
|
|
||||||
function dockerComposePull() { |
|
||||||
dockerComposeFiles |
|
||||||
$dccmd pull |
|
||||||
} |
|
||||||
|
|
||||||
function dockerComposeFiles() { |
|
||||||
if [ -f "${DOCKER_DIR}/docker-compose.override.yml" ] |
|
||||||
then |
|
||||||
export COMPOSE_FILE="$DOCKER_DIR/docker-compose.yml:$DOCKER_DIR/docker-compose.override.yml" |
|
||||||
else |
|
||||||
export COMPOSE_FILE="$DOCKER_DIR/docker-compose.yml" |
|
||||||
fi |
|
||||||
export COMPOSE_HTTP_TIMEOUT="300" |
|
||||||
} |
|
||||||
|
|
||||||
function dockerComposeVolumes() { |
|
||||||
createDir "core" |
|
||||||
createDir "core/attachments" |
|
||||||
createDir "logs" |
|
||||||
createDir "logs/admin" |
|
||||||
createDir "logs/api" |
|
||||||
createDir "logs/events" |
|
||||||
createDir "logs/icons" |
|
||||||
createDir "logs/identity" |
|
||||||
createDir "logs/mssql" |
|
||||||
createDir "logs/nginx" |
|
||||||
createDir "logs/notifications" |
|
||||||
createDir "logs/sso" |
|
||||||
createDir "logs/portal" |
|
||||||
createDir "mssql/backups" |
|
||||||
createDir "mssql/data" |
|
||||||
} |
|
||||||
|
|
||||||
function createDir() { |
|
||||||
if [ ! -d "${OUTPUT_DIR}/$1" ] |
|
||||||
then |
|
||||||
echo "Creating directory $OUTPUT_DIR/$1" |
|
||||||
mkdir -p $OUTPUT_DIR/$1 |
|
||||||
fi |
|
||||||
} |
|
||||||
|
|
||||||
function dockerPrune() { |
|
||||||
docker image prune --all --force --filter="label=com.bitwarden.product=bitwarden" \ |
|
||||||
--filter="label!=com.bitwarden.project=setup" |
|
||||||
} |
|
||||||
|
|
||||||
function updateLetsEncrypt() { |
|
||||||
if [ -d "${OUTPUT_DIR}/letsencrypt/live" ] |
|
||||||
then |
|
||||||
docker pull certbot/certbot |
|
||||||
docker run -i --rm --name certbot -p 443:443 -p 80:80 \ |
|
||||||
-v $OUTPUT_DIR/letsencrypt:/etc/letsencrypt/ certbot/certbot \ |
|
||||||
renew --logs-dir /etc/letsencrypt/logs |
|
||||||
fi |
|
||||||
} |
|
||||||
|
|
||||||
function forceUpdateLetsEncrypt() { |
|
||||||
if [ -d "${OUTPUT_DIR}/letsencrypt/live" ] |
|
||||||
then |
|
||||||
docker pull certbot/certbot |
|
||||||
docker run -i --rm --name certbot -p 443:443 -p 80:80 \ |
|
||||||
-v $OUTPUT_DIR/letsencrypt:/etc/letsencrypt/ certbot/certbot \ |
|
||||||
renew --logs-dir /etc/letsencrypt/logs --force-renew |
|
||||||
fi |
|
||||||
} |
|
||||||
|
|
||||||
function updateDatabase() { |
|
||||||
pullSetup |
|
||||||
dockerComposeFiles |
|
||||||
MSSQL_ID=$($dccmd ps -q mssql) |
|
||||||
docker run -i --rm --name setup --network container:$MSSQL_ID \ |
|
||||||
-v $OUTPUT_DIR:/bitwarden --env-file $ENV_DIR/uid.env bitwarden/setup:$COREVERSION \ |
|
||||||
dotnet Setup.dll -update 1 -db 1 -os $OS -corev $COREVERSION -webv $WEBVERSION -keyconnectorv $KEYCONNECTORVERSION |
|
||||||
echo "Database update complete" |
|
||||||
} |
|
||||||
|
|
||||||
function updatebw() { |
|
||||||
KEY_CONNECTOR_ENABLED=$(grep -A3 'enable_key_connector:' $OUTPUT_DIR/config.yml | tail -n1 | awk '{ print $2}') |
|
||||||
CORE_ID=$($dccmd ps -q admin) |
|
||||||
WEB_ID=$($dccmd ps -q web) |
|
||||||
if [ "$KEY_CONNECTOR_ENABLED" = true ]; |
|
||||||
then |
|
||||||
KEYCONNECTOR_ID=$($dccmd ps -q key-connector) |
|
||||||
fi |
|
||||||
|
|
||||||
if [ $KEYCONNECTOR_ID ] && |
|
||||||
docker inspect --format='{{.Config.Image}}:' $CORE_ID | grep -F ":$COREVERSION:" | grep -q ":[0-9.]*:$" && |
|
||||||
docker inspect --format='{{.Config.Image}}:' $WEB_ID | grep -F ":$WEBVERSION:" | grep -q ":[0-9.]*:$" && |
|
||||||
docker inspect --format='{{.Config.Image}}:' $KEYCONNECTOR_ID | grep -F ":$KEYCONNECTORVERSION:" | grep -q ":[0-9.]*:$" |
|
||||||
then |
|
||||||
echo "Update not needed" |
|
||||||
exit |
|
||||||
elif |
|
||||||
docker inspect --format='{{.Config.Image}}:' $CORE_ID | grep -F ":$COREVERSION:" | grep -q ":[0-9.]*:$" && |
|
||||||
docker inspect --format='{{.Config.Image}}:' $WEB_ID | grep -F ":$WEBVERSION:" | grep -q ":[0-9.]*:$" |
|
||||||
then |
|
||||||
echo "Update not needed" |
|
||||||
exit |
|
||||||
fi |
|
||||||
dockerComposeDown |
|
||||||
update withpull |
|
||||||
restart |
|
||||||
dockerPrune |
|
||||||
echo "Pausing 60 seconds for database to come online. Please wait..." |
|
||||||
sleep 60 |
|
||||||
} |
|
||||||
|
|
||||||
function update() { |
|
||||||
if [ "$1" == "withpull" ] |
|
||||||
then |
|
||||||
pullSetup |
|
||||||
fi |
|
||||||
docker run -i --rm --name setup -v $OUTPUT_DIR:/bitwarden \ |
|
||||||
--env-file $ENV_DIR/uid.env bitwarden/setup:$COREVERSION \ |
|
||||||
dotnet Setup.dll -update 1 -os $OS -corev $COREVERSION -webv $WEBVERSION -keyconnectorv $KEYCONNECTORVERSION |
|
||||||
} |
|
||||||
|
|
||||||
function uninstall() { |
FOUND=false |
||||||
echo -e -n "${RED}(WARNING: UNINSTALL STARTED) Would you like to save the database files? (y/n): ${NC}" |
|
||||||
read KEEP_DATABASE |
|
||||||
|
|
||||||
if [ "$KEEP_DATABASE" == "y" ] |
for i in *.sh; do |
||||||
|
if [ $i = "bitwarden.sh" ] |
||||||
|
then |
||||||
|
FOUND=true |
||||||
|
if curl -L -s -w "http_code %{http_code}" -o bitwarden.sh.1 $BITWARDEN_SCRIPT_URL | grep -q "^http_code 20[0-9]" |
||||||
then |
then |
||||||
echo "Saving database files." |
mv bitwarden.sh.1 bitwarden.sh |
||||||
tar -cvzf "./bitwarden_database.tar.gz" "$OUTPUT_DIR/mssql" |
chmod u+x bitwarden.sh |
||||||
echo -e -n "${RED}(SAVED DATABASE FILES: YES): WARNING: ALL DATA WILL BE REMOVED, INCLUDING THE FOLDER $OUTPUT_DIR): Are you sure you want to uninstall Bitwarden? (y/n): ${NC}" |
echo "We have moved our self-hosted scripts to their own repository (https://github.com/bitwarden/self-host). Your 'bitwarden.sh' script has been automatically upgraded. Please run it again." |
||||||
read UNINSTALL_ACTION |
|
||||||
else |
else |
||||||
echo -e -n "${RED}WARNING: ALL DATA WILL BE REMOVED, INCLUDING THE FOLDER $OUTPUT_DIR): Are you sure you want to uninstall Bitwarden? (y/n): ${NC}" |
rm -f bitwarden.sh.1 |
||||||
read UNINSTALL_ACTION |
|
||||||
fi |
|
||||||
|
|
||||||
|
|
||||||
if [ "$UNINSTALL_ACTION" == "y" ] |
|
||||||
then |
|
||||||
echo "Uninstalling Bitwarden..." |
|
||||||
dockerComposeDown |
|
||||||
echo "Removing $OUTPUT_DIR" |
|
||||||
rm -R $OUTPUT_DIR |
|
||||||
echo "Removing MSSQL docker volume." |
|
||||||
docker volume prune --force --filter="label=com.bitwarden.product=bitwarden" |
|
||||||
echo "Bitwarden uninstall complete!" |
|
||||||
else |
|
||||||
echo -e -n "${CYAN}(!) Bitwarden uninstall canceled. ${NC}" |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
|
|
||||||
echo -e -n "${RED}(!) Would you like to purge all local Bitwarden container images? (y/n): ${NC}" |
|
||||||
read PURGE_ACTION |
|
||||||
if [ "$PURGE_ACTION" == "y" ] |
|
||||||
then |
|
||||||
dockerPrune |
|
||||||
echo -e -n "${CYAN}Bitwarden uninstall complete! ${NC}" |
|
||||||
fi |
fi |
||||||
|
fi |
||||||
} |
done |
||||||
|
|
||||||
function printEnvironment() { |
|
||||||
pullSetup |
|
||||||
docker run -i --rm --name setup -v $OUTPUT_DIR:/bitwarden \ |
|
||||||
--env-file $ENV_DIR/uid.env bitwarden/setup:$COREVERSION \ |
|
||||||
dotnet Setup.dll -printenv 1 -os $OS -corev $COREVERSION -webv $WEBVERSION -keyconnectorv $KEYCONNECTORVERSION |
|
||||||
} |
|
||||||
|
|
||||||
function restart() { |
|
||||||
dockerComposeDown |
|
||||||
dockerComposePull |
|
||||||
updateLetsEncrypt |
|
||||||
dockerComposeUp |
|
||||||
printEnvironment |
|
||||||
} |
|
||||||
|
|
||||||
function certRestart() { |
|
||||||
dockerComposeDown |
|
||||||
dockerComposePull |
|
||||||
forceUpdateLetsEncrypt |
|
||||||
dockerComposeUp |
|
||||||
printEnvironment |
|
||||||
} |
|
||||||
|
|
||||||
function pullSetup() { |
if [ $FOUND = false ] |
||||||
docker pull bitwarden/setup:$COREVERSION |
then |
||||||
} |
echo "We have moved our self-hosted scripts to their own repository (https://github.com/bitwarden/self-host). Please run 'bitwarden.sh updateself' before updating." |
||||||
|
fi |
||||||
# Commands |
|
||||||
|
|
||||||
case $1 in |
|
||||||
"install") |
|
||||||
install |
|
||||||
;; |
|
||||||
"start" | "restart") |
|
||||||
restart |
|
||||||
;; |
|
||||||
"pull") |
|
||||||
dockerComposePull |
|
||||||
;; |
|
||||||
"stop") |
|
||||||
dockerComposeDown |
|
||||||
;; |
|
||||||
"renewcert") |
|
||||||
certRestart |
|
||||||
;; |
|
||||||
"updateconf") |
|
||||||
dockerComposeDown |
|
||||||
update withpull |
|
||||||
;; |
|
||||||
"updatedb") |
|
||||||
updateDatabase |
|
||||||
;; |
|
||||||
"update") |
|
||||||
dockerComposeFiles |
|
||||||
updatebw |
|
||||||
updateDatabase |
|
||||||
;; |
|
||||||
"uninstall") |
|
||||||
dockerComposeFiles |
|
||||||
uninstall |
|
||||||
;; |
|
||||||
"rebuild") |
|
||||||
dockerComposeDown |
|
||||||
update nopull |
|
||||||
;; |
|
||||||
esac |
|
||||||
|
|||||||
Loading…
Reference in new issue