plane/deploy/selfhost/install.sh
sriram veeraghanta 59335618b4
feat: session auth implementation (#4411)
* feat: session authentication and god-mode implementation (#4302)

* dev: move authentication to base class for credentials

* chore: new account creation

* dev: return error as query parameter

* dev: accounts and profile endpoints for user

* fix: user store updates

* fix: store fixes

* fix: type fixes

* dev: set is_password_autoset and is_email_verifier for auth providers

* dev: move all auth configuration to different apps

* dev: fix circular imports

* dev: remove unused imports

* dev: fix imports for authentication

* dev: update endpoints to use rest framework api viewa

* fix: onboarding fixes

* dev: session model changes

* fix: session model and add check for last name first name and avatar

* dev: fix referer redirect

* dev: remove auth imports

* dev: fix imports

* dev: update migrations

* fix: instance admin login

* comflict: conflicts resolved

* dev: fix import errors and email check endpoint

* fix: error messages and redirects after login

* dev: configs api

* fix: is github enabled boolean

* dev: merge config and instance api

* conflict: merge conflict resolved

* dev: instance admin sign up endpoint

* dev: enable magic link login

* dev: configure instance variables for github and google enabled

* chore: typo fixes

* fix: god mode docker file changes

* build-error: resolved build errors

* fix: docker compose changes

* dev: add email credential check endpoint

* fix: minor package changes

* fix: docker related changes

* dev: add nginx rules in the nginx template

* dev: refactor the url patterns

* fix: docker changes

* fix: docker files for god-mode

* fix: static export

* fix: nginx conf

* dev: smtp sender refused exception

* fix: godmode fixes

* chore: god mode revamp.

* dev: add csrf secured flag

* fix: oauth redirect uri and session settings

* chore: god mode app changes.  (#3982)

* chore: send test email functionality.

* style: authentication methods page UI revamp.

* chore: create workspace popup.

* fix: user me endpoint

* dev: fix redirection after authentication

* dev: handle god mode redirection

* fix: redirections

* fix: auth related hooks

* fix: store related fixes

* dev: fix session authentication for rest apis

* fix: linting errors

* fix: removing references of useStore=

* dev: fix redirection and password validation

* dev: add useUser hook

* fix: build fixes and lint issues

* fix: removing useApplication hook

* fix: build errors

* fix: delete unused files

* fix: auth build fixes

* fix: bugfixes

* dev: alter avatar to support more than 255 chars

* dev: fix profile endpoint and increase session expiry time and update session on every request

* chore: resolved the migration

* chore: resolved merge conflicts

* dev: error codes and error messages for the auth flow

* dev: instance admin sign up and sign in endpoint

* dev: use zxcvbn to validate password strength

* dev: add extra parameters when error handling on instance god mode

* chore: auth init

* chore: signin/ signup form ui updates and password strength meter.

* chore: update password fields.

* chore: validations and error handling.

* chore: updated sign-up form

* chore: updated workflow and updated the code structure

* chore: instance empty state for god-mode.

* chore: instance and auth wrappers update

* fix: renaming godmode

* fix: docker changes

* chore: updated authentication wrappers

* chore: updated the authentication workflow and rendered all pages

* fix: build errors

* fix: docker related fixes

* fix: tailing slash added to space and admin for valid nginx locations

* chore: seperate pages for signup and login

* git-action modified for admin file changes

* feature build action updated for admin app

* self host modified

* chore: resolved build errors and handled signin and signup in a seperate route

* chore: sign-in and sign-up revamp.

* fix: migration conflicts

* dev: migrations

* chore: handled redirection

* dev: admin url

* dev: create seperate endpoint for instance admin me

* dev: instance admin endpoint

* git action fixed

* chore: handled auth wrappers

* dev: add serializer and remove print logs

* fix: build errors

* dev: fix migrations

* dev: instance folder structuring

* fix: linting errors

* chore: resolved build errors

* chore: updated store and auth workflow and updates api service types

* chore: Replaced Next Link with Anchoer tag for god-mode redirection

* add 3333 port to allowed origins

* make password login working again

* dev: fix redirection, add admin signout endpoint and fix email credential check endpoint

* fix unique code sign in

* fix small build error

* enable sign out

* dev: add google client secret variable to configure instance

* dev: add referer for redirection

* fix origin urls for oauths

* admin setup and login separation

* dev: fix user redirection and tour completed endpoint

* fix build errors

* dev: add set password endpoint

* dev: remove user creation logic for redirection

* fix unique code page

* fix forgot password

* chore: onboarding revamp.

* dev: fix workspace slug redirection in login

* chore: invited user onboarding flow update.

* chore: fix switch or delete account modal.

* fix members exception

* refactor auth flows and add invitations to auth flow

* fix sig in sign up url

* fix action url

* fix build errors

* dev: fix user set password when logging in

* dev: reset password endpoint

* chore: confirm password validation for signup and onboarding.

* enable reset password

* fix build error

* chore: minor UI updates.

* chore: forgot and reset password UI revamp.

* fix authentication re directions

* dev: auth redirections

* change url paths for signup and signin

* dev: make the user logged in when changing passwords

* dev: next path redirection for web and space app

* dev: next path for magic sign in endpoint

* dev: github space endpoint

* chore: minor ui updates and fixes in web app.

* set password screen

* fix multiple unique code generation

* dev: next path base redirection

* dev: remove print logs

* dev: auth space endpoints

* fix build errors

* dev: invalidate cache on configuration update, god mode exception errors and authentication failed code

* dev: fix space endpoints and add extra endpoints

* chore: space auth revamp.

* dev: add sign up for space app

* fix: build errors.

* fix: auth redirection logic.

* chore: space app onboarding revamp.

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com>
Co-authored-by: Manish Gupta <manish@mgupta.me>
Co-authored-by: = <=>
Co-authored-by: rahulramesha <rahulramesham@gmail.com>

* chore: updated file structure for admin

* chore: updated admin-sidebar

* chore: auth error handling

* chore: onboarding UI updates and dark mode fixes.

* chore: add `user personalization` step to onboarding profile setup screen.

* chore: fix minor UI bugs

* chore: authentication workflow changes

* chore: handled signin workflow

* style: switch or delete account workflow

* chore: god mode redirection URL

* feat(dashboard): improve label readability (#4321)

change none label for all time in dashbard filters

* chore: god-mode redirection

* chore: onboarding ui updates and accept invitation workflow updates.

* chore: rename unique code auth form.

* style: space auth ux copy.

* chore: updated intance and auth wrapper logic

* chore: update default layout style.

* chore: update confirm password.

* chore: backend redirection

* style: update banner ui

* chore: minor ui updates and validation fix.

* chore: removed old auth hook

* chore: handled auth wrapper

* chore: handled store loaders in the user

* chore: handled logs

* chore: add loading spinners for all auth and onboarding form buttons.

* chore: add background pattern in admin auth forms and minor ui fixes.

* chore: UI changes and revamp components for authentication

* chore: auth UI consistency in web, space and admin.

* chore: resolved build errors

* chore: removed old auth hooks

* chore: handled lint errors in use accounts

* chore: updated authentication wrapper logic in web app

* [WEB -1149] dev: update dependencies (#4333)

* dev: upgrade dependencies remove unwanted dependency and add ruff as local dependency

* dev: add comments

* chore: authentication wrapper fetch user

* chore: updated store loader

* chore: removed old auth wrapper and replaced the imports with new auth wrapper

* chore: join workspace invitation workflow updates

* chore: build error resolved in deploy

* chore: handled onboarding step error in web app

* chore: SMTP Name and Password validation removed

* chore: handled seo and signout logic and new user popup

* chore: added redirection to plane in the sidebar

* chore: resolved build errors

* dev: admin session cookie update

* chore: updated cookie session time for admin

* dev: add start date and end date to projects (#4355)

* chore: add email security dropdown and remove SMTP username and password validation.

* chore: add tooltip to admin sidebar help-section.

* chore: add dropdown to collapsed admin sidebar.

* chore: profile themning

* chore: updated page error messages and theme in command palette

* dev: add email validation in email check apis

* dev: remove start date and end date from project

* chore: updated space folder structure and updated the store hooks

* dev: error codes for authentication

* chore: handled authentication in space and web apps

* chore: banner redirect handling the email

* dev: god mode error codes

* chore: updated error codes

* chore: updated onboarding images

* dev: signout endpoints and saving login domain while creating sessions

* feat: Self Host Data Backup (#4383)

* feat: implemented backup , support for docker-compose tool, readme updated

* minor fix in shell script

* codacy fixes

* chore: handled build errors in web

* chore: updated react, react-dom, and next versions

* chore: updated password autioset in the signin

* dev: add logo prop to views and pages

* chore: updated api service and handled the set password in store

* chore: handled build errors and code cleanup

* dev: return 401 when the session is not valid

* dev: users/me exception for api

* chore: installed lodash in space app

* dev: add auth route in nginx

---------

Co-authored-by: pablohashescobar <nikhilschacko@gmail.com>
Co-authored-by: NarayanBavisetti <narayan3119@gmail.com>
Co-authored-by: gurusainath <gurusainath007@gmail.com>
Co-authored-by: Prateek Shourya <prateekshourya29@gmail.com>
Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com>
Co-authored-by: Manish Gupta <manish@mgupta.me>
Co-authored-by: rahulramesha <rahulramesham@gmail.com>
Co-authored-by: Aaryan Khandelwal <aaryankhandu123@gmail.com>
Co-authored-by: Daniel Alba <56451942+redrum15@users.noreply.github.com>
Co-authored-by: Nikhil <118773738+pablohashescobar@users.noreply.github.com>
2024-05-08 23:01:20 +05:30

434 lines
13 KiB
Bash
Executable File

#!/bin/bash
BRANCH=master
SCRIPT_DIR=$PWD
PLANE_INSTALL_DIR=$PWD/plane-app
export APP_RELEASE=$BRANCH
export DOCKERHUB_USER=makeplane
export PULL_POLICY=always
USE_GLOBAL_IMAGES=1
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
function print_header() {
clear
cat <<"EOF"
--------------------------------------------
____ _ /////////
| _ \| | __ _ _ __ ___ /////////
| |_) | |/ _` | '_ \ / _ \ ///// /////
| __/| | (_| | | | | __/ ///// /////
|_| |_|\__,_|_| |_|\___| ////
////
--------------------------------------------
Project management tool from the future
--------------------------------------------
EOF
}
function buildLocalImage() {
if [ "$1" == "--force-build" ]; then
DO_BUILD="1"
elif [ "$1" == "--skip-build" ]; then
DO_BUILD="2"
else
printf "\n" >&2
printf "${YELLOW}You are on ${CPU_ARCH} cpu architecture. ${NC}\n" >&2
printf "${YELLOW}Since the prebuilt ${CPU_ARCH} compatible docker images are not available for, we will be running the docker build on this system. ${NC} \n" >&2
printf "${YELLOW}This might take ${YELLOW}5-30 min based on your system's hardware configuration. \n ${NC} \n" >&2
printf "\n" >&2
printf "${GREEN}Select an option to proceed: ${NC}\n" >&2
printf " 1) Build Fresh Images \n" >&2
printf " 2) Skip Building Images \n" >&2
printf " 3) Exit \n" >&2
printf "\n" >&2
read -p "Select Option [1]: " DO_BUILD
until [[ -z "$DO_BUILD" || "$DO_BUILD" =~ ^[1-3]$ ]]; do
echo "$DO_BUILD: invalid selection." >&2
read -p "Select Option [1]: " DO_BUILD
done
echo "" >&2
fi
if [ "$DO_BUILD" == "1" ] || [ "$DO_BUILD" == "" ];
then
REPO=https://github.com/makeplane/plane.git
CURR_DIR=$PWD
PLANE_TEMP_CODE_DIR=$(mktemp -d)
git clone $REPO $PLANE_TEMP_CODE_DIR --branch $BRANCH --single-branch
cp $PLANE_TEMP_CODE_DIR/deploy/selfhost/build.yml $PLANE_TEMP_CODE_DIR/build.yml
cd $PLANE_TEMP_CODE_DIR
if [ "$BRANCH" == "master" ];
then
export APP_RELEASE=stable
fi
/bin/bash -c "$COMPOSE_CMD -f build.yml build --no-cache" >&2
# cd $CURR_DIR
# rm -rf $PLANE_TEMP_CODE_DIR
echo "build_completed"
elif [ "$DO_BUILD" == "2" ];
then
printf "${YELLOW}Build action skipped by you in lieu of using existing images. ${NC} \n" >&2
echo "build_skipped"
elif [ "$DO_BUILD" == "3" ];
then
echo "build_exited"
else
printf "INVALID OPTION SUPPLIED" >&2
fi
}
function install() {
echo "Installing Plane.........."
download
}
function download() {
cd $SCRIPT_DIR
TS=$(date +%s)
if [ -f "$PLANE_INSTALL_DIR/docker-compose.yaml" ]
then
mv $PLANE_INSTALL_DIR/docker-compose.yaml $PLANE_INSTALL_DIR/archive/$TS.docker-compose.yaml
fi
curl -H 'Cache-Control: no-cache, no-store' -s -o $PLANE_INSTALL_DIR/docker-compose.yaml https://raw.githubusercontent.com/makeplane/plane/$BRANCH/deploy/selfhost/docker-compose.yml?$(date +%s)
curl -H 'Cache-Control: no-cache, no-store' -s -o $PLANE_INSTALL_DIR/variables-upgrade.env https://raw.githubusercontent.com/makeplane/plane/$BRANCH/deploy/selfhost/variables.env?$(date +%s)
if [ -f "$DOCKER_ENV_PATH" ];
then
cp $DOCKER_ENV_PATH $PLANE_INSTALL_DIR/archive/$TS.env
else
mv $PLANE_INSTALL_DIR/variables-upgrade.env $DOCKER_ENV_PATH
fi
if [ "$BRANCH" != "master" ];
then
cp $PLANE_INSTALL_DIR/docker-compose.yaml $PLANE_INSTALL_DIR/temp.yaml
sed -e 's@${APP_RELEASE:-stable}@'"$BRANCH"'@g' \
$PLANE_INSTALL_DIR/temp.yaml > $PLANE_INSTALL_DIR/docker-compose.yaml
rm $PLANE_INSTALL_DIR/temp.yaml
fi
if [ $USE_GLOBAL_IMAGES == 0 ]; then
local res=$(buildLocalImage)
# echo $res
if [ "$res" == "build_exited" ];
then
echo
echo "Install action cancelled by you. Exiting now."
echo
exit 0
fi
else
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH pull"
fi
echo ""
echo "Most recent Stable version is now available for you to use"
echo ""
echo "In case of Upgrade, your new setting file is availabe as 'variables-upgrade.env'. Please compare and set the required values in 'plane.env 'file."
echo ""
}
function startServices() {
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH up -d --quiet-pull"
local migrator_container_id=$(docker container ls -aq -f "name=plane-app-migrator")
if [ -n "$migrator_container_id" ]; then
local idx=0
while docker inspect --format='{{.State.Status}}' $migrator_container_id | grep -q "running"; do
local message=">> Waiting for Data Migration to finish"
local dots=$(printf '%*s' $idx | tr ' ' '.')
echo -ne "\r$message$dots"
((idx++))
sleep 1
done
fi
printf "\r\033[K"
echo ""
echo " Data Migration completed successfully ✅"
# if migrator exit status is not 0, show error message and exit
if [ -n "$migrator_container_id" ]; then
local migrator_exit_code=$(docker inspect --format='{{.State.ExitCode}}' $migrator_container_id)
if [ $migrator_exit_code -ne 0 ]; then
echo "Plane Server failed to start ❌"
# stopServices
echo
echo "Please check the logs for the 'migrator' service and resolve the issue(s)."
echo "Stop the services by running the command: ./setup.sh stop"
exit 1
fi
fi
local api_container_id=$(docker container ls -q -f "name=plane-app-api")
local idx2=0
while ! docker logs $api_container_id 2>&1 | grep -m 1 -i "Application startup complete" | grep -q ".";
do
local message=">> Waiting for API Service to Start"
local dots=$(printf '%*s' $idx2 | tr ' ' '.')
echo -ne "\r$message$dots"
((idx2++))
sleep 1
done
printf "\r\033[K"
echo " API Service started successfully ✅"
source "${DOCKER_ENV_PATH}"
echo " Plane Server started successfully ✅"
echo ""
echo " You can access the application at $WEB_URL"
echo ""
}
function stopServices() {
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH --env-file=$DOCKER_ENV_PATH down"
}
function restartServices() {
stopServices
startServices
}
function upgrade() {
echo "***** STOPPING SERVICES ****"
stopServices
echo
echo "***** DOWNLOADING STABLE VERSION ****"
download
echo "***** PLEASE VALIDATE AND START SERVICES ****"
}
function viewSpecificLogs(){
local SERVICE_NAME=$1
if /bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH ps | grep -q '$SERVICE_NAME'"; then
echo "Service '$SERVICE_NAME' is running."
else
echo "Service '$SERVICE_NAME' is not running."
fi
/bin/bash -c "$COMPOSE_CMD -f $DOCKER_FILE_PATH logs -f $SERVICE_NAME"
}
function viewLogs(){
ARG_SERVICE_NAME=$2
if [ -z "$ARG_SERVICE_NAME" ];
then
echo
echo "Select a Service you want to view the logs for:"
echo " 1) Web"
echo " 2) Space"
echo " 3) API"
echo " 4) Worker"
echo " 5) Beat-Worker"
echo " 6) Migrator"
echo " 7) Proxy"
echo " 8) Redis"
echo " 9) Postgres"
echo " 10) Minio"
echo " 0) Back to Main Menu"
echo
read -p "Service: " DOCKER_SERVICE_NAME
until (( DOCKER_SERVICE_NAME >= 0 && DOCKER_SERVICE_NAME <= 10 )); do
echo "Invalid selection. Please enter a number between 1 and 11."
read -p "Service: " DOCKER_SERVICE_NAME
done
if [ -z "$DOCKER_SERVICE_NAME" ];
then
echo "INVALID SERVICE NAME SUPPLIED"
else
case $DOCKER_SERVICE_NAME in
1) viewSpecificLogs "web";;
2) viewSpecificLogs "space";;
3) viewSpecificLogs "api";;
4) viewSpecificLogs "worker";;
5) viewSpecificLogs "beat-worker";;
6) viewSpecificLogs "migrator";;
7) viewSpecificLogs "proxy";;
8) viewSpecificLogs "plane-redis";;
9) viewSpecificLogs "plane-db";;
10) viewSpecificLogs "plane-minio";;
0) askForAction;;
*) echo "INVALID SERVICE NAME SUPPLIED";;
esac
fi
elif [ -n "$ARG_SERVICE_NAME" ];
then
ARG_SERVICE_NAME=$(echo "$ARG_SERVICE_NAME" | tr '[:upper:]' '[:lower:]')
case $ARG_SERVICE_NAME in
web) viewSpecificLogs "web";;
space) viewSpecificLogs "space";;
api) viewSpecificLogs "api";;
worker) viewSpecificLogs "worker";;
beat-worker) viewSpecificLogs "beat-worker";;
migrator) viewSpecificLogs "migrator";;
proxy) viewSpecificLogs "proxy";;
redis) viewSpecificLogs "plane-redis";;
postgres) viewSpecificLogs "plane-db";;
minio) viewSpecificLogs "plane-minio";;
*) echo "INVALID SERVICE NAME SUPPLIED";;
esac
else
echo "INVALID SERVICE NAME SUPPLIED"
fi
}
function backupSingleVolume() {
backupFolder=$1
selectedVolume=$2
# Backup data from Docker volume to the backup folder
docker run --rm -v "$selectedVolume":/source -v "$backupFolder":/backup busybox sh -c 'cp -r /source/* /backup/'
}
function backupData() {
local datetime=$(date +"%Y%m%d-%H%M")
local BACKUP_FOLDER=$PLANE_INSTALL_DIR/backup/$datetime
mkdir -p "$BACKUP_FOLDER"
volumes=$(docker volume ls -f "name=plane-app" --format "{{.Name}}" | grep -E "_pgdata|_redisdata|_uploads")
# Check if there are any matching volumes
if [ -z "$volumes" ]; then
echo "No volumes found starting with 'plane-app'"
exit 1
fi
for vol in $volumes; do
# selected_volume=$(echo "$volumes" | sed -n "${volume_number}p")
local backup_folder="$BACKUP_FOLDER/$vol"
mkdir -p "$backup_folder"
echo "Backing Up $vol"
backupSingleVolume "$backup_folder" "$vol"
done
echo ""
echo "Backup completed successfully. Backup files are stored in $BACKUP_FOLDER"
echo ""
}
function askForAction() {
local DEFAULT_ACTION=$1
if [ -z "$DEFAULT_ACTION" ];
then
echo
echo "Select a Action you want to perform:"
echo " 1) Install (${CPU_ARCH})"
echo " 2) Start"
echo " 3) Stop"
echo " 4) Restart"
echo " 5) Upgrade"
echo " 6) View Logs"
echo " 7) Backup Data"
echo " 8) Exit"
echo
read -p "Action [2]: " ACTION
until [[ -z "$ACTION" || "$ACTION" =~ ^[1-8]$ ]]; do
echo "$ACTION: invalid selection."
read -p "Action [2]: " ACTION
done
if [ -z "$ACTION" ];
then
ACTION=2
fi
echo
fi
if [ "$ACTION" == "1" ] || [ "$DEFAULT_ACTION" == "install" ]
then
install
askForAction
elif [ "$ACTION" == "2" ] || [ "$DEFAULT_ACTION" == "start" ]
then
startServices
# askForAction
elif [ "$ACTION" == "3" ] || [ "$DEFAULT_ACTION" == "stop" ]
then
stopServices
# askForAction
elif [ "$ACTION" == "4" ] || [ "$DEFAULT_ACTION" == "restart" ]
then
restartServices
# askForAction
elif [ "$ACTION" == "5" ] || [ "$DEFAULT_ACTION" == "upgrade" ]
then
upgrade
askForAction
elif [ "$ACTION" == "6" ] || [ "$DEFAULT_ACTION" == "logs" ]
then
viewLogs $@
askForAction
elif [ "$ACTION" == "7" ] || [ "$DEFAULT_ACTION" == "backup" ]
then
backupData
askForAction
elif [ "$ACTION" == "8" ]
then
exit 0
else
echo "INVALID ACTION SUPPLIED"
fi
}
# if docker-compose is installed
if command -v docker-compose &> /dev/null
then
COMPOSE_CMD="docker-compose"
else
COMPOSE_CMD="docker compose"
fi
# CPU ARCHITECHTURE BASED SETTINGS
CPU_ARCH=$(uname -m)
if [[ $CPU_ARCH == "amd64" || $CPU_ARCH == "x86_64" || ( $BRANCH == "master" && ( $CPU_ARCH == "arm64" || $CPU_ARCH == "aarch64" ) ) ]];
then
USE_GLOBAL_IMAGES=1
DOCKERHUB_USER=makeplane
PULL_POLICY=always
else
USE_GLOBAL_IMAGES=0
DOCKERHUB_USER=myplane
PULL_POLICY=never
fi
if [ "$BRANCH" == "master" ];
then
export APP_RELEASE=stable
fi
# REMOVE SPECIAL CHARACTERS FROM BRANCH NAME
if [ "$BRANCH" != "master" ];
then
PLANE_INSTALL_DIR=$PWD/plane-app-$(echo $BRANCH | sed -r 's@(\/|" "|\.)@-@g')
fi
mkdir -p $PLANE_INSTALL_DIR/archive
DOCKER_FILE_PATH=$PLANE_INSTALL_DIR/docker-compose.yaml
DOCKER_ENV_PATH=$PLANE_INSTALL_DIR/plane.env
# BACKWARD COMPATIBILITY
OLD_DOCKER_ENV_PATH=$PLANE_INSTALL_DIR/.env
if [ -f "$OLD_DOCKER_ENV_PATH" ];
then
mv "$OLD_DOCKER_ENV_PATH" "$DOCKER_ENV_PATH"
OS_NAME=$(uname)
if [ "$OS_NAME" == "Darwin" ];
then
sed -i '' -e 's@APP_RELEASE=latest@APP_RELEASE=stable@' "$DOCKER_ENV_PATH"
else
sed -i -e 's@APP_RELEASE=latest@APP_RELEASE=stable@' "$DOCKER_ENV_PATH"
fi
fi
print_header
askForAction $@