Skip to content

Instantly share code, notes, and snippets.

@ibraheem-ghazi
Created August 15, 2024 10:31
Show Gist options
  • Save ibraheem-ghazi/a31d00fefec28abf70e5a1323004848f to your computer and use it in GitHub Desktop.
Save ibraheem-ghazi/a31d00fefec28abf70e5a1323004848f to your computer and use it in GitHub Desktop.
Setup a Bare Git repo, for auto deployment code to Ubuntu server, a Bare repo created with a new username at /home/$USERNAME/git/$REPO_NAME, once you push to it, the code will be copied to the target_dir. Not Fully tested for common cases, but its working. If you used this script, read it, and modify it as needed.
#!/bin/bash
# If you keep getting permission denied or something do the following:
# - sudo nano /etc/ssh/sshd_config
# - Uncomment and ensure the following lines are present:
# PubkeyAuthentication yes
# AuthorizedKeysFile .ssh/authorized_keys
# - sudo systemctl restart ssh.service
# To Remove (reverse) the user/repo setup
# - USERNAME=username
# - REPO_NAME=repo
# - sudo -u $USERNAME git config --global --unset safe.directory /home/$USERNAME/git/$REPO_NAME.git
# - sudo deluser --remove-home $USERNAME
# - sudo nano /etc/ssh/sshd_config
# - remove the lines related to Match User $USERNAME (with PermitRootLogin and PasswordAuthentication)
# - sudo systemctl restart ssh
# Usage: ./setup_deploy.sh <username> <repo_name> <target_dir> <branch>
# Check if the correct number of arguments is provided
if [ "$#" -ne 4 ]; then
echo "Usage: $0 <username> <repo_name> <target_dir> <branch>"
exit 1
fi
# Parameters
USERNAME=$1
REPO_NAME=$2
TARGET_DIR=$3
BRANCH=$4
REPO_DIR="/home/$USERNAME/git/$REPO_NAME.git"
# Step 1: Check if the user exists, create if not
if id "$USERNAME" &>/dev/null; then
echo "User $USERNAME already exists."
else
sudo adduser --disabled-password --gecos "" $USERNAME
echo "User $USERNAME created."
fi
# Ensure the home directory and the git directory are set up with correct permissions
sudo mkdir -p /home/$USERNAME/git
sudo chown -R $USERNAME:$USERNAME /home/$USERNAME
sudo chmod -R 755 /home/$USERNAME
# Step 2: Set up SSH keys for the user if not already set up
if [ ! -f /home/$USERNAME/.ssh/id_rsa ]; then
sudo -u $USERNAME ssh-keygen -t rsa -b 4096 -N "" -f /home/$USERNAME/.ssh/id_rsa
sudo -u $USERNAME sh -c "cat /home/$USERNAME/.ssh/id_rsa.pub | tee -a /home/$USERNAME/.ssh/authorized_keys"
sudo chmod 700 /home/$USERNAME/.ssh
sudo chmod 600 /home/$USERNAME/.ssh/authorized_keys
echo "SSH key generated for $USERNAME."
else
echo "SSH key already exists for $USERNAME. Skipping key generation."
fi
# Step 3: Set up the bare repository
if [ ! -d $REPO_DIR ]; then
sudo mkdir -p $REPO_DIR
sudo chown -R $USERNAME:$USERNAME $REPO_DIR
cd $REPO_DIR
sudo -u $USERNAME git init --bare
echo "Bare repository $REPO_NAME created at $REPO_DIR."
else
echo "Repository $REPO_NAME already exists at $REPO_DIR."
fi
# Step 4: Create the post-receive hook
HOOK_PATH="$REPO_DIR/hooks/post-receive"
sudo -u $USERNAME bash -c "cat > $HOOK_PATH" <<EOF
#!/bin/bash
# Read the branch name from the push
while read oldrev newrev ref
do
# Extract the branch name from the ref
BRANCH=\$(echo \$ref | cut -d/ -f3)
done
# Checkout the branch that was pushed
GIT_WORK_TREE=$TARGET_DIR git checkout -f \$BRANCH
# Navigate to the target directory and run additional commands
cd $TARGET_DIR/system
# Run composer install with specified options
sudo composer install --ignore-platform-req=ext-http --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --optimize-autoloader
# Add any additional commands here, e.g., npm install, etc.
EOF
sudo chmod +x $HOOK_PATH
echo "Post-receive hook created at $HOOK_PATH."
# Step 5: Configure the target directory permissions
sudo mkdir -p $TARGET_DIR
sudo chown -R $USERNAME:$USERNAME $TARGET_DIR
sudo chmod -R 755 $TARGET_DIR
echo "Target directory $TARGET_DIR configured with correct permissions."
# Step 6: Mark the repo as safe for the user
sudo -u $USERNAME git config --global --add safe.directory $REPO_DIR
echo "Repository marked as safe for $USERNAME."
# Step 7: Secure SSH access (if not already configured)
SSH_CONFIG_MATCH="Match User $USERNAME"
if grep -q "$SSH_CONFIG_MATCH" /etc/ssh/sshd_config; then
echo "SSH configuration for $USERNAME already exists."
else
sudo bash -c "cat >> /etc/ssh/sshd_config" <<EOF
Match User $USERNAME
PermitRootLogin no
PasswordAuthentication no
EOF
echo "SSH configuration for $USERNAME added."
fi
# Step 8: Output the SSH private key for the user
if [ -f /home/$USERNAME/.ssh/id_rsa ]; then
sudo ssh-keygen -p -m PEM -f /home/$USERNAME/.ssh/id_rsa -N ""
else
echo "SSH private key not found. Something went wrong."
exit 1
fi
# Clear the screen
clear
# Show the RSA PEM key content
echo "=================================================="
echo "Copy the following RSA PEM key content and save it as 'your_key.pem':"
echo "=================================================="
sudo cat /home/$USERNAME/.ssh/id_rsa
echo "=================================================="
# Show the SSH connection command
SERVER=$(hostname -i)
echo
echo "Connect to SSH via command:"
echo "ssh -i your_key.pem $USERNAME@$SERVER"
# Show the Git repository setup commands
echo
echo "Add to your local machine repo origin by running the following commands:"
echo "git remote add production \"ssh://$USERNAME@$SERVER:$REPO_DIR\""
echo "#git config remote.production.url \"ssh://$USERNAME@$SERVER:$REPO_DIR\""
echo "git config remote.production.fetch \"+refs/heads/*:refs/remotes/production/*\""
echo "git config core.sshCommand \"ssh -i your_key.pem\""
echo "git config --global --add safe.directory $REPO_DIR"
echo
echo "From your local machine repo, you can push to server via:"
echo "git push production $BRANCH"
# Step 9: Restart SSHD service as the final step
echo
echo "Restarting SSH service to apply changes..."
sudo systemctl restart ssh
echo "SSH service restarted. You might be disconnected if you're using SSH."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment