-
Notifications
You must be signed in to change notification settings - Fork 3
/
deploy.sh
executable file
·193 lines (171 loc) · 7.04 KB
/
deploy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#!/bin/bash
# read https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
set -euxo pipefail
# Read .env settings if .env is present (.env will not be present in a pipeline)
# In that case, settings are read from environment
# https://stackoverflow.com/a/30969768
# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html#:~:text=option%2Dname%3A-,allexport,-Same%20as%20%2Da
# shellcheck disable=SC1091
# shellcheck source=/dev/null
if [ -f .env ]; then
echo Reading from .env file
set -o allexport && source .env && set +o allexport
else
echo No .env file present, assuming we\'re running within pipeline
fi
# shellcheck enable=all
if [ "$RUNNING_WITHIN_CI_PIPELINE" -eq 0 ]; then
echo We\'re not RUNNING_WITHIN_CI_PIPELINE so performing checkout to WORKSPACE_DIR "$WORKSPACE_DIR"
echo Checking for WORKSPACE_DIR
(set +x
if [ -z "$WORKSPACE_DIR" ]; then
echo "Please set the WORKSPACE_DIR variable and try again."
echo "💥 ERROR: WORKSPACE_DIR is not set but RUNNING_WITHIN_CI_PIPELINE was 0"
echo "If RUNNING_WITHIN_CI_PIPELINE=0 we expect you're running deploy.sh locally"
echo "and you're not running within an automated pipeline (GitHub actions/Gitlab Pipelines etc)."
echo "When running outside of a pipeline, deploy.sh needs to do a git checkout of"
echo "your repo, therefore you need to set WORKSPACE_DIR to a path"
echo "you'd like to clone the repo to."
echo "If you are trying to deploy within a pipeline, then change"
echo "RUNNING_WITHIN_CI_PIPELINE=0 to RUNNING_WITHIN_CI_PIPELINE=1"
exit 255
fi
)
echo Creating WORKSPACE_DIR
mkdir -p "$WORKSPACE_DIR"
echo Checking for GIT_CLONE_URL_OR_PATH
(set +x
if [ -n "${GIT_CLONE_URL_OR_PATH:+notset}" ]; then
echo "GIT_CLONE_URL_OR_PATH is set to $GIT_CLONE_URL_OR_PATH"
else
echo "💥 ERROR: GIT_CLONE_URL_OR_PATH is not set but RUNNING_WITHIN_CI_PIPELINE was 0"
echo "If RUNNING_WITHIN_CI_PIPELINE=0 we expect you're running deploy.sh locally"
echo "and you're not running within an automated pipeline (GitHub actions/Gitlab Pipelines etc)."
echo "When running outside of a pipeline, deploy.sh needs to do a git checkout of"
echo "your repo, therefore you need to set GIT_CLONE_URL_OR_PATH to the URL or"
echo "path of your git repo being deployed."
echo "If you are trying to deploy within a pipeline, then change"
echo "RUNNING_WITHIN_CI_PIPELINE=0 to RUNNING_WITHIN_CI_PIPELINE=1"
exit 255
fi
)
# Verify that WORKSPACE_DIR is not a critical system path
critical_paths=(
"/"
"/bin"
"/yoloyolo"
"/boot"
"/dev"
"/etc"
"/home"
"/lib"
"/lib64"
"/media"
"/mnt"
"/opt"
"/proc"
"/root"
"/run"
"/sbin"
"/srv"
"/sys"
"/tmp"
"/usr"
"/var"
)
(set +x
for path in "${critical_paths[@]}"; do
if [ "$WORKSPACE_DIR" == "$path" ]; then
echo "💥 Error: WORKSPACE_DIR is set to a dangerous critical path,"
echo "which you probably don't want to delete so we stopped before deletion."
echo "WORKSPACE_DIR was set to: $WORKSPACE_DIR"
echo "Please set a different path and try again. See .env.example"
exit 1
fi
done
)
echo Deleting current WORKSPACE_DIR "$WORKSPACE_DIR"
rm -rf "${WORKSPACE_DIR:?}/"* || true
rm -rf "${WORKSPACE_DIR:?}/."* || true
echo "Checking out git repo '$GIT_CLONE_URL_OR_PATH' to $WORKSPACE_DIR"
git clone "$GIT_CLONE_URL_OR_PATH" "$WORKSPACE_DIR"
echo "Changing directory to root of GIT_CLONE_URL_OR_PATH"
cd "$WORKSPACE_DIR"
fi
echo Checking if provided DOKKU_SSH_PRIVATE_KEY key requires a passphrase
if ssh-keygen -y -P "" -f /dev/stdin <<<"$DOKKU_SSH_PRIVATE_KEY"&>/dev/null; then
echo "✅ DOKKU_SSH_PRIVATE_KEY does not require a passphrase. OK."
else
echo "🧐 DOKKU_SSH_PRIVATE_KEY requires a passphrase. Ask user for passphrase"
echo Verify ssh-askpass is installed, needed for passphrase protected ssh key
(set +e
which ssh-askpass
ret=$?
if [ "$ret" -ne 0 ];
then
set +x
echo '💥 ERROR: The DOKKU_SSH_PRIVATE_KEY you have given requires a passphrase'
echo '(this is probably a mistake- if you want an automated pipeline, then'
echo generate an ssh key *without* a passphrase\).
echo If this wasn\'t a mistake and you want to enter a password every time,
echo 'then you must install ssh-askpass'
echo e.g. \'sudo apt install ssh-askpass\'
exit 255
fi)
fi
if [ -n "${AMBER_SECRET:+notset}" ]; then
echo "AMBER_SECRET is set"
else
echo "ERROR: AMBER_SECRET is not set"
exit 255
fi
echo Installing amber secrets manager
mkdir -p ./bin
curl -L https://github.com/fpco/amber/releases/download/v0.1.3/amber-x86_64-unknown-linux-musl > ./amber
chmod +x ./amber
mv ./amber ./bin/amber
PATH=./bin:$PATH
echo Setup ssh to talk to dokku host
mkdir -p ~/.ssh
amber -v exec -- sh -c 'ssh-keyscan $DOKKU_HOST >> ~/.ssh/known_hosts'
eval "$(ssh-agent -s)"
ssh-add -D
ssh-add - <<< "$DOKKU_SSH_PRIVATE_KEY"
ssh-add -l
SSH_ARGS="-F $SSH_CONFIG_FILE"
amber exec -- sh -c ''"ssh $SSH_ARGS"' dokku@$DOKKU_HOST -C $CONTAINER_HOSTING_API_KEY dokku apps:create $APP_NAME || true'
amber exec -- sh -c ''"ssh $SSH_ARGS"' dokku@$DOKKU_HOST -C $CONTAINER_HOSTING_API_KEY dokku builder:set $APP_NAME build-dir src'
amber exec -- sh -c ''"ssh $SSH_ARGS"' dokku@$DOKKU_HOST -C $CONTAINER_HOSTING_API_KEY dokku builder-dockerfile:set $APP_NAME dockerfile-path Dockerfile'
# Set common env settings
# Note we *dont* expand the APP_NAME env setting because the APP_NAME
# is worked out from the CONTAINER_HOSTING_API_KEY server side by
# searching the containers database:
# WHERE CONTAINER_HOSTING_API_KEY = CONTAINER_HOSTING_API_KEY
# see:
# https://github.com/KarmaComputing/container-hosting/blob/91573f47cf0de5bbd3a35d7e8a7a019e184c2117/dokku-wrapper.py#L44
#
echo Set app envrionment settings
amber exec -- sh -c ''"ssh $SSH_ARGS"' dokku@$DOKKU_HOST -C $CONTAINER_HOSTING_API_KEY \
dokku config:set --no-restart $APP_NAME \
DB_USER=$DB_USER\
DB_PASSWORD=$DB_PASSWORD\
DB_HOST=$DB_HOST\
DB_PORT=$DB_PORT\
DB_NAME=$DB_NAME\
RAILS_DEVELOPMENT_HOSTS=$APP_NAME.containers.anotherwebservice.com\
DATABASE_URL=$RAILS_DATABASE_URL\
SECRET_KEY=$DJANGO_SECRET_KEY\
ALLOWED_HOSTS=$ALLOWED_HOSTS\
DEBUG=$DJANGO_DEBUG\
DB_ENGINE=$DJANGO_ENGINE\
DB_NAME=$DJANGO_DB_NAME\
DB_HOST=$DJANGO_DB_HOST\
DB_USER=$DJANGO_DB_USER\
DB_PASSWORD=$DJANGO_DB_PASSWORD\
DB_PORT=$DJANGO_DB_PORT'
amber exec -- sh -c ''"ssh $SSH_ARGS"' dokku@$DOKKU_HOST -C $CONTAINER_HOSTING_API_KEY dokku git:sync --build $APP_NAME https://github.com/'"$GIT_USERNAME_OR_ORG"'/'"$GIT_REPO_NAME"'.git main'
# Assign letsencrypt wildcard certificate
# Note that SSH_ARGS are not stored in amber, which is why they are expanded
# vs the rest (e.g. DOKKU_HOST and CONTAINER_HOSTING_API_KEY which are stored
# within amber.yaml secrets
amber exec -v --unmasked -- sh -c 'ssh '"$SSH_ARGS"' dokku@$DOKKU_HOST -C "$CONTAINER_HOSTING_API_KEY dokku certs:add $APP_NAME < cert-key.tar"'