Skip to content

Commit 66c5ccf

Browse files
Vscode devcontainers (#3080)
* add devcontainers for `server` * run db migrations automatically in dev environment * remove curl * remove trailing comma; causes parsing with `jq` * use existing .env * add initializeCommand * use better search string * restructure common files * chmod +x scripts * remove problematic env config scripts * add mention of var that is needed for devcontainer * remove ref to deleted script * Update .devcontainer/community_dev/devcontainer.json Co-authored-by: Justin Baur <[email protected]> * Update .devcontainer/internal_dev/devcontainer.json Co-authored-by: Justin Baur <[email protected]> * use dev image for `6.0.416` SDK * revert to manual DB migrations * reuse SQL connection string var --------- Co-authored-by: Justin Baur <[email protected]>
1 parent 3eb4d54 commit 66c5ccf

File tree

7 files changed

+223
-0
lines changed

7 files changed

+223
-0
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
version: '3'
2+
3+
services:
4+
bitwarden_server:
5+
image: mcr.microsoft.com/devcontainers/dotnet:dev-6.0
6+
volumes:
7+
- ../../:/workspace:cached
8+
# Overrides default command so things don't shut down after the process ends.
9+
command: sleep infinity
10+
11+
bitwarden_mssql:
12+
image: mcr.microsoft.com/azure-sql-edge:latest
13+
restart: unless-stopped
14+
env_file:
15+
../../dev/.env
16+
environment:
17+
ACCEPT_EULA: "Y"
18+
MSSQL_PID: Developer
19+
volumes:
20+
- edgesql_dev_data:/var/opt/mssql
21+
- ../../util/Migrator:/mnt/migrator/
22+
- ../../dev/helpers/mssql:/mnt/helpers
23+
- ../../dev/.data/mssql:/mnt/data
24+
network_mode: service:bitwarden_server
25+
26+
bitwarden_mail:
27+
image: sj26/mailcatcher:latest
28+
restart: unless-stopped
29+
network_mode: service:bitwarden_server
30+
31+
volumes:
32+
edgesql_dev_data:
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "Bitwarden Community Dev",
3+
"dockerComposeFile": "../../.devcontainer/bitwarden_common/docker-compose.yml",
4+
"service": "bitwarden_server",
5+
"workspaceFolder": "/workspace",
6+
"customizations": {
7+
"vscode": {
8+
"settings": {},
9+
"features": {},
10+
"extensions": ["ms-dotnettools.csdevkit"]
11+
}
12+
},
13+
"postCreateCommand": "bash .devcontainer/community_dev/postCreateCommand.sh"
14+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env bash
2+
export DEV_DIR=/workspace/dev
3+
export CONTAINER_CONFIG=/workspace/.devcontainer/community_dev
4+
git config --global --add safe.directory /workspace
5+
6+
get_installation_id_and_key() {
7+
pushd ./dev >/dev/null || exit
8+
echo "Please enter your installation id and key from https://bitwarden.com/host:"
9+
read -r -p "Installation id: " INSTALLATION_ID
10+
read -r -p "Installation key: " INSTALLATION_KEY
11+
jq ".globalSettings.installation.id = \"$INSTALLATION_ID\" |
12+
.globalSettings.installation.key = \"$INSTALLATION_KEY\"" \
13+
secrets.json.example >secrets.json # create/overwrite secrets.json
14+
popd >/dev/null || exit
15+
}
16+
17+
configure_other_vars() {
18+
pushd ./dev >/dev/null || exit
19+
cp secrets.json .secrets.json.tmp
20+
# set DB_PASSWORD equal to .services.mssql.environment.MSSQL_SA_PASSWORD, accounting for quotes
21+
DB_PASSWORD="$(grep -oP 'MSSQL_SA_PASSWORD=["'"'"']?\K[^"'"'"'\s]+' $DEV_DIR/.env)"
22+
CERT_OUTPUT="$(./create_certificates_linux.sh)"
23+
#shellcheck disable=SC2086
24+
IDENTITY_SERVER_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Identity Server Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
25+
#shellcheck disable=SC2086
26+
DATA_PROTECTION_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Data Protection Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
27+
SQL_CONNECTION_STRING="Server=localhost;Database=vault_dev;User Id=SA;Password=$DB_PASSWORD;Encrypt=True;TrustServerCertificate=True"
28+
echo "Identity Server Dev: $IDENTITY_SERVER_FINGERPRINT"
29+
echo "Data Protection Dev: $DATA_PROTECTION_FINGERPRINT"
30+
jq \
31+
".globalSettings.sqlServer.connectionString = \"$SQL_CONNECTION_STRING\" |
32+
.globalSettings.postgreSql.connectionString = \"Host=localhost;Username=postgres;Password=$DB_PASSWORD;Database=vault_dev;Include Error Detail=true\" |
33+
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\" |
34+
.globalSettings.identityServer.certificateThumbprint = \"$IDENTITY_SERVER_FINGERPRINT\" |
35+
.globalSettings.dataProtection.certificateThumbprint = \"$DATA_PROTECTION_FINGERPRINT\"" \
36+
.secrets.json.tmp >secrets.json
37+
rm -f .secrets.json.tmp
38+
popd >/dev/null || exit
39+
}
40+
41+
one_time_setup() {
42+
read -r -p \
43+
"Would you like to configure your secrets and certificates for the first time?
44+
WARNING: This will overwrite any existing secrets.json and certificate files.
45+
Proceed? [y/N] " response
46+
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
47+
echo "Running one-time setup script..."
48+
sleep 1
49+
get_installation_id_and_key
50+
configure_other_vars
51+
pushd ./dev >/dev/null || exit
52+
pwsh ./setup_secrets.ps1 || true
53+
popd >/dev/null || exit
54+
55+
echo "Running migrations..."
56+
sleep 5 # wait for DB container to start
57+
dotnet run --project ./util/MsSqlMigratorUtility "$SQL_CONNECTION_STRING"
58+
59+
fi
60+
}
61+
62+
# main
63+
one_time_setup
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "Bitwarden Dev",
3+
"dockerComposeFile": [
4+
"../../.devcontainer/bitwarden_common/docker-compose.yml",
5+
"../../.devcontainer/internal_dev/docker-compose.override.yml"
6+
], "service": "bitwarden_server",
7+
"workspaceFolder": "/workspace",
8+
"customizations": {
9+
"vscode": {
10+
"settings": {},
11+
"features": {},
12+
"extensions": ["ms-dotnettools.csdevkit"]
13+
}
14+
},
15+
"postCreateCommand": "bash .devcontainer/internal_dev/postCreateCommand.sh"
16+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
version: '3'
2+
3+
services:
4+
bitwarden_storage:
5+
image: mcr.microsoft.com/azure-storage/azurite:latest
6+
restart: unless-stopped
7+
volumes:
8+
- ../../dev/.data/azurite:/data
9+
network_mode: service:bitwarden_server
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env bash
2+
export DEV_DIR=/workspace/dev
3+
export CONTAINER_CONFIG=/workspace/.devcontainer/internal_dev
4+
git config --global --add safe.directory /workspace
5+
6+
get_installation_id_and_key() {
7+
pushd ./dev >/dev/null || exit
8+
echo "Please enter your installation id and key from https://bitwarden.com/host:"
9+
read -r -p "Installation id: " INSTALLATION_ID
10+
read -r -p "Installation key: " INSTALLATION_KEY
11+
jq ".globalSettings.installation.id = \"$INSTALLATION_ID\" |
12+
.globalSettings.installation.key = \"$INSTALLATION_KEY\"" \
13+
secrets.json.example >secrets.json # create/overwrite secrets.json
14+
popd >/dev/null || exit
15+
}
16+
17+
remove_comments() {
18+
# jq will not parse files with comments
19+
file="$1"
20+
21+
if [[ -f "$file" ]]; then
22+
sed -e '/^\/\//d' -e 's@[[:blank:]]\{1,\}//.*@@' "$file" >"$file.tmp"
23+
mv "$file.tmp" "$file"
24+
fi
25+
}
26+
27+
configure_other_vars() {
28+
pushd ./dev >/dev/null || exit
29+
cp secrets.json .secrets.json.tmp
30+
# set DB_PASSWORD equal to .services.mssql.environment.MSSQL_SA_PASSWORD, accounting for quotes
31+
DB_PASSWORD="$(grep -oP 'MSSQL_SA_PASSWORD=["'"'"']?\K[^"'"'"'\s]+' $DEV_DIR/.env)"
32+
CERT_OUTPUT="$(./create_certificates_linux.sh)"
33+
#shellcheck disable=SC2086
34+
IDENTITY_SERVER_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Identity Server Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
35+
#shellcheck disable=SC2086
36+
DATA_PROTECTION_FINGERPRINT="$(echo $CERT_OUTPUT | awk -F 'Data Protection Dev: ' '{match($2, /[[:alnum:]]+/); print substr($2, RSTART, RLENGTH)}')"
37+
SQL_CONNECTION_STRING="Server=localhost;Database=vault_dev;User Id=SA;Password=$DB_PASSWORD;Encrypt=True;TrustServerCertificate=True"
38+
echo "Identity Server Dev: $IDENTITY_SERVER_FINGERPRINT"
39+
echo "Data Protection Dev: $DATA_PROTECTION_FINGERPRINT"
40+
jq \
41+
".globalSettings.sqlServer.connectionString = \"$SQL_CONNECTION_STRING\" |
42+
.globalSettings.postgreSql.connectionString = \"Host=localhost;Username=postgres;Password=$DB_PASSWORD;Database=vault_dev;Include Error Detail=true\" |
43+
.globalSettings.mySql.connectionString = \"server=localhost;uid=root;pwd=$DB_PASSWORD;database=vault_dev\" |
44+
.globalSettings.identityServer.certificateThumbprint = \"$IDENTITY_SERVER_FINGERPRINT\" |
45+
.globalSettings.dataProtection.certificateThumbprint = \"$DATA_PROTECTION_FINGERPRINT\"" \
46+
.secrets.json.tmp >secrets.json
47+
rm .secrets.json.tmp
48+
popd >/dev/null || exit
49+
}
50+
51+
one_time_setup() {
52+
read -r -p \
53+
"Would you like to configure your secrets and certificates for the first time?
54+
WARNING: This will overwrite any existing secrets.json and certificate files.
55+
Proceed? [y/N] " response
56+
if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
57+
echo "Running one-time setup script..."
58+
sleep 1
59+
read -r -p \
60+
"Place the secrets.json and dev.pfx files from our shared Collection in the ./dev directory.
61+
Press <Enter> to continue."
62+
remove_comments ./dev/secrets.json
63+
configure_other_vars
64+
echo "Installing Az module. This will take ~a minute..."
65+
pwsh -Command "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force"
66+
pwsh ./dev/setup_azurite.ps1
67+
68+
dotnet tool install dotnet-certificate-tool -g >/dev/null
69+
70+
read -r -s -p "Paste the \"Licensing Certificate - Dev\" password: " CERT_PASSWORD
71+
echo
72+
pushd ./dev >/dev/null || exit
73+
certificate-tool add --file ./dev.pfx --password "$CERT_PASSWORD"
74+
echo "Injecting dotnet secrets..."
75+
pwsh ./setup_secrets.ps1 || true
76+
popd >/dev/null || exit
77+
78+
echo "Running migrations..."
79+
sleep 5 # wait for DB container to start
80+
dotnet run --project ./util/MsSqlMigratorUtility "$SQL_CONNECTION_STRING"
81+
fi
82+
}
83+
84+
# main
85+
one_time_setup

dev/.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
COMPOSE_PROJECT_NAME=bitwardenserver
22
# Ensure the MSSQL_PASSWORD is complex and follows the password policy defined at
33
# https://docs.microsoft.com/en-us/sql/relational-databases/security/password-policy?view=sql-server-ver15
4+
5+
# The MSSQL*_PASSWORD variables can be the same value; MSSQL_SA_PASSWORD is used for VS Code devcontainers
6+
# and MSSQL_PASSWORD is used for docker-compose for traditional dev configurations.
47
MSSQL_PASSWORD=SET_A_PASSWORD_HERE_123
8+
MSSQL_SA_PASSWORD=SET_A_PASSWORD_HERE_123
59
MAILCATCHER_PORT=1080
610

711
# Alternative databases

0 commit comments

Comments
 (0)