Last active
February 14, 2025 09:55
-
-
Save d10r/523c315db414b128a085223ddd3f840b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Script for deploying nodejs applications to the SF cloud ™. | |
# Requirements: | |
# - ssh access | |
# - application name in package.json or provided as env var APP_NAME | |
# - git url in package.json or provided as env var GIT_URL | |
# - package-lock.json | |
# - npm scripts "build" and "start" | |
# Optional: | |
# - .nvmrc file signalling the wanted node version | |
# - .env.prod (or file specified in env var ENV_FILE) with env vars to be used in production | |
# - custom install command(s) in env var INSTALL_CMD (default: npm ci && npm run build) | |
# | |
# When running for an existing app, it will: | |
# - update the .env file based on the local .env.prod | |
# - update the repo | |
# - update dependencies (npm ci) | |
# - build the app (npm run build) | |
# - restart the service | |
# | |
# When running for a new app, it will additionally first: | |
# - clone the repo | |
# - create a user systemd unit | |
set -eu | |
[email protected] | |
APP_NAME=${APP_NAME:-$(cat package.json | jq -r '.name')} | |
GIT_URL=${GIT_URL:-$(cat package.json | jq -r '.repository.url')} | |
ENV_FILE=${ENV_FILE:-.env.prod} | |
INSTALL_CMD=${INSTALL_CMD:-"node --version && npm ci && npm run build"} | |
SERVICE_FILE=$APP_NAME.service | |
echo "APP_NAME: $APP_NAME" | |
if [ -z "$APP_NAME" ] || [[ "$APP_NAME" =~ ' ' ]]; then | |
echo "Invalid app name" | |
exit 1 | |
fi | |
echo "GIT_URL: $GIT_URL" | |
if [ -z "$GIT_URL" ]; then | |
echo "Invalid git url" | |
exit 1 | |
fi | |
echo "ENV_FILE: $ENV_FILE" | |
if [ ! -f "$ENV_FILE" ]; then | |
echo "env file not found" | |
exit 1 | |
fi | |
echo "INSTALL_CMD: $INSTALL_CMD" | |
# if there's a local env file (as specified), copy it to the server with the name .env.$APP_NAME | |
if [ -f "$ENV_FILE" ]; then | |
echo "Using $ENV_FILE for the production environment" | |
scp $ENV_FILE $SSH_HOST:~/.env.$APP_NAME | |
fi | |
# if any of the commands fails, don't continue | |
ssh -q -T $SSH_HOST "/bin/bash --noprofile --norc" <<EOF | |
set -e | |
set -u | |
. ./.profile | |
. .nvm/nvm.sh | |
# (conditional) first time setup | |
# if directory with app name doesn't exist, clone the repo | |
if [ ! -d "$APP_NAME" ]; then | |
echo "Cloning repo" | |
git clone $GIT_URL $APP_NAME | |
fi | |
# if service file doesn't exist, copy it from the template | |
if [ ! -f "services/$SERVICE_FILE" ]; then | |
echo "Copying service file" | |
cp template.service services/$SERVICE_FILE | |
sed -i "s|Description=|Description=$APP_NAME|" services/$SERVICE_FILE | |
sed -i "s|WorkingDirectory=|WorkingDirectory=/home/dapps/$APP_NAME|" services/$SERVICE_FILE | |
systemctl --user daemon-reload | |
sleep 1 | |
systemctl --user enable $SERVICE_FILE | |
fi | |
# regular update | |
# if there's an .env.$APP_NAME, use it | |
if [ -f ".env.$APP_NAME" ]; then | |
echo "Using .env.$APP_NAME for the production environment" | |
cp .env.$APP_NAME $APP_NAME/.env | |
rm .env.$APP_NAME | |
else | |
echo "No .env.$APP_NAME found" | |
fi | |
cd $APP_NAME | |
git pull | |
if [ -f .nvmrc ]; then | |
nvm use | |
else | |
echo "no .nvmrc provided, using default node version" | |
fi | |
$INSTALL_CMD | |
cd | |
systemctl --user restart $SERVICE_FILE | |
systemctl --user -n 50 status $SERVICE_FILE | |
EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment