#!/usr/bin/env bash set -eo pipefail; [[ $TRACE ]] && set -x # A script to bootstrap dokku. # It expects to be run on Ubuntu 14.04 via 'sudo' # If installing a tag higher than 0.3.13, it may install dokku via a package (so long as the package is higher than 0.3.13) # It checks out the dokku source code from Github into ~/dokku and then runs 'make install' from dokku source. # We wrap this whole script in functions, so that we won't execute # until the entire script is downloaded. # That's good because it prevents our output overlapping with wget's. # It also means that we can't run a partially downloaded script. proc ensure-environment { var FREE_MEMORY = '' echo "Preparing to install $DOKKU_TAG from $DOKKU_REPO..." if ! command -v apt-get &>/dev/null; { echo "This installation script requires apt-get. For manual installation instructions, consult http://dokku.viewdocs.io/dokku/advanced-installation/" exit 1 } hostname -f > /dev/null !2 > !1 || do { echo "This installation script requires that you have a hostname set for the instance. Please set a hostname for 127.0.0.1 in your /etc/hosts" exit 1 } FREE_MEMORY := $[grep MemTotal /proc/meminfo | awk '{print $2}] if [[ "$FREE_MEMORY" -lt 1003600 ]] { echo "For dokku to build containers, it is strongly suggested that you have 1024 megabytes or more of free memory" echo "If necessary, please consult this document to setup swap: http://dokku.viewdocs.io/dokku/advanced-installation/#vms-with-less-than-1gb-of-memory" } } proc install-requirements { echo "--> Ensuring we have the proper dependencies" apt-get update -qq > /dev/null if [[ $(lsb_release -sr) == "12.04" ]] { apt-get -qq -y install python-software-properties } } proc install-dokku { if [[ -n $DOKKU_BRANCH ]] { install-dokku-from-source "origin/$DOKKU_BRANCH" } elif [[ -n $DOKKU_TAG ]] { var DOKKU_SEMVER = $(DOKKU_TAG//v) global major := $[echo $DOKKU_SEMVER | awk '{split($0,a,"."); print a[1]}] global minor := $[echo $DOKKU_SEMVER | awk '{split($0,a,"."); print a[2]}] global patch := $[echo $DOKKU_SEMVER | awk '{split($0,a,"."); print a[3]}] # 0.3.13 was the first version with a debian package if [[ "$major" -eq "0" ]] && [[ "$minor" -eq "3" ]] && [[ "$patch" -ge "13" ]] { install-dokku-from-package $DOKKU_SEMVER echo "--> Running post-install dependency installation" dokku plugins-install-dependencies # 0.4.0 implemented a `plugin` plugin } elif [[ "$major" -eq "0" ]] && [[ "$minor" -ge "4" ]] && [[ "$patch" -ge "0" ]] { install-dokku-from-package $DOKKU_SEMVER echo "--> Running post-install dependency installation" sudo -E dokku plugin:install-dependencies --core } else { install-dokku-from-source $DOKKU_TAG } } else { install-dokku-from-package echo "--> Running post-install dependency installation" sudo -E dokku plugin:install-dependencies --core } } proc install-dokku-from-source { var DOKKU_CHECKOUT = $1 apt-get -qq -y install git make software-properties-common cd /root if [[ ! -d /root/dokku ]] { git clone $DOKKU_REPO /root/dokku } cd /root/dokku git fetch origin [[ -n $DOKKU_CHECKOUT ]] && git checkout $DOKKU_CHECKOUT make install } proc install-dokku-from-package { var DOKKU_CHECKOUT = $1 var NO_INSTALL_RECOMMENDS = $(DOKKU_NO_INSTALL_RECOMMENDS:="") if [[ -n $DOKKU_DOCKERFILE ]] { NO_INSTALL_RECOMMENDS := '" --no-install-recommends '" } echo "--> Initial apt-get update" apt-get update -qq > /dev/null apt-get -qq -y install apt-transport-https echo "--> Installing docker" if uname -r | grep -q linode { echo "--> NOTE: Using Linode? Docker might complain about missing AUFS support." echo " See http://dokku.viewdocs.io/dokku/getting-started/install/linode/" echo " Installation will continue in 10 seconds." sleep 10 } wget -nv -O - https://get.docker.com/ | sh echo "--> Installing dokku" wget -nv -O - https://packagecloud.io/gpg.key | apt-key add - echo "deb https://packagecloud.io/dokku/dokku/ubuntu/ trusty main" | tee /etc/apt/sources.list.d/dokku.list apt-get update -qq > /dev/null [[ -n $DOKKU_VHOST_ENABLE ]] && echo "dokku dokku/vhost_enable boolean $DOKKU_VHOST_ENABLE" | sudo debconf-set-selections [[ -n $DOKKU_WEB_CONFIG ]] && echo "dokku dokku/web_config boolean $DOKKU_WEB_CONFIG" | sudo debconf-set-selections [[ -n $DOKKU_HOSTNAME ]] && echo "dokku dokku/hostname string $DOKKU_HOSTNAME" | sudo debconf-set-selections [[ -n $DOKKU_SKIP_KEY_FILE ]] && echo "dokku dokku/skip_key_file boolean $DOKKU_SKIP_KEY_FILE" | sudo debconf-set-selections [[ -n $DOKKU_KEY_FILE ]] && echo "dokku dokku/key_file string $DOKKU_KEY_FILE" | sudo debconf-set-selections if [[ -n $DOKKU_CHECKOUT ]] { # shellcheck disable=SC2086 apt-get -qq -y $NO_INSTALL_RECOMMENDS install "dokku=$DOKKU_CHECKOUT" } else { # shellcheck disable=SC2086 apt-get -qq -y $NO_INSTALL_RECOMMENDS install dokku } } proc main { export DEBIAN_FRONTEND=noninteractive export DOKKU_REPO=$(DOKKU_REPO:-"https://github.com/dokku/dokku.git") ensure-environment install-requirements install-dokku } main @Argv (CommandList children: [ (Sentence child:(C {(set)} {(-eo)} {(pipefail)}) terminator:) (AndOr children: [(DBracket expr:(WordTest w:{($ VSub_Name "$TRACE")})) (C {(set)} {(-x)})] op_id: Op_DAmp ) (FuncDef name: ensure-environment body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:FREE_MEMORY) op:Equal spids:[58])] spids: [56] ) (C {(echo)} { (DQ ("Preparing to install ") ($ VSub_Name "$DOKKU_TAG") (" from ") ($ VSub_Name "$DOKKU_REPO") (...) ) } ) (If arms: [ (if_arm cond: [ (Sentence child: (Pipeline children:[(C {(command)} {(-v)} {(apt-get)})] negated:True) terminator: ) (Sentence child: (SimpleCommand redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(/dev/null)} spids: [83] ) ] ) terminator: ) ] action: [ (C {(echo)} { (DQ ( "This installation script requires apt-get. For manual installation instructions, consult http://dokku.viewdocs.io/dokku/advanced-installation/" ) ) } ) (C {(exit)} {(1)}) ] spids: [-1 87] ) ] spids: [-1 102] ) (AndOr children: [ (SimpleCommand words: [{(hostname)} {(-f)}] redirects: [ (Redir op_id: Redir_Great fd: -1 arg_word: {(/dev/null)} spids: [110] ) (Redir op_id:Redir_GreatAnd fd:2 arg_word:{(1)} spids:[114]) ] ) (BraceGroup children: [ (C {(echo)} { (DQ ( "This installation script requires that you have a hostname set for the instance. Please set a hostname for 127.0.0.1 in your /etc/hosts" ) ) } ) (C {(exit)} {(1)}) ] spids: [119] ) ] op_id: Op_DPipe ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:FREE_MEMORY) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(grep)} {(MemTotal)} {(/proc/meminfo)}) (C {(awk)} {(SQ <"{print $2}">)}) ] negated: False ) ] ) left_token: spids: [139 153] ) } spids: [138] ) ] spids: [138] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_lt left: {(DQ ($ VSub_Name "$FREE_MEMORY"))} right: {(1003600)} ) ) terminator: ) ] action: [ (C {(echo)} { (DQ ( "For dokku to build containers, it is strongly suggested that you have 1024 megabytes or more of free memory" ) ) } ) (C {(echo)} { (DQ ( "If necessary, please consult this document to setup swap: http://dokku.viewdocs.io/dokku/advanced-installation/#vms-with-less-than-1gb-of-memory" ) ) } ) ] spids: [-1 171] ) ] spids: [-1 188] ) ] spids: [53] ) spids: [49 52] ) (FuncDef name: install-requirements body: (BraceGroup children: [ (C {(echo)} {(DQ ("--> Ensuring we have the proper dependencies"))}) (SimpleCommand words: [{(apt-get)} {(update)} {(-qq)}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[213])] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolBinary op_id: BoolBinary_GlobDEqual left: { (CommandSubPart command_list: (CommandList children: [(C {(lsb_release)} {(-sr)})] ) left_token: spids: [222 226] ) } right: {(DQ (12.04))} ) ) terminator: ) ] action: [(C {(apt-get)} {(-qq)} {(-y)} {(install)} {(python-software-properties)})] spids: [-1 237] ) ] spids: [-1 251] ) ] spids: [197] ) spids: [193 196] ) (FuncDef name: install-dokku body: (BraceGroup children: [ (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_BRANCH")}) ) terminator: ) ] action: [ (C {(install-dokku-from-source)} {(DQ (origin/) ($ VSub_Name "$DOKKU_BRANCH"))}) ] spids: [-1 274] ) (if_arm cond: [ (Sentence child: (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_TAG")}) ) terminator: ) ] action: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:DOKKU_SEMVER) op: Equal rhs: { (DQ (BracedVarSub token: suffix_op: (PatSub pat: {(v)} do_all: True do_prefix: False do_suffix: False ) spids: [303 308] ) ) } spids: [301] ) ] spids: [299] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:major) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$DOKKU_SEMVER"))}) (C {(awk)} {(SQ <"{split($0,a,\".\"); print a[1]}">)}) ] negated: False ) ] ) left_token: spids: [313 327] ) } spids: [312] ) ] spids: [312] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:minor) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$DOKKU_SEMVER"))}) (C {(awk)} {(SQ <"{split($0,a,\".\"); print a[2]}">)}) ] negated: False ) ] ) left_token: spids: [331 345] ) } spids: [330] ) ] spids: [330] ) (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:patch) op: Equal rhs: { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Name "$DOKKU_SEMVER"))}) (C {(awk)} {(SQ <"{split($0,a,\".\"); print a[3]}">)}) ] negated: False ) ] ) left_token: spids: [349 363] ) } spids: [348] ) ] spids: [348] ) (If arms: [ (if_arm cond: [ (Sentence child: (AndOr children: [ (DBracket expr: (BoolBinary op_id: BoolBinary_eq left: {(DQ ($ VSub_Name "$major"))} right: {(DQ (0))} ) ) (AndOr children: [ (DBracket expr: (BoolBinary op_id: BoolBinary_eq left: {(DQ ($ VSub_Name "$minor"))} right: {(DQ (3))} ) ) (DBracket expr: (BoolBinary op_id: BoolBinary_ge left: {(DQ ($ VSub_Name "$patch"))} right: {(DQ (13))} ) ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) terminator: ) ] action: [ (C {(install-dokku-from-package)} {(DQ ($ VSub_Name "$DOKKU_SEMVER"))}) (C {(echo)} {(DQ ("--> Running post-install dependency installation"))}) (C {(dokku)} {(plugins-install-dependencies)}) ] spids: [-1 420] ) (if_arm cond: [ (Sentence child: (AndOr children: [ (DBracket expr: (BoolBinary op_id: BoolBinary_eq left: {(DQ ($ VSub_Name "$major"))} right: {(DQ (0))} ) ) (AndOr children: [ (DBracket expr: (BoolBinary op_id: BoolBinary_ge left: {(DQ ($ VSub_Name "$minor"))} right: {(DQ (4))} ) ) (DBracket expr: (BoolBinary op_id: BoolBinary_ge left: {(DQ ($ VSub_Name "$patch"))} right: {(DQ (0))} ) ) ] op_id: Op_DAmp ) ] op_id: Op_DAmp ) terminator: ) ] action: [ (C {(install-dokku-from-package)} {(DQ ($ VSub_Name "$DOKKU_SEMVER"))}) (C {(echo)} {(DQ ("--> Running post-install dependency installation"))}) (C {(sudo)} {(-E)} {(dokku)} {(plugin) (Lit_Other ":") (install-dependencies)} {(--core)} ) ] spids: [446 495] ) ] else_action: [(C {(install-dokku-from-source)} {(DQ ($ VSub_Name "$DOKKU_TAG"))})] spids: [525 535] ) ] spids: [285 296] ) ] else_action: [ (C {(install-dokku-from-package)}) (C {(echo)} {(DQ ("--> Running post-install dependency installation"))}) (C {(sudo)} {(-E)} {(dokku)} {(plugin) (Lit_Other ":") (install-dependencies)} {(--core)}) ] spids: [538 564] ) ] spids: [260] ) spids: [256 259] ) (FuncDef name: install-dokku-from-source body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:DOKKU_CHECKOUT) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [579] ) ] spids: [577] ) (C {(apt-get)} {(-qq)} {(-y)} {(install)} {(git)} {(make)} {(software-properties-common)}) (C {(cd)} {(/root)}) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (LogicalNot child:(BoolUnary op_id:BoolUnary_d child:{(/root/dokku)})) ) terminator: ) ] action: [(C {(git)} {(clone)} {(DQ ($ VSub_Name "$DOKKU_REPO"))} {(/root/dokku)})] spids: [-1 618] ) ] spids: [-1 632] ) (C {(cd)} {(/root/dokku)}) (C {(git)} {(fetch)} {(origin)}) (AndOr children: [ (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_CHECKOUT")}) ) (C {(git)} {(checkout)} {(DQ ($ VSub_Name "$DOKKU_CHECKOUT"))}) ] op_id: Op_DAmp ) (C {(make)} {(install)}) ] spids: [574] ) spids: [570 573] ) (FuncDef name: install-dokku-from-package body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:DOKKU_CHECKOUT) op: Equal rhs: {(DQ ($ VSub_Number "$1"))} spids: [683] ) ] spids: [681] ) (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:NO_INSTALL_RECOMMENDS) op: Equal rhs: { (BracedVarSub token: suffix_op: (StringUnary op_id:VTest_ColonEquals arg_word:{(DQ )}) spids: [692 697] ) } spids: [691] ) ] spids: [689] ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_DOCKERFILE")}) ) terminator: ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:NO_INSTALL_RECOMMENDS) op: Equal rhs: {(DQ (" --no-install-recommends "))} spids: [715] ) ] spids: [715] ) ] spids: [-1 712] ) ] spids: [-1 721] ) (C {(echo)} {(DQ ("--> Initial apt-get update"))}) (SimpleCommand words: [{(apt-get)} {(update)} {(-qq)}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[738])] ) (C {(apt-get)} {(-qq)} {(-y)} {(install)} {(apt-transport-https)}) (C {(echo)} {(DQ ("--> Installing docker"))}) (If arms: [ (if_arm cond: [ (Sentence child: (Pipeline children: [(C {(uname)} {(-r)}) (C {(grep)} {(-q)} {(linode)})] negated: False ) terminator: ) ] action: [ (C {(echo)} { (DQ ( "--> NOTE: Using Linode? Docker might complain about missing AUFS support." ) ) } ) (C {(echo)} { (DQ ( " See http://dokku.viewdocs.io/dokku/getting-started/install/linode/" ) ) } ) (C {(echo)} {(DQ (" Installation will continue in 10 seconds."))}) (C {(sleep)} {(10)}) ] spids: [-1 777] ) ] spids: [-1 806] ) (Pipeline children: [ (C {(wget)} {(-nv)} {(-O)} {(-)} {(https) (Lit_Other ":") (//get.docker.com/)}) (C {(sh)}) ] negated: False ) (C {(echo)} {(DQ ("--> Installing dokku"))}) (Pipeline children: [ (C {(wget)} {(-nv)} {(-O)} {(-)} {(https) (Lit_Other ":") (//packagecloud.io/gpg.key)}) (C {(apt-key)} {(add)} {(-)}) ] negated: False ) (Pipeline children: [ (C {(echo)} {(DQ ("deb https://packagecloud.io/dokku/dokku/ubuntu/ trusty main"))}) (C {(tee)} {(/etc/apt/sources.list.d/dokku.list)}) ] negated: False ) (SimpleCommand words: [{(apt-get)} {(update)} {(-qq)}] redirects: [(Redir op_id:Redir_Great fd:-1 arg_word:{(/dev/null)} spids:[874])] ) (AndOr children: [ (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_VHOST_ENABLE")}) ) (Pipeline children: [ (C {(echo)} { (DQ ("dokku dokku/vhost_enable boolean ") ($ VSub_Name "$DOKKU_VHOST_ENABLE")) } ) (C {(sudo)} {(debconf-set-selections)}) ] negated: False ) ] op_id: Op_DAmp ) (AndOr children: [ (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_WEB_CONFIG")}) ) (Pipeline children: [ (C {(echo)} {(DQ ("dokku dokku/web_config boolean ") ($ VSub_Name "$DOKKU_WEB_CONFIG"))} ) (C {(sudo)} {(debconf-set-selections)}) ] negated: False ) ] op_id: Op_DAmp ) (AndOr children: [ (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_HOSTNAME")}) ) (Pipeline children: [ (C {(echo)} {(DQ ("dokku dokku/hostname string ") ($ VSub_Name "$DOKKU_HOSTNAME"))}) (C {(sudo)} {(debconf-set-selections)}) ] negated: False ) ] op_id: Op_DAmp ) (AndOr children: [ (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_SKIP_KEY_FILE")}) ) (Pipeline children: [ (C {(echo)} { (DQ ("dokku dokku/skip_key_file boolean ") ($ VSub_Name "$DOKKU_SKIP_KEY_FILE") ) } ) (C {(sudo)} {(debconf-set-selections)}) ] negated: False ) ] op_id: Op_DAmp ) (AndOr children: [ (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_KEY_FILE")}) ) (Pipeline children: [ (C {(echo)} {(DQ ("dokku dokku/key_file string ") ($ VSub_Name "$DOKKU_KEY_FILE"))}) (C {(sudo)} {(debconf-set-selections)}) ] negated: False ) ] op_id: Op_DAmp ) (If arms: [ (if_arm cond: [ (Sentence child: (DBracket expr: (BoolUnary op_id:BoolUnary_n child:{($ VSub_Name "$DOKKU_CHECKOUT")}) ) terminator: ) ] action: [ (C {(apt-get)} {(-qq)} {(-y)} {($ VSub_Name "$NO_INSTALL_RECOMMENDS")} {(install)} {(DQ ("dokku=") ($ VSub_Name "$DOKKU_CHECKOUT"))} ) ] spids: [-1 1012] ) ] else_action: [ (C {(apt-get)} {(-qq)} {(-y)} {($ VSub_Name "$NO_INSTALL_RECOMMENDS")} {(install)} {(dokku)} ) ] spids: [1035 1055] ) ] spids: [678] ) spids: [674 677] ) (FuncDef name: main body: (BraceGroup children: [ (C {(export)} {(Lit_VarLike "DEBIAN_FRONTEND=") (noninteractive)}) (C {(export)} {(Lit_VarLike "DOKKU_REPO=") (BracedVarSub token: suffix_op: (StringUnary op_id: VTest_ColonHyphen arg_word: {(DQ ("https://github.com/dokku/dokku.git"))} ) spids: [1076 1082] ) } ) (C {(ensure-environment)}) (C {(install-requirements)}) (C {(install-dokku)}) ] spids: [1064] ) spids: [1060 1063] ) (C {(main)} {(DQ ($ VSub_At "$@"))}) ] )