primate icon indicating copy to clipboard operation
primate copied to clipboard

add `@primate/deploy`

Open terrablue opened this issue 1 year ago • 11 comments

Different providers

  • Repopack (default)
  • Cloudflare workers
  • Cloudflare pages
  • Amazon
  • Google
  • Netlify
  • Vercel
  • Deno deploy
  • ?

terrablue avatar Jun 08 '24 14:06 terrablue

just a standalone server would be good too. no need to only support paid cloud offerings.

ralyodio avatar Jul 12 '24 15:07 ralyodio

@ralyodio how would such a deployment work?

terrablue avatar Jul 12 '24 16:07 terrablue

Sync with a ssh

ralyodio avatar Jul 12 '24 16:07 ralyodio

// deploy.sh

#!/bin/bash

. $HOME/.bashrc
. .env
. .env.local

args=(-azvP --delete --exclude=node_modules --exclude=.idea --exclude=data --exclude=static/_posts)
hosts=($HOST_DOMAIN) # tornado lightning thunder tundra jefferson
dry=() #add --dry-run to enable testing
user=$HOST_USER
name=$HOST_PATH
project=$HOST_PROJECT


if [ -z "$name" ] || [ -z "$project" ]; then
    echo "One or both directories do not exist"
    exit 1
fi

result=$(ssh $user@$HOST_DOMAIN "[ -d ~/www/$name ] && [ -d ~/www/$name/$project ] && echo 'exists' || echo 'does not exist'")

if [ "$result" == "exists" ]; then
    # If both directories exist, run your command here
    echo "Both directories exist"

    for host in "${hosts[@]}"
    do
      echo ""
      date
      echo "---------------------"
      echo "syncing ${host}"
      echo "---------------------"
      rsync ${dry[@]} ${args[@]} ./ ${user}@${host}:www/${name}/${project}
      ssh -t ${user}@${host} \$HOME/www/${name}/${project}/bin/post-deploy.sh
    done

else
    echo "One or both directories do not exist"
fi

version=$(jq -r .version package.json)
say "$HOST_PROJECT is live!"
exit

//post-deploy.sh

#!/bin/bash

cd "$(dirname "$0")/.."
. $HOME/.bashrc
. .env
. .env.local

host=$HOST_DOMAIN
name=$HOST_PATH
project=$HOST_PROJECT

echo "current name: $name"

if [ -d "$HOME/www/${name}/${project}" ]; then
    # If both directories exist, run your command here
    echo "Both directories exist"
    cd $HOME/www/${name}/${project}
    nvm install v20
    node -v
    pnpm -v
    rm -f package-lock.json
    rm -f pnpm-lock.yaml
    rm -rf ./node_modules
		npm i -g pnpm
    #pnpm cache clean --force
    #pnpm cache verify
    pnpm i
		# curl --proto '=https' --tlsv1.2 -sSf https://install.surrealdb.com | sh -s -- --nightl
    sudo systemctl stop ${META_SERVICE}
    sudo systemctl stop surrealdb
    # surreal upgrade --nightly
    surreal upgrade
    sudo /etc/init.d/nginx reload
    sudo systemctl daemon-reload
    sudo systemctl start ${META_SERVICE}
    sudo systemctl start surrealdb
    # run migrations
    ./migrations/users.sh
    # ./migrations/comments.sh
    ./migrations/links.sh
    ./migrations/apikeys.sh
    ./migrations/products.sh
    # ./migrations/send_email.sh
    ./migrations/nostrusers.sh
    ./migrations/affiliates.sh
    ./migrations/appointments.sh
    ./migrations/payouts.sh
    ./migrations/waitlist.sh

  else
    echo "One or both directories do not exist"
fi



ralyodio avatar Jul 14 '24 14:07 ralyodio

in my opinion if you gave us the ability to write our own deploy script and post deploy scripts (which runs on the server) that would be good enough for custom deploys.

ralyodio avatar Jul 14 '24 14:07 ralyodio

@ralyodio noted, I think that's the best way forward

terrablue avatar Jul 14 '24 14:07 terrablue

maybe a ./bin/setup.sh too which would be ran once. I manually setup certs, symlink conf files and shit. I should script that.

ralyodio avatar Jul 14 '24 15:07 ralyodio

Here's an example setup.sh script:

#!/bin/bash

. $HOME/.bashrc
. .env
. .env.local

# Check if the user provided the domain name and project name
if [ -z "$1" ] || [ -z "$2" ]; then
  echo "Usage: $0 <domain_name> <project_name>"
  exit 1
fi

# Variables
DOMAIN_NAME="$1"
PROJECT_NAME="$2"
TARGET_PATH="~/www/$DOMAIN_NAME/$PROJECT_NAME"
NGINX_CONF="$TARGET_PATH/etc/$DOMAIN_NAME.conf"
SYSTEMD_SERVICE="$TARGET_PATH/etc/$PROJECT_NAME.service"
NGINX_SYMLINK="/etc/nginx/sites-available/$DOMAIN_NAME.com.conf"
SYSTEMD_SYMLINK="/etc/systemd/system/$PROJECT_NAME.service"
user=$HOST_USER

# Create the directory if it does not exist
ssh $user@$HOST_DOMAIN "mkdir -p $TARGET_PATH"

# Deploy the code
rsync -azvP --delete --exclude=node_modules --exclude=.idea --exclude=data --exclude=static/_posts ./ ${user}@${HOST_DOMAIN}:${TARGET_PATH}

# Symlink the Nginx configuration
ssh $user@$HOST_DOMAIN "if [ -f $NGINX_CONF ]; then sudo ln -sf $NGINX_CONF $NGINX_SYMLINK && sudo ln -sf $NGINX_SYMLINK /etc/nginx/sites-enabled/; else echo 'Nginx configuration file not found at $NGINX_CONF'; exit 1; fi"

# Symlink the systemd service
ssh $user@$HOST_DOMAIN "if [ -f $SYSTEMD_SERVICE ]; then sudo ln -sf $SYSTEMD_SERVICE $SYSTEMD_SYMLINK; else echo 'Systemd service file not found at $SYSTEMD_SERVICE'; exit 1; fi"

# Generate Let's Encrypt certificates for the domain
ssh $user@$HOST_DOMAIN "sudo certbot certonly --nginx -d $DOMAIN_NAME"
ssh $user@$HOST_DOMAIN "sudo certbot certonly --nginx -d www.${DOMAIN_NAME}"

# Enable and start the systemd service
ssh $user@$HOST_DOMAIN "sudo systemctl enable $(basename $SYSTEMD_SERVICE) --now"

ssh -t ${user}@${HOST_DOMAIN} ${TARGET_PATH}/bin/post-deploy.sh

echo "Setup completed successfully!"

version=$(jq -r .version package.json)
say "$HOST_PROJECT is setup!"
exit

ralyodio avatar Jul 14 '24 15:07 ralyodio

it could be smarter and write out .env.local based on questions you answer.

ralyodio avatar Jul 14 '24 15:07 ralyodio

I also decided to support multiple environments. basically you just symlink .env.<envname> to .env.local and add those custom files to .gitignore

this makes it easiser for staging.example.com vs. example.com which a lot of clients want

ralyodio avatar Jul 14 '24 17:07 ralyodio