-
Notifications
You must be signed in to change notification settings - Fork 0
/
install.sh
executable file
·227 lines (186 loc) · 6.8 KB
/
install.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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
#!/bin/bash
function getNextPort() {
INIT_PORT="${1}"
LIMIT_PORT="${2}"
FINAL_PORT=$(( $INIT_PORT + $LIMIT_PORT ))
for PORT in $(seq ${INIT_PORT} ${FINAL_PORT})
do
NETSTAT=$(netstat -utna | grep ${PORT})
if [[ $NETSTAT == "" ]]; then
AVAILABLE_PORT=$PORT
break
fi
done
}
function install_nginx {
cat <<EOF > /etc/nginx/nginx.conf
user www-data;
worker_processes auto;
error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
# Include separate files in the main "http{}" configuration
include conf.d/*.conf;
# Allow status requests from localhost
server
{
listen 127.0.0.1;
server_name localhost;
location /nginx_status {
stub_status on; # activate stub_status module
access_log off;
allow 127.0.0.1; # localhost
allow ::1; # localhost
deny all;
}
}
include upstream/*.conf;
}
EOF
cat <<EOF > /etc/nginx/conf.d/performance.conf
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 10;
send_timeout 10;
types_hash_max_size 2048;
client_max_body_size 20M;
client_body_timeout 10;
client_header_timeout 10;
large_client_header_buffers 8 16k;
EOF
cat <<EOF > /etc/nginx/conf.d/gzip.conf
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/rss+xml application/atom+xml image/svg+xml;
EOF
mkdir -p /etc/nginx/ssl
openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
chmod 400 /etc/nginx/ssl/dhparam.pem
cat <<EOF > /etc/nginx/conf.d/ssl.conf
# Diffie-Hellman parameters
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 20m;
ssl_session_tickets off;
# SSL OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
# DNS resolver configuration for OCSP response
resolver 8.8.4.4 8.8.8.8 valid=300s ipv6=off;
resolver_timeout 10s;
EOF
cat <<EOF > /etc/nginx/conf.d/security.conf
# Hide nginx server version
server_tokens off;
EOF
}
function install_upstream {
mkdir -p /etc/nginx/upstream
cat <<EOF > /etc/nginx/upstream/${HOSTNAME}.conf
server {
server_name $HOSTNAME;
location / {
proxy_pass http://localhost:$HAPIFHIR_EXPOSED_PORT;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host \$server_name;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/$HOSTNAME/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$HOSTNAME/privkey.pem;
}
server {
if (\$host = $HOSTNAME) {
return 301 https://\$host\$request_uri;
}
server_name $HOSTNAME;
listen 80;
return 404;
}
EOF
}
# Send error output and exit with status code 1
function errout {
echo "ERROR: $*, exiting..." >&2
echo "========================================================="
docker-compose down
sed -i "s/$HOSTNAME/HOST_NAME/g" docker-compose.yml
rm -rf /etc/nginx/upstream/hapifhir.conf
exit 1
}
if [ $# -ne 1 ]; then
echo "Usage: install.sh <HOSTNAME>"
exit 1
fi
HOSTNAME="$1"
HOSTNAME_ENV=$(grep HOSTNAME .env | awk -F '=' '{printf $2}')
CONTAINERS=$(docker ps | grep "_${HOSTNAME}")
CONTAINERS_ENV=$(docker ps | grep "_${HOSTNAME_ENV}")
if [[ $CONTAINERS != "" ]]; then
echo "HapiFHIR containers are already running with provided hostname: ${HOSTNAME}"
exit 1
fi
if [[ $CONTAINERS_ENV != "" ]]; then
echo "HapiFHIR containers are already running with current hostname in .env: ${HOSTNAME_ENV}"
exit 1
fi
echo "Installing docker and docker-compose"
apt update 1>&2 && apt install docker docker-compose jq unzip sendmail -y
echo "Setting hostname: $HOSTNAME"
sed -i "s/$HOSTNAME_ENV/$HOSTNAME/g" .env ./docker-compose.yml
# Change exposed port to the next available one. Parameters: Initial Port and Limit Port
HAPIFHIR_EXPOSED_PORT=$(grep HAPIFHIR_EXPOSED_PORT .env | awk -F '=' '{printf $2}')
getNextPort "$HAPIFHIR_EXPOSED_PORT" "1000"
sed -i "s/HAPIFHIR_EXPOSED_PORT=$HAPIFHIR_EXPOSED_PORT/HAPIFHIR_EXPOSED_PORT=$AVAILABLE_PORT/g" .env
echo "HapiFHIR docker service will be exposed on port: $AVAILABLE_PORT"
HAPIFHIR_EXPOSED_PORT=$AVAILABLE_PORT
POSTGRES_EXPOSED_PORT=$(grep POSTGRES_EXPOSED_PORT .env | awk -F '=' '{printf $2}')
getNextPort "$POSTGRES_EXPOSED_PORT" "1000"
sed -i "s/POSTGRES_EXPOSED_PORT=$POSTGRES_EXPOSED_PORT/POSTGRES_EXPOSED_PORT=$AVAILABLE_PORT/g" .env
echo "Postgres docker service will be exposed on port: $AVAILABLE_PORT"
POSTGRES_EXPOSED_PORT=$AVAILABLE_PORT
echo "Building and creating docker containers"
if ! docker-compose up --build -d; then
errout "Failed docker-compose" 1>&2
fi
echo "Configuring nginx"
if ! which nginx 1>/dev/null; then
apt update 1>&2 && apt install nginx -y
install_nginx
install_upstream
else
install_upstream
fi
if ! which certbot 1>/dev/null; then
sudo snap install --classic certbot 1>&2
sudo ln -s /snap/bin/certbot /usr/bin/certbot
service nginx stop
if ! certbot certonly -d $HOSTNAME --standalone -m [email protected] --agree-tos -n --no-eff-email; then
errout "Failed when installing certificate"
fi
service nginx start
else
service nginx stop
if ! certbot certonly -d $HOSTNAME --standalone -m [email protected] --agree-tos -n --no-eff-email; then
errout "Failed when installing certificate"
fi
service nginx start
fi
echo "Successfully installed HapiFHIR."