Skip to content

Instantly share code, notes, and snippets.

@anxolin
Last active October 12, 2020 23:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anxolin/87c2657038f662f63a83771273dac4d2 to your computer and use it in GitHub Desktop.
Save anxolin/87c2657038f662f63a83771273dac4d2 to your computer and use it in GitHub Desktop.
Deploy app/web with rsync
################################
# Staging: Deployment conf
################################
# overrided by: deployment-pro.conf
# Target
SERVER=example.com
DEPLOY_PATH=/opt/my_service
DEPLOY_USER=my_service
SERVER_POST_DEPLOY_COMMAND="sudo systemctl restart my_service"
# Source
DIST_PATH=build
BUILD_COMMAND=yarn build
RSYNC_EXTRA_PARAMS=
DEPLOY_IGNORE_FILE=
# Restrictions
ALLOW_DEPLOY_UNCOMMITED=false
ALLOW_DEPLOY_UNTRACKED=false
#!/usr/bin/env bash
###########################
# Deploy app script #
###########################
# 🏄 Usage
# deploy.sh
# Deploy using "deploy.conf"
# deploy.sh config-pro.conf
# Deploy using "deploy.conf" + "config-pro.conf" override
# DEBUG=true deploy.sh
# Deploy with DEBUG enabled
# 🚀 Update:
# wget -O deploy.sh --no-cache https://gist.githubusercontent.com/anxolin/87c2657038f662f63a83771273dac4d2/raw/deploy.sh
#
# 👀 Check last version of this gist in:
# https://gist.github.com/anxolin/87c2657038f662f63a83771273dac4d2
#
# 🤔 Troubleshooting:
# https://gist.github.com/anxolin/87c2657038f662f63a83771273dac4d2#gistcomment-2731552
set -e
# Colors
GREEN='\033[0;32m'
LG='\033[0;37m' # Light gray
RED='\033[1;31m'
NC='\033[0m' # No Color
if [[ ! -z $DEBUG ]]; then
# Debug
set -x
fi
#############################################################
# 1. Create deploy.conf with the following content:
# SERVER=example.com
# DIST_PATH=./dist
# DEPLOY_PATH=/var/www/cool-web
#
# Optionaly, you can add:
# DEPLOY_USER=www-data
#
# BUILD_COMMAND=yarn install
# Command executed to build the dist path
# SERVER_POST_DEPLOY_COMMAND=chown -R www-data:www-data
# Executes a command in the server
# RSYNC_EXTRA_PARAMS=
# Allows to add additional params to rsync
# ALLOW_DEPLOY_UNCOMMITED=false
# Allows to deploy uncommited files (default=false)
# ALLOW_DEPLOY_UNTRACKED=false
# Allows to deploy untracked files (default=false)
#
# 2. echo deploy.conf >> .gitignore
# 3. chmod +x deploy.sh
# 4. [optional] Create alternative config files (i.e. deploy-pro.conf)
# 5. ./deploy.sh [file]
#############################################################
# ALLOW_DEPLOY_UNCOMMITED: Notice you can override this for different
# environments
# true: If you don't use GIT or not require to have everything commited
# false: if you want to prevent deploying things that are not commited.
ALLOW_DEPLOY_UNCOMMITED=false
# ALLOW_DEPLOY_UNTRACKED: If you require changes to be commited, you can further
# ensure that there's no unstaged changes either.
# true: will allow to deploy with untracked files
# false: will not
ALLOW_DEPLOY_UNTRACKED=false
# Load conf
source deploy.conf
# CONF_FILE: Override conf file (environment)
if [[ ! -z $1 ]]; then
source $1
fi
echo
echo -e "${LG}---- DEPLOY APP ----${NC}"
echo -e "Deploy: ${GREEN}$DIST_PATH${NC}"
echo -e "To: ${GREEN}$DEPLOY_PATH${NC}"
echo -e "Server: ${GREEN}$SERVER${NC}"
echo -e "User: ${GREEN}$DEPLOY_USER${NC}"
echo -e "Additional rsync params: ${GREEN}$RSYNC_EXTRA_PARAMS${NC}"
echo -e "Build command: ${GREEN}$BUILD_COMMAND${NC}"
echo -e "Deploy ignore file: ${GREEN}$DEPLOY_IGNORE_FILE${NC}"
echo -e "Server - Post deploy command: ${GREEN}$SERVER_POST_DEPLOY_COMMAND${NC}"
echo -e "Git - allow uncommited changes: ${GREEN}$ALLOW_DEPLOY_UNCOMMITED${NC}"
echo -e "Git - allow untracked files: ${GREEN}$ALLOW_DEPLOY_UNTRACKED${NC}"
echo -e "${LG}----------------------${NC}"
echo
# Decide wether to deploy or not
if $ALLOW_DEPLOY_UNCOMMITED; then
# Alow to deploy with unstaged changes
PRINT_STATUS=true
ALLOW_DEPLOY=true
elif $ALLOW_DEPLOY_UNTRACKED; then
PRINT_STATUS=true
# Required changes to be commited, but allows untracked files
if [ -z "$(git status --untracked-files=no --porcelain)" ]; then
ALLOW_DEPLOY=true
else
NOT_ALLOWED_MSG="There are some local changes, make sure all changes are commited before deploying"
ALLOW_DEPLOY=false
fi
else
# Require changes to be commited, do not allow untracked files
if [ -z "$(git status --porcelain)" ]; then
ALLOW_DEPLOY=true
else
PRINT_STATUS=true
NOT_ALLOWED_MSG="There are some local changes or unstaged files, make sure all changes are commited before deploying"
ALLOW_DEPLOY=false
fi
fi
if $PRINT_STATUS; then
echo -e "${LG}---- Status for Git ----${NC}"
git status
echo
fi
if $ALLOW_DEPLOY; then
echo -e "${LG}---- Are you sure ----${NC}\n"
printf "Continue with deployment? 🚀 [${GREEN}y/n${NC}]"
read -p " " choice
echo
case "$choice" in
y|Y )
# Build
if [[ ! -z $BUILD_COMMAND ]]; then
echo
echo -e "${RED}[deploy:build]${NC} ${GREEN}$BUILD_COMMAND${NC}"
$BUILD_COMMAND
fi
# Server pre deploy
if [[ ! -z $SERVER_PRE_DEPLOY_COMMAND ]]; then
echo -e "${RED}[deploy:server:predeploy]${NC} ${GREEN}$SERVER_PRE_DEPLOY_COMMAND${NC}"
ssh $SERVER $SERVER_PRE_DEPLOY_COMMAND
fi
# Deploy
if [[ ! -z $RSYNC_EXTRA_PARAMS ]]; then
RSYNC_EXTRA_PARAMS=" $RSYNC_EXTRA_PARAMS"
fi
if [[ ! -z $DEPLOY_USER ]]; then
RSYNC_EXTRA_PARAMS="$RSYNC_EXTRA_PARAMS -e \"ssh -l $DEPLOY_USER\""
fi
if [[ ! -z $DEPLOY_IGNORE_FILE ]]; then
RSYNC_EXTRA_PARAMS="$RSYNC_EXTRA_PARAMS --exclude-from='$DEPLOY_IGNORE_FILE'"
fi
DEPLOY_COMMAND="rsync -av --delete-after$RSYNC_EXTRA_PARAMS $DIST_PATH/ $SERVER:$DEPLOY_PATH/"
echo
echo -e "${RED}[deploy:command]${NC} ${GREEN}$DEPLOY_COMMAND${NC}"
eval $DEPLOY_COMMAND
# Server post deploy
if [[ ! -z $SERVER_POST_DEPLOY_COMMAND ]]; then
echo -e "${RED}[deploy:server:postdeploy]${NC} ${GREEN}$SERVER_POST_DEPLOY_COMMAND${NC}"
if [[ ! -z $DEPLOY_USER ]]; then
SSH_EXTRA_PARAMS="$DEPLOY_USER@"
fi
ssh $SSH_EXTRA_PARAMS$SERVER "cd $DEPLOY_PATH && $SERVER_POST_DEPLOY_COMMAND"
fi
# Success
echo
echo -e "${RED}[deploy:success]${NC} ✨ ${GREEN}Bye${NC}"
;;
n|N )
# Do not deploy
echo -e "${RED}[deploy]${NC} 👋 ${GREEN}Ok. Maybe another day${NC}"
exit 10
;;
* )
# Invalid option
echo -e "${RED}[deploy]${NC} 🦐 ${GREEN}Invalid option. Bye${NC}"
exit 20
;;
esac
echo
else
# Cannot deploy
echo -e "${RED}[deploy]${NC} 🙈 ${GREEN}The application cannot be deployed:${NC}"
echo -e " - ${LG}$NOT_ALLOWED_MSG${NC}"
echo
exit 99
fi
@anxolin
Copy link
Author

anxolin commented Oct 13, 2018

Troubleshooting

ssh www-data@example.com -v

You'll need access to the service user by SSH (key in authorized_keys). Also, the permissions of the home and .ssh/authorized_keys config files needs to be correct.

Make sure you can SSH as the service user

touch /home/my_service/.ssh/authorized_keys
curl https://github.com/anxolin.keys >> /home/my_service/.ssh/authorized_keys

Make sure permissions are ok

chmod go-w /home/my_service
chmod 700 /home/my_service/.ssh
chmod 600 /home/my_service/.ssh/authorized_keys
chown -R my_service:my_service /home/my_service/.ssh

Example for nginx: Deploy as www-data

touch /var/www/.ssh/authorized_keys
curl https://github.com/anxolin.keys >> /var/www/.ssh/authorized_keys
chmod go-w /var/www
chmod 700 /var/www/.ssh
chmod 600 /var/www/.ssh/authorized_keys
chown -R www-data:www-data /var/www/.ssh

usermod -a -G my_service foo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment