Polish install, migration script, docs (#1050)

* Checkpoint

* Checkpoint

* checkpoint

* fix typo

* Update migrate with changes

* UID and GID

* fix perms

* Remove custom user

* Fix migrate script typos

* fix grep

* remove cleverness

* migrate final fixes
This commit is contained in:
Jamil
2022-10-20 13:43:31 -07:00
committed by GitHub
parent bf6874df56
commit dd9841cd94
7 changed files with 202 additions and 120 deletions

View File

@@ -1,5 +1,11 @@
# Example compose deployment
# Example compose file for production deployment.
#
# Note: This file is meant to serve as a template. Please modify it
# according to your needs. Read more about Docker Compose:
#
# https://docs.docker.com/compose/compose-file/
#
#
x-deploy: &default-deploy
restart_policy:
condition: on-failure
@@ -15,7 +21,7 @@ services:
caddy:
image: caddy:2
volumes:
- ./caddy:/data/caddy
- ${FZ_INSTALL_DIR:-.}/caddy:/data/caddy
ports:
- 80:80
- 443:443
@@ -30,12 +36,12 @@ services:
env_file:
# This should contain a list of env vars for configuring Firezone.
# See https://docs.firezone.dev/reference/env-vars for more info.
- .env
- ${FZ_INSTALL_DIR:-.}/.env
volumes:
# IMPORTANT: Persists WireGuard private key and other data. If
# /var/firezone/private_key exists when Firezone starts, it is
# used as the WireGuard private. Otherwise, one is generated.
- ./firezone:/var/firezone
- ${FZ_INSTALL_DIR:-.}/firezone:/var/firezone
cap_add:
# Needed for WireGuard and firewall support.
- NET_ADMIN
@@ -53,7 +59,7 @@ services:
postgres:
image: postgres:15
volumes:
- ./postgres:/var/lib/postgresql/data
- ${FZ_INSTALL_DIR:-.}/postgres:/var/lib/postgresql/data
environment:
POSTGRES_DB: ${DATABASE_NAME:-firezone}
POSTGRES_USER: ${DATABASE_USER:-postgres}

View File

@@ -3,6 +3,21 @@ title: Uninstall
sidebar_position: 5
---
Firezone can be uninstalled using the steps below.
:::warning
This will irreversibly destroy ALL Firezone data and can't be undone.
:::
<Tabs>
<TabItem label="Docker" value="docker" default>
For docker-based deployments, simply delete the working directory where
you installed the Firezone docker files (`$HOME/.firezone` by default).
</TabItem>
<TabItem label="Omnibus" value="omnibus">
To completely remove Omnibus-based deployments of Firezone run the [uninstall.sh
script](https://github.com/firezone/firezone/blob/master/scripts/uninstall.sh):
@@ -10,8 +25,5 @@ script](https://github.com/firezone/firezone/blob/master/scripts/uninstall.sh):
sudo /bin/bash -c "$(curl -fsSL https://github.com/firezone/firezone/raw/master/scripts/uninstall.sh)"
```
**Warning**: This will irreversibly destroy ALL Firezone data and can't be
undone.
For docker-based deployments, simply delete the working directory where
you installed the Firezone docker files (`/data/firezone` by default).
</TabItem>
</Tabs>

View File

@@ -3,8 +3,8 @@ title: Deploy
sidebar_position: 2
---
Firezone can be deployed on most Linux servers in minutes. Read more
below to get started.
Firezone can be deployed on most Docker-supported platforms in about a minute.
Read more below to get started.
## Deployment Methods
@@ -19,8 +19,8 @@ preferred method of deployment.
:::note
Chef Infra Client, the configuration system Chef Omnibus relies on, has been
[scheduled for End-of-Life in 2024](https://docs.chef.io/versions/). As such,
Omnibus-based deployments will be deprecated in a future version of Firezone.
To transition to Docker from Omnibus today, follow our [migration guide
support for Omnibus-based deployments will be removed in a future version of
Firezone. To transition to Docker from Omnibus today, follow our [migration guide
](../administer/migrate).
:::
@@ -87,13 +87,6 @@ See the
[configuration file reference](../reference/configuration-file)
for details.
:::warning
Firezone modifies the kernel netfilter and routing tables. Other
programs that modify the Linux routing table or firewall may interfere with
Firezone's operation. For help troubleshooting connectivity issues, see
[troubleshoot](../administer/troubleshoot).
:::
### Resource Requirements
We recommend **starting with 1 vCPU and 1 GB of RAM and scaling up** as the

View File

@@ -44,7 +44,7 @@ After prerequisites are satisfied, you're ready to install the Firezone Server.
The easiest way to deploy Firezone with Docker is the automatic install script:
```bash
curl -fsSL https://github.com/firezone/firezone/raw/master/scripts/install.sh | bash -E
bash <(curl -fsSL https://github.com/firezone/firezone/raw/master/scripts/install.sh)
```
This will ask you a few questions regarding initial configuration, then proceed

View File

@@ -32,7 +32,7 @@ if [ $1 -eq "1" ]; then
count=`cat count`
if [ $count -eq "5" ]; then
rm -f count
echo "Firezone detected a service crash loop. Taking service down. For support please email support@firez.one and include a copy of these crash logs."
echo "Firezone detected a service crash loop. Taking service down. For support please email support@firezone.dev and include a copy of these crash logs."
echo 'd' > supervise/control
else
new_count=$((count+1))

View File

@@ -1,37 +1,54 @@
#!/bin/bash
set -eE
trap 'handler' ERR
trap "handler" ERR
handler () {
echo
echo 'An error occurred running this migration. Your existing Firezone installation has not been affected.'
rm .env
echo "An error occurred running this migration. Your existing Firezone installation has not been affected."
echo
exit 1
}
curlCheck () {
if ! type curl > /dev/null; then
echo 'curl not found. Please install curl to use this script.'
echo "curl not found. Please install curl to use this script."
exit 1
fi
}
dockerCheck () {
if ! command -v docker > /dev/null; then
echo 'docker not found. Please install docker and try again.'
echo "docker not found. Please install docker and try again."
exit 1
fi
if command -v docker-compose &> /dev/null; then
dc='docker-compose'
else
dc='docker compose'
fi
$dc version | grep -q "v2"
if [ $? -ne 0 ]; then
echo "Error: Automatic migration is only supported with Docker Compose version 2 or higher."
exit 1
fi
}
prompt () {
echo 'This script will copy Omnibus-based Firezone configuration to Docker-based Firezone configuration.'
echo 'It operates non-destructively and leaves your current Firezone services running.'
read -p 'Proceed? (Y/n): ' migrate
echo "This script will copy Omnibus-based Firezone configuration to Docker-based Firezone configuration."
echo "It operates non-destructively and leaves your current Firezone services running."
read -p "Proceed? (Y/n): " migrate
case $proceed in
n|N) echo 'Aborted' ;;
*) migrate
n|N)
echo "Aborted"
exit
;;
*)
migrate
;;
esac
}
@@ -43,39 +60,47 @@ condIns () {
val=$(cat $dir/$file)
val=$(echo $val | sed 's/"/\\"/g')
if [ $file = "EXTERNAL_URL" ]; then
val=$(echo $val | sed 's:/*$::')
val=$(echo $val | sed "s:/*$::")
fi
echo "$file=\"$val\"" >> .env
echo "$file=\"$val\"" >> $installDir/.env
fi
}
promptInstallDir() {
defaultInstallDir="${HOME}/.firezone"
read -p "Enter the desired installation directory ($defaultInstallDir): " installDir
if [ -z "$installDir" ]; then
installDir=$defaultInstallDir
fi
if ! test -d $installDir; then
mkdir $installDir
fi
}
migrate () {
export FZ_INSTALL_DIR=$installDir
promptInstallDir
env_files=/opt/firezone/service/phoenix/env
cwd=`pwd`
read -p "Enter the desired installation directory ($cwd): " installDir
if [ -z "$installDir" ]; then
installDir=$cwd
fi
cd $installDir
if ! test -f docker-compose.yml; then
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.prod.yml -o docker-compose.yml
fi
# setup data dir
mkdir -p /data/firezone/firezone
if ! test -f $installDir/docker-compose.yml; then
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.prod.yml -o $installDir/docker-compose.yml
fi
# copy tid
cp $env_files/TELEMETRY_ID /data/firezone/firezone/.tid
mkdir -p $installDir/firezone/
cp $env_files/TELEMETRY_ID $installDir/firezone/.tid
# copy private key
cp /var/opt/firezone/cache/wg_private_key /data/firezone/firezone/private_key
chown root:root /data/firezone/firezone/private_key
chmod 0600 /data/firezone/firezone/private_key
cp /var/opt/firezone/cache/wg_private_key $installDir/firezone/private_key
chown $(id -u):$(id -g) $installDir/firezone/private_key
chmod 0600 $installDir/firezone/private_key
# generate .env
if test -f ".env"; then
echo 'Existing .env detected! Remove and try again.'
exit 1
if test -f "$installDir/.env"; then
echo
echo "Existing .env detected! Moving to .env.bak and continuing..."
echo
mv $installDir/.env $installDir/.env.bak
fi
# BEGIN env vars that matter
@@ -89,8 +114,8 @@ migrate () {
condIns $env_files "COOKIE_ENCRYPTION_SALT"
condIns $env_files "DATABASE_NAME"
# These shouldn't change
echo "DATABASE_HOST=postgres" >> .env
echo "DATABASE_PORT=5432" >> .env
echo "DATABASE_HOST=postgres" >> $installDir/.env
echo "DATABASE_PORT=5432" >> $installDir/.env
condIns $env_files "DATABASE_POOL"
condIns $env_files "DATABASE_SSL"
condIns $env_files "DATABASE_SSL_OPTS"
@@ -124,68 +149,90 @@ migrate () {
condIns $env_files "CONNECTIVITY_CHECKS_ENABLED"
condIns $env_files "CONNECTIVITY_CHECKS_INTERVAL"
# optional vars
if test -f $env_files/DATABASE_PASSWORD; then
db_pass=$(cat $env_files/DATABASE_PASSWORD)
else
db_pass=$(/opt/firezone/embedded/bin/openssl rand -base64 12)
fi
echo "DATABASE_PASSWORD=\"${db_pass}\"" >> .env
echo "DATABASE_PASSWORD=\"${db_pass}\"" >> $installDir/.env
if test -f $env_files/DEFAULT_ADMIN_PASSWORD; then
echo "DEFAULT_ADMIN_PASSWORD=\"$(cat $env_files/DEFAULT_ADMIN_PASSWORD)\"" >> .env
echo "DEFAULT_ADMIN_PASSWORD=\"$(cat $env_files/DEFAULT_ADMIN_PASSWORD)\"" >> $installDir/.env
fi
# END env vars that matter
}
doDumpLoad () {
if command -v docker-compose &> /dev/null; then
dc='docker-compose'
else
dc='docker compose'
fi
echo 'Dumping existing database to ./firezone.sql'
echo "Dumping existing database to $installDir/firezone_omnibus_backup.sql"
db_host=$(cat /opt/firezone/service/phoenix/env/DATABASE_HOST)
db_port=$(cat /opt/firezone/service/phoenix/env/DATABASE_PORT)
db_name=$(cat /opt/firezone/service/phoenix/env/DATABASE_NAME)
db_user=$(cat /opt/firezone/service/phoenix/env/DATABASE_USER)
/opt/firezone/embedded/bin/pg_dump -h $db_host -p $db_port -d $db_name -U $db_user > firezone.sql
/opt/firezone/embedded/bin/pg_dump -h $db_host -p $db_port -d $db_name -U $db_user > $installDir/firezone_omnibus_backup.sql
echo 'Loading existing database into docker...'
DATABASE_PASSWORD=$db_pass $dc up -d postgres
echo "Loading existing database into docker..."
DATABASE_PASSWORD=$db_pass $dc -f $installDir/docker-compose.yml up -d postgres
sleep 5
$dc exec postgres psql -U postgres -h 127.0.0.1 -c "ALTER ROLE postgres WITH PASSWORD '${db_pass}'"
$dc exec postgres dropdb -U postgres -h 127.0.0.1 --if-exists $db_name
$dc exec postgres createdb -U postgres -h 127.0.0.1 $db_name
$dc exec -T postgres psql -U postgres -h 127.0.0.1 -d $db_name < firezone.sql
rm firezone.sql
$dc -f $installDir/docker-compose.yml exec postgres psql -U postgres -h 127.0.0.1 -c "ALTER ROLE postgres WITH PASSWORD '${db_pass}'"
$dc -f $installDir/docker-compose.yml exec postgres dropdb -U postgres -h 127.0.0.1 --if-exists $db_name
$dc -f $installDir/docker-compose.yml exec postgres createdb -U postgres -h 127.0.0.1 $db_name
$dc -f $installDir/docker-compose.yml exec -T postgres psql -U postgres -h 127.0.0.1 -d $db_name < $installDir/firezone_omnibus_backup.sql
rm $installDir/firezone_omnibus_backup.sql
}
dumpLoadDb () {
echo 'Would you like Firezone to attempt to migrate your existing database to Dockerized Postgres too?'
echo 'We only recommend this for Firezone installations using the default bundled Postgres.'
read -p 'Proceed? (Y/n): ' dumpLoad
echo "Would you like Firezone to attempt to migrate your existing database to Dockerized Postgres too?"
echo "We only recommend this for Firezone installations using the default bundled Postgres."
read -p "Proceed? (Y/n): " dumpLoad
case $dumpLoad in
n|N) echo 'Aborted' ;;
*) doDumpLoad
n|N)
echo "Aborted"
exit
;;
*)
doDumpLoad
;;
esac
}
doBoot () {
echo "Stopping Omnibus Firezone..."
firezone-ctl stop
echo "Tearing down network..."
firezone-ctl teardown-network
$dc up -d
echo "Disabling systemd unit..."
systemctl disable firezone-runsvdir-start.service
echo "Bringing Docker services up..."
$dc -f $installDir/docker-compose.yml up -d
}
printSuccess () {
echo 'Done! Would you like to stop Omnibus Firezone and start Docker Firezone now?'
read -p 'Proceed? (y/N): ' boot
echo "Done! Would you like to stop Omnibus Firezone and start Docker Firezone now?"
read -p "Proceed? (y/N): " boot
case $boot in
y|Y) doBoot ;;
*) echo "Aborted. Run 'firezone-ctl stop && firezone-ctl teardown-network && docker-compose up -d' to stop Omnibus Firezone and start Docker Firezone when you're ready."
y|Y)
doBoot
;;
*)
cat << EOF
Aborted. Run the following to stop Omnibus Firezone and start Docker Firezone when you're ready.
sudo firezone-ctl stop
sudo firezone-ctl teardown-network
docker-compose up -d
You may also want to disable the systemd unit:
sudo systemctl disable firezone-runsvdir-start.service
EOF
exit
;;
esac
}

View File

@@ -3,19 +3,27 @@ set -e
dockerCheck () {
if ! type docker > /dev/null; then
echo 'docker not found. Please install docker and try again.'
echo "docker not found. Please install docker and try again."
exit
fi
if command -v docker-compose &> /dev/null; then
dc='docker-compose'
dc="docker-compose"
else
dc='docker compose'
dc="docker compose"
fi
$dc version | grep -q "v2"
if [ $? -ne 0 ]; then
echo "Error: Automatic installation is only supported with Docker Compose version 2 or higher."
echo "Please upgrade Docker Compose or use the manual installation method: https://docs.firezone.dev/deploy/docker"
exit 1
fi
}
curlCheck () { if ! type curl > /dev/null; then
echo 'curl not found. Please install curl to use this script.'
echo "curl not found. Please install curl to use this script."
exit
fi
}
@@ -25,7 +33,7 @@ capture () {
if [ ! -z "$telemetry_id" ]; then
curl -s -XPOST \
-m 5 \
-H 'Content-Type: application/json' \
-H "Content-Type: application/json" \
-d "{
\"api_key\": \"phc_ubuPhiqqjMdedpmbWpG2Ak3axqv5eMVhFDNBaXl9UZK\",
\"event\": \"$1\",
@@ -45,12 +53,15 @@ promptInstallDir() {
if [ -z "$installDir" ]; then
installDir=$defaultInstallDir
fi
if ! test -d $installDir; then
mkdir $installDir
fi
}
promptExternalUrl() {
read -p "$1" externalUrl
# Remove trailing slash if present
externalUrl=$(echo $externalUrl | sed 's:/*$::')
externalUrl=$(echo $externalUrl | sed "s:/*$::")
if [ -z "$externalUrl" ]; then
externalUrl=$defaultExternalUrl
fi
@@ -59,49 +70,64 @@ promptExternalUrl() {
promptEmail() {
read -p "$1" adminEmail
case $adminEmail in
*@*) adminUser=$adminEmail;;
*) promptEmail "Please provide a valid email: "
*@*)
adminUser=$adminEmail
;;
*)
promptEmail "Please provide a valid email: "
;;
esac
}
promptContact() {
read -p 'Could we email you to ask for product feedback? Firezone depends heavily on input from users like you to steer development. (Y/n): ' contact
read -p "Could we email you to ask for product feedback? Firezone depends heavily on input from users like you to steer development. (Y/n): " contact
case $contact in
n|N);;
*) capture "contactOk" $adminUser
n|N)
;;
*)
capture "contactOk" $adminUser
;;
esac
}
promptACME() {
read -p 'Would you like to enable automatic SSL cert provisioning? Requires a valid DNS record and port 80 to be reachable. (Y/n): ' acme
read -p "Would you like to enable automatic SSL cert provisioning? Requires a valid DNS record and port 80 to be reachable. (Y/n): " acme
case $acme in
n|N) export CADDY_OPTS="--internal-certs";;
n|N)
export CADDY_OPTS="--internal-certs"
;;
*)
export CADDY_OPTS=""
;;
esac
}
firezoneSetup() {
installDir=${installDir/\~/$HOME}
cd $installDir
if ! test -f docker-compose.yml; then
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.prod.yml -o docker-compose.yml
export FZ_INSTALL_DIR=$installDir
if ! test -f $installDir/docker-compose.yml; then
curl -fsSL https://raw.githubusercontent.com/firezone/firezone/master/docker-compose.prod.yml -o $installDir/docker-compose.yml
fi
db_pass=$(od -vN "8" -An -tx1 /dev/urandom | tr -d " \n" ; echo)
docker run --rm firezone/firezone bin/gen-env > .env
sed -i.bak "s/ADMIN_EMAIL=.*/ADMIN_EMAIL=$1/" .env
sed -i.bak "s~EXTERNAL_URL=.*~EXTERNAL_URL=$2~" .env
sed -i.bak "s/DATABASE_PASSWORD=.*/DATABASE_PASSWORD=$db_pass/" .env
docker run --rm firezone/firezone bin/gen-env > "$installDir/.env"
sed -i.bak "s/ADMIN_EMAIL=.*/ADMIN_EMAIL=$1/" "$installDir/.env"
sed -i.bak "s~EXTERNAL_URL=.*~EXTERNAL_URL=$2~" "$installDir/.env"
sed -i.bak "s/DATABASE_PASSWORD=.*/DATABASE_PASSWORD=$db_pass/" "$installDir/.env"
echo "UID=$(id -u)" >> $installDir/.env
echo "GID=$(id -g)" >> $installDir/.env
# Set DATABASE_PASSWORD explicitly here in case the user has this var set in their shell
DATABASE_PASSWORD=$db_pass $dc up -d postgres
echo 'Waiting for DB to boot...'
DATABASE_PASSWORD=$db_pass $dc -f $installDir/docker-compose.yml up -d postgres
echo "Waiting for DB to boot..."
sleep 5
$dc logs postgres
echo 'Resetting DB password...'
$dc exec postgres psql -p 5432 -U postgres -d firezone -h 127.0.0.1 -c "ALTER ROLE postgres WITH PASSWORD '${db_pass}'"
$dc up -d firezone caddy
echo 'Waiting for app to boot before creating admin...'
$dc -f $installDir/docker-compose.yml logs postgres
echo "Resetting DB password..."
$dc -f $installDir/docker-compose.yml exec postgres psql -p 5432 -U postgres -d firezone -h 127.0.0.1 -c "ALTER ROLE postgres WITH PASSWORD '${db_pass}'"
$dc -f $installDir/docker-compose.yml up -d firezone caddy
echo "Waiting for app to boot before creating admin..."
sleep 15
$dc exec firezone bin/create-or-reset-admin
$dc -f $installDir/docker-compose.yml exec firezone bin/create-or-reset-admin
displayLogo
@@ -111,12 +137,10 @@ Installation complete!
You should now be able to log into the Web UI at $externalUrl with the
following credentials:
`grep ADMIN_EMAIL .env`
`grep DEFAULT_ADMIN_PASSWORD .env`
`grep ADMIN_EMAIL $installDir/.env`
`grep DEFAULT_ADMIN_PASSWORD $installDir/.env`
EOF
cd -
}
displayLogo() {
@@ -151,10 +175,10 @@ EOF
}
main() {
defaultInstallDir=`pwd`
defaultExternalUrl="https://$(hostname)"
adminUser=''
externalUrl=''
adminUser=""
externalUrl=""
defaultInstallDir="$HOME/.firezone"
promptEmail "Enter the administrator email you'd like to use for logging into this Firezone instance: "
promptInstallDir "Enter the desired installation directory ($defaultInstallDir): "
promptExternalUrl "Enter the external URL that will be used to access this instance. ($defaultExternalUrl): "