The BYOP Engine now supports Git-based deployments using Git hooks for continuous deployment. This allows developers to deploy applications by simply pushing to a Git repository.
Initial Setup: When a VM is initialized:
Continuous Deployment: After initial setup, developers can:
Component-Specific Deployment: Different components are handled appropriately:
After a component is deployed, add the remote repository to your Git config:
git remote add production ssh://root@<vm-ip>/opt/byop/repos/<component-id>.git
Push to the remote repository to trigger a deployment:
git push production <branch>
The post-receive hook will automatically:
You can monitor deployment status through:
// createFrontendPostReceiveHook generates a Git hook for frontend components
func createFrontendPostReceiveHook(component models.Component, deployPath string) string {
return fmt.Sprintf(`#!/bin/bash
echo "Deploying frontend component: %s"
# Get the target branch (usually main or master)
TARGET="%s"
while read oldrev newrev ref
do
# Check if the pushed branch is our target branch
if [[ $ref = refs/heads/$TARGET ]];
then
echo "Deploying $TARGET branch..."
# Checkout code to the deployment directory
GIT_WORK_TREE=%s git checkout -f $TARGET
cd %s
# Update environment variables
echo '%s' > %s/.env
# Install dependencies
echo "Installing dependencies..."
npm install
# Build the application
echo "Building application..."
%s
# Notify about completion
echo "Frontend deployment completed successfully"
fi
done
`, component.Name, component.Branch, deployPath, deployPath, component.EnvVariables, deployPath, component.BuildCommand)
}
// createGoPostReceiveHook generates a Git hook for Go components
func createGoPostReceiveHook(component models.Component, deployPath string) string {
return fmt.Sprintf(`#!/bin/bash
echo "Deploying Go component: %s"
# Get the target branch (usually main or master)
TARGET="%s"
while read oldrev newrev ref
do
# Check if the pushed branch is our target branch
if [[ $ref = refs/heads/$TARGET ]];
then
echo "Deploying $TARGET branch..."
# Checkout code to the deployment directory
GIT_WORK_TREE=%s git checkout -f $TARGET
cd %s
# Update environment variables
echo '%s' > %s/.env
# Build the application
echo "Building Go application..."
go build -o app
# Restart the service
echo "Restarting service..."
systemctl restart byop-%s
# Notify about completion
echo "Go deployment completed successfully"
fi
done
`, component.Name, component.Branch, deployPath, deployPath, component.EnvVariables, deployPath, component.ID)
}
// createNodePostReceiveHook generates a Git hook for Node.js components
func createNodePostReceiveHook(component models.Component, deployPath string) string {
return fmt.Sprintf(`#!/bin/bash
echo "Deploying Node.js component: %s"
# Get the target branch (usually main or master)
TARGET="%s"
while read oldrev newrev ref
do
# Check if the pushed branch is our target branch
if [[ $ref = refs/heads/$TARGET ]];
then
echo "Deploying $TARGET branch..."
# Checkout code to the deployment directory
GIT_WORK_TREE=%s git checkout -f $TARGET
cd %s
# Update environment variables
echo '%s' > %s/.env
# Install dependencies
echo "Installing dependencies..."
npm install
# Build the application if there's a build command
if [[ "%s" != "" ]]; then
echo "Building application..."
%s || true
fi
# Restart the PM2 process
echo "Restarting PM2 process..."
pm2 restart byop-%s || pm2 start npm --name "byop-%s" -- start
pm2 save
# Notify about completion
echo "Node.js deployment completed successfully"
fi
done
`, component.Name, component.Branch, deployPath, deployPath, component.EnvVariables, deployPath, component.BuildCommand, component.BuildCommand, component.ID, component.ID)
}
// createPythonPostReceiveHook generates a Git hook for Python components
func createPythonPostReceiveHook(component models.Component, deployPath string) string {
return fmt.Sprintf(`#!/bin/bash
echo "Deploying Python component: %s"
# Get the target branch (usually main or master)
TARGET="%s"
while read oldrev newrev ref
do
# Check if the pushed branch is our target branch
if [[ $ref = refs/heads/$TARGET ]];
then
echo "Deploying $TARGET branch..."
# Checkout code to the deployment directory
GIT_WORK_TREE=%s git checkout -f $TARGET
cd %s
# Update environment variables
echo '%s' > %s/.env
# Update dependencies
echo "Updating Python dependencies..."
source venv/bin/activate
pip install -r requirements.txt
# Restart the service
echo "Restarting service..."
systemctl restart byop-%s
# Notify about completion
echo "Python deployment completed successfully"
fi
done
`, component.Name, component.Branch, deployPath, deployPath, component.EnvVariables, deployPath, component.ID)
}
// createDatabasePostReceiveHook generates a Git hook for database components
func createDatabasePostReceiveHook(component models.Component, deployPath string, dbType string) string {
var configUpdate, restartCmd string
switch dbType {
case "postgresql":
configUpdate = fmt.Sprintf(`
# Apply configuration changes if available
if [ -f %s/postgresql.conf ]; then
cp %s/postgresql.conf /etc/postgresql/*/main/
echo "Updated PostgreSQL configuration"
fi`, deployPath, deployPath)
restartCmd = "systemctl restart postgresql"
case "mariadb", "mysql":
configUpdate = fmt.Sprintf(`
# Apply configuration changes if available
if [ -f %s/my.cnf ]; then
cp %s/my.cnf /etc/mysql/
echo "Updated MariaDB configuration"
fi`, deployPath, deployPath)
restartCmd = "systemctl restart mariadb"
case "mongodb":
configUpdate = fmt.Sprintf(`
# Apply configuration changes if available
if [ -f %s/mongodb.conf ]; then
cp %s/mongodb.conf /etc/mongodb.conf
echo "Updated MongoDB configuration"
fi`, deployPath, deployPath)
restartCmd = "systemctl restart mongodb"
}
return fmt.Sprintf(`#!/bin/bash
echo "Deploying database component: %s"
# Get the target branch (usually main or master)
TARGET="%s"
while read oldrev newrev ref
do
# Check if the pushed branch is our target branch
if [[ $ref = refs/heads/$TARGET ]];
then
echo "Deploying $TARGET branch..."
# Checkout code to the deployment directory
GIT_WORK_TREE=%s git checkout -f $TARGET
cd %s
# Update environment variables
echo '%s' > %s/.env
%s
# Run any database migrations if available
if [ -f %s/migrations/run.sh ]; then
echo "Running database migrations..."
bash %s/migrations/run.sh
fi
# Restart database service
echo "Restarting database service..."
%s
# Notify about completion
echo "Database component deployment completed successfully"
fi
done
`, component.Name, component.Branch, deployPath, deployPath, component.EnvVariables, deployPath, configUpdate, deployPath, deployPath, restartCmd)
}
// createSystemdServiceCommand creates a systemd service file for the component
func createSystemdServiceCommand(component models.Component, deploymentPath string) string {
var execStart string
var workingDir string
workingDir = deploymentPath
switch component.Language {
case "golang":
execStart = fmt.Sprintf("%s/app", deploymentPath)
case "python":
execStart = fmt.Sprintf("%s/venv/bin/python %s/main.py", deploymentPath, deploymentPath)
default:
execStart = component.BuildCommand
}
serviceFile := fmt.Sprintf(`[Unit]
Description=BYOP Component %s
After=network.target
[Service]
ExecStart=%s
WorkingDirectory=%s
Restart=always
User=root
Group=root
Environment=PATH=/usr/bin:/usr/local/bin
EnvironmentFile=%s/.env
[Install]
WantedBy=multi-user.target
`, component.Name, execStart, workingDir, deploymentPath)
return fmt.Sprintf("echo '%s' > /etc/systemd/system/byop-%s.service", serviceFile, component.ID)
}