Adding the deployment shell script for Linux instances (#62)

TODO: Need to add checks for MacOS machines as well.

Co-authored-by: Nikhil Nandagopal <nikhil@appsmith.com>

Co-authored-by: Shrikant Sharat Kandula <shrikant@appsmith.com>
This commit is contained in:
Arpit Mohan 2020-07-10 19:18:42 +05:30 committed by GitHub
parent 4796b6edba
commit 4e08e69351
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 2010 additions and 0 deletions

179
deploy/install.sh Executable file
View File

@ -0,0 +1,179 @@
#!/bin/bash
set -o errexit
echo "" > appsmith_deploy.log
is_command_present() {
type "$1" >/dev/null 2>&1
}
install_docker() {
if [[ $package_manager -eq apt-get ]];then
echo "++++++++++++++++++++++++"
echo "Setting up docker repos"
sudo $package_manager update --quiet
sudo apt-get -y --quiet install gnupg-agent
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
else
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
fi
sudo ${package_manager} -y update --quiet
echo "Installing docker"
sudo ${package_manager} -y install docker-ce docker-ce-cli containerd.io --quiet
echo "Installing docker-compose"
sudo curl -L "https://github.com/docker/compose/releases/download/1.26.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
}
echo -e "\U1F44B Thank you for trying out Appsmith! "
echo ""
declare -A osInfo;
osInfo[/etc/debian_version]="apt-get"
osInfo[/etc/centos-release]="yum"
osInfo[/etc/redhat-release]="yum"
# Checking OS and assiging package manager
desired_os=0
echo -e "\U1F575 Detecting your OS"
echo ""
for f in ${!osInfo[@]}
do
if [[ -f $f ]];then
package_manager=${osInfo[$f]}
desired_os=1
fi
done
if [[ $desired_os -eq 0 ]];then
echo "This script is currently meant to install Appsmith on Ubuntu | RHEL | CentOS machines."
echo "Please contact hello@appsmith.com with your OS details if you wish to extend this support"
echo -e "Exiting for now. Bye! \U1F44B"
exit
fi
read -p 'Installation Directory [appsmith]: ' install_dir
install_dir=${install_dir:-appsmith}
mkdir -p $PWD/$install_dir
install_dir=$PWD/$install_dir
echo "Appsmith needs a mongodb instance to run"
echo "1) Automatically setup mongo db on this instance (recommended)"
echo "2) Connect to an external mongo db"
read -p 'Enter option number [1]: ' mongo_option
mongo_option=${mongo_option:-1}
if [[ $mongo_option -eq 2 ]];then
read -p 'Enter your mongo db host: ' mongo_host
read -p 'Enter the mongo root user: ' mongo_root_user
read -sp 'Enter the mongo password: ' mongo_root_password
read -p 'Enter your mongo database name: ' mongo_database
elif [[ $mongo_option -eq 1 ]];then
mongo_host="mongo"
mongo_database="appsmith"
read -p 'Set the mongo root user: ' mongo_root_user
read -sp 'Set the mongo password: ' mongo_root_password
fi
echo ""
read -p 'Would you like to setup a custom domain to access appsmith? [Y/n]: ' setup_domain
setup_domain=${setup_domain:-Y}
if [ $setup_domain == "Y" -o $setup_domain == "y" -o $setup_domain == "yes" -o $setup_domain == "Yes" ];then
read -p 'Enter your domain name (example.com): ' custom_domain
fi
NGINX_SSL_CMNT=""
if [[ -z $custom_domain ]]; then
NGINX_SSL_CMNT="#"
fi
#mkdir template
#cd template
#curl https://raw.githubusercontent.com/Nikhil-Nandagopal/test-rep/master/docker-compose.yml.sh --output docker-compose.yml.sh
#curl https://raw.githubusercontent.com/Nikhil-Nandagopal/test-rep/master/init-letsencrypt.sh.sh --output init-letsencrypt.sh.sh
#curl https://raw.githubusercontent.com/Nikhil-Nandagopal/test-rep/master/mongo-init.js.sh --output mongo-init.js.sh
#curl https://raw.githubusercontent.com/Nikhil-Nandagopal/test-rep/master/nginx_app.conf.sh --output nginx_app.conf.sh
#curl https://raw.githubusercontent.com/Nikhil-Nandagopal/test-rep/master/nginx_app.conf.sh --output nginx_app.conf.sh
#cd ..
# Role - Docker
if ! is_command_present docker ;then
install_docker
fi
# Role - Folder
for directory_name in nginx certbot mongo/db opa/config appsmith-server/config
do
if [[ ! -d "$install_dir/data/$directory_name" ]];then
mkdir -p "$install_dir/data/$directory_name"
fi
done
echo "Generating the configuration files from the templates"
. ./template/nginx_app.conf.sh
. ./template/docker-compose.yml.sh
. ./template/mongo-init.js.sh
. ./template/init-letsencrypt.sh.sh
. ./template/docker.env.sh
chmod 0755 init-letsencrypt.sh
declare -A fileInfo
fileInfo[/data/nginx/app.conf]="nginx_app.conf"
fileInfo[/docker-compose.yml]="docker-compose.yml"
fileInfo[/data/mongo/init.js]="mongo-init.js"
fileInfo[/init-letsencrypt.sh]="init-letsencrypt.sh"
fileInfo[/docker.env]="docker.env"
for f in ${!fileInfo[@]}
do
if [ -f $install_dir/$f ]
then
echo "File already exist."
read -p "File $f already exist. Would you like to replace it? [Y]: " value
if [ $value == "Y" -o $value == "y" -o $value == "yes" -o $value == "Yes" ]
then
mv -f ${fileInfo[$f]} $install_dir$f
echo "File $install_dir$f replaced succeffuly!"
else
echo "You choose not to replae existing file: $install_dir$f"
rm -rf ${fileInfo[$f]}
echo "File ${fileInfo[$f]} removed from source directory."
echo ""
fi
else
mv -f ${fileInfo[$f]} $install_dir$f
fi
done
echo ""
#echo "Running init-letsencrypt.sh...."
cd $install_dir
if [[ ! -z $custom_domain ]]; then
echo "Running init-letsencrypt.sh...."
sudo ./init-letsencrypt.sh
else
echo "No domain found. Skipping generation of LetsEncrypt certificate."
fi
echo "Updating the container images"
sudo docker-compose pull
echo "Starting the Appsmith containers"
sudo docker-compose -f docker-compose.yml up -d --remove-orphans
echo ""
echo "Your installation is complete. Please run the following command to ensure that all the containers are running without errors"
echo " cd $install_dir && sudo docker-compose ps -a"
echo -e "Peace out \U1F596"

View File

@ -0,0 +1,78 @@
#!/bin/sh
if [ -f docker-compose.yml ]
then
echo "file docker-compose.yml already exists"
else
touch docker-compose.yml
fi
cat > docker-compose.yml << EOF
version: "3.7"
services:
nginx:
image: appsmith/appsmith-editor
env_file: ./docker.env
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
command: "/bin/sh -c 'while :; do sleep 6h & wait \$\${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
depends_on:
- appsmith-internal-server
networks:
- appsmith
certbot:
image: certbot/certbot
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait \$\${!}; done;'"
networks:
- appsmith
appsmith-internal-server:
image: appsmith/appsmith-server:latest
env_file: ./docker.env
ports:
- "8080:8080"
links:
- mongo
depends_on:
- mongo
networks:
- appsmith
mongo:
image: mongo
ports:
- "27017:27017"
environment:
- MONGO_INITDB_DATABASE=appsmith
- MONGO_INITDB_ROOT_USERNAME=$mongo_root_user
- MONGO_INITDB_ROOT_PASSWORD=$mongo_root_password
volumes:
- ./data/mongo/db:/data/db
- ./data/mongo/init.js:/docker-entrypoint-initdb.d/init.js:ro
networks:
- appsmith
redis:
image: redis
ports:
- "6379:6379"
networks:
- appsmith
networks:
appsmith:
driver: bridge
EOF

View File

@ -0,0 +1,30 @@
#!/bin/sh
if [ -f docker-compose.yml ]
then
echo "file docker-compose.yml already exists"
else
touch docker-compose.yml
fi
cat > docker.env << EOF
APPSMITH_MAIL_ENABLED=false
# APPSMITH_MAIL_HOST=
# APPSMITH_MAIL_PASSWORD=
# APPSMITH_MAIL_PORT=
# APPSMITH_MAIL_SMTP_AUTH=
# APPSMITH_MAIL_SMTP_TLS_ENABLED=
# APPSMITH_MAIL_USERNAME=
# APPSMITH_MARKETPLACE_URL=
APPSMITH_MONGODB_URI=mongodb://$mongo_root_user:$mongo_root_password@$mongo_host/appsmith?retryWrites=true
# APPSMITH_OAUTH2_GITHUB_CLIENT_ID=
# APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET=
# APPSMITH_OAUTH2_GOOGLE_CLIENT_ID=
# APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET=
# APPSMITH_RAPID_API_KEY_VALUE=
APPSMITH_REDIS_URL=redis://redis:6379
# APPSMITH_ROLLBAR_ACCESS_TOKEN=
# APPSMITH_ROLLBAR_ENV=
# APPSMITH_SEGMENT_KEY=
EOF

View File

@ -0,0 +1,96 @@
#!/bin/sh
if [ -f init-letsencrypt.sh ]
then
echo "file init-letsencrypt.sh already exists"
else
touch init-letsencrypt.sh
fi
cat > init-letsencrypt.sh << EOF
#!/bin/bash
if ! [ -x "\$(command -v docker-compose)" ]; then
echo 'Error: docker-compose is not installed.' >&2
exit 1
fi
domains=($custom_domain)
rsa_key_size=4096
data_path="./data/certbot"
email="" # Adding a valid address is strongly recommended
staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits
echo "\$data_path"
if [ -d "\$data_path" ]; then
read -p "Existing data found for \$domains. Continue and replace existing certificate? [y/N] " decision
if [ "\$decision" != "Y" ] && [ "\$decision" != "y" ]; then
exit
fi
fi
if [ ! -e "\$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "\$data_path/conf/ssl-dhparams.pem" ]; then
echo "### Downloading recommended TLS parameters ..."
mkdir -p "\$data_path/conf"
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "\$data_path/conf/options-ssl-nginx.conf"
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "\$data_path/conf/ssl-dhparams.pem"
echo
fi
echo "### Creating dummy certificate for \$domains ..."
path="/etc/letsencrypt/live/\$domains"
mkdir -p "\$data_path/conf/live/\$domains"
docker-compose run --rm --entrypoint "\\
openssl req -x509 -nodes -newkey rsa:1024 -days 1\\
-keyout '\$path/privkey.pem' \\
-out '\$path/fullchain.pem' \\
-subj '/CN=localhost'" certbot
echo
echo "### Starting nginx ..."
docker-compose up --force-recreate -d nginx
echo
echo "### Deleting dummy certificate for \$domains ..."
docker-compose run --rm --entrypoint "\\
rm -Rf /etc/letsencrypt/live/\$domains && \\
rm -Rf /etc/letsencrypt/archive/\$domains && \\
rm -Rf /etc/letsencrypt/renewal/\$domains.conf" certbot
echo
echo "### Requesting Let's Encrypt certificate for \$domains ..."
#Join \$domains to -d args
domain_args=""
for domain in "\${domains[@]}"; do
domain_args="\$domain_args -d \$domain"
done
# Select appropriate email arg
case "\$email" in
"") email_arg="--register-unsafely-without-email" ;;
*) email_arg="--email \$email" ;;
esac
# Enable staging mode if needed
if [ \$staging != "0" ]; then staging_arg="--staging"; fi
docker-compose run --rm --entrypoint "\\
certbot certonly --webroot -w /var/www/certbot \\
\$staging_arg \\
\$email_arg \\
\$domain_args \\
--rsa-key-size \$rsa_key_size \\
--agree-tos \\
--force-renewal" certbot
echo
echo "### Reloading nginx ..."
docker-compose exec nginx nginx -s reload
EOF

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,84 @@
#!/bin/sh
if [ -f nginx_app.conf ]
then
echo "file nginx_app.conf already exists"
else
touch nginx_app.conf
fi
cat > nginx_app.conf << EOF
server {
listen 80;
$NGINX_SSL_CMNT server_name $custom_domain ;
client_max_body_size 10m;
gzip on;
root /var/www/appsmith;
index index.html index.htm;
#location / {
# return 301 https://\$host\$request_uri;
#}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Forwarded-Host \$host;
location / {
try_files \$uri /index.html =404;
}
location /f {
proxy_pass https://cdn.optimizely.com/;
}
location /api {
proxy_pass http://appsmith-internal-server:8080;
}
location /oauth2 {
proxy_pass http://appsmith-internal-server:8080;
}
}
$NGINX_SSL_CMNT server {
$NGINX_SSL_CMNT listen 443 ssl;
$NGINX_SSL_CMNT server_name $custom_domain;
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT ssl_certificate /etc/letsencrypt/live/$custom_domain/fullchain.pem;
$NGINX_SSL_CMNT ssl_certificate_key /etc/letsencrypt/live/$custom_domain/privkey.pem;
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT include /etc/letsencrypt/options-ssl-nginx.conf;
$NGINX_SSL_CMNT ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT proxy_set_header X-Forwarded-Proto \$scheme;
$NGINX_SSL_CMNT proxy_set_header X-Forwarded-Host \$host;
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT root /var/www/appsmith;
$NGINX_SSL_CMNT index index.html index.htm;
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT location / {
$NGINX_SSL_CMNT try_files \$uri /index.html =404;
$NGINX_SSL_CMNT }
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT location /f {
$NGINX_SSL_CMNT proxy_pass https://cdn.optimizely.com/;
$NGINX_SSL_CMNT }
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT location /api {
$NGINX_SSL_CMNT proxy_pass http://appsmith-internal-server:8080;
$NGINX_SSL_CMNT }
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT location /oauth2 {
$NGINX_SSL_CMNT proxy_pass http://appsmith-internal-server:8080;
$NGINX_SSL_CMNT }
$NGINX_SSL_CMNT
$NGINX_SSL_CMNT }
EOF