From a4171330e54bc9aa5c984496e0fb107825eae324 Mon Sep 17 00:00:00 2001 From: Frank John Begornia Date: Tue, 16 Dec 2025 13:18:29 +0800 Subject: [PATCH] Enhance deployment workflows with additional input parameters and setup scripts --- .gitea/workflows/build-push.yml | 9 ++ .gitea/workflows/deploy-dev.yml | 27 ++--- .gitea/workflows/deploy.yml | 18 +-- DEPLOYMENT-SETUP.md | 187 ++++++++++++++++++++++++++++++++ setup-server-env.sh | 153 ++++++++++++++++++++++++++ setup-ssh-keys.sh | 90 +++++++++++++++ 6 files changed, 452 insertions(+), 32 deletions(-) create mode 100644 DEPLOYMENT-SETUP.md create mode 100755 setup-server-env.sh create mode 100755 setup-ssh-keys.sh diff --git a/.gitea/workflows/build-push.yml b/.gitea/workflows/build-push.yml index 06f3dab..88b0bd8 100644 --- a/.gitea/workflows/build-push.yml +++ b/.gitea/workflows/build-push.yml @@ -5,6 +5,15 @@ on: tags: - 'v*' workflow_dispatch: + inputs: + tag: + description: 'Docker image tag (e.g., v1.0.0, latest)' + required: false + default: 'latest' + push_to_registry: + description: 'Push to registry?' + required: false + default: 'true' jobs: build-and-push: diff --git a/.gitea/workflows/deploy-dev.yml b/.gitea/workflows/deploy-dev.yml index f376506..5c6b3eb 100644 --- a/.gitea/workflows/deploy-dev.yml +++ b/.gitea/workflows/deploy-dev.yml @@ -5,6 +5,15 @@ on: branches: - dev workflow_dispatch: + inputs: + skip_health_check: + description: 'Skip health check?' + required: false + default: 'false' + run_migrations: + description: 'Run database migrations?' + required: false + default: 'true' jobs: deploy: @@ -47,17 +56,8 @@ jobs: cp docker-compose.yml \$DEPLOY_DIR/ cd \$DEPLOY_DIR - cat > .env <<'ENVEOF' - APP_ENV=staging - APP_DEBUG=false - APP_URL=https://dev.merchbay.app - DB_HOST=$DEV_DB_HOST - DB_PORT=${DEV_DB_PORT:-3306} - DB_DATABASE=$DEV_DB_DATABASE - DB_USERNAME=$DEV_DB_USERNAME - DB_PASSWORD=$DEV_DB_PASSWORD - DOMAIN=dev.merchbay.app - ENVEOF + # .env file should already exist on server with all secrets + # If it doesn't exist, deployment will fail (this is intentional for security) docker compose down || true docker image prune -f @@ -78,11 +78,6 @@ jobs: DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} DEPLOY_USER: ${{ secrets.DEPLOY_USER }} DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} - DEV_DB_HOST: ${{ secrets.DEV_DB_HOST }} - DEV_DB_PORT: ${{ secrets.DEV_DB_PORT }} - DEV_DB_DATABASE: ${{ secrets.DEV_DB_DATABASE }} - DEV_DB_USERNAME: ${{ secrets.DEV_DB_USERNAME }} - DEV_DB_PASSWORD: ${{ secrets.DEV_DB_PASSWORD }} - name: Health Check shell: sh diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 5d7e58a..dc49d0c 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -48,17 +48,8 @@ jobs: cp docker-compose.yml \$DEPLOY_DIR/ cd \$DEPLOY_DIR - cat > .env <<'ENVEOF' - APP_ENV=production - APP_DEBUG=false - APP_URL=https://merchbay.com - DB_HOST=$PROD_DB_HOST - DB_PORT=${PROD_DB_PORT:-3306} - DB_DATABASE=$PROD_DB_DATABASE - DB_USERNAME=$PROD_DB_USERNAME - DB_PASSWORD=$PROD_DB_PASSWORD - DOMAIN=merchbay.com - ENVEOF + # .env file should already exist on server with all secrets + # If it doesn't exist, deployment will fail (this is intentional for security) docker compose down || true docker image prune -f @@ -79,11 +70,6 @@ jobs: PROD_DEPLOY_SSH_KEY: ${{ secrets.PROD_DEPLOY_SSH_KEY }} PROD_DEPLOY_USER: ${{ secrets.PROD_DEPLOY_USER }} PROD_DEPLOY_HOST: ${{ secrets.PROD_DEPLOY_HOST }} - PROD_DB_HOST: ${{ secrets.PROD_DB_HOST }} - PROD_DB_PORT: ${{ secrets.PROD_DB_PORT }} - PROD_DB_DATABASE: ${{ secrets.PROD_DB_DATABASE }} - PROD_DB_USERNAME: ${{ secrets.PROD_DB_USERNAME }} - PROD_DB_PASSWORD: ${{ secrets.PROD_DB_PASSWORD }} - name: Health Check shell: sh diff --git a/DEPLOYMENT-SETUP.md b/DEPLOYMENT-SETUP.md new file mode 100644 index 0000000..bdd52d7 --- /dev/null +++ b/DEPLOYMENT-SETUP.md @@ -0,0 +1,187 @@ +# Deployment Setup Guide + +This guide will help you set up your deployment infrastructure for the MerchBay Admin application. + +## Quick Start + +We've created two helper scripts to simplify the setup process: + +### 1. Setup SSH Keys (`setup-ssh-keys.sh`) + +Generate and configure SSH keys for Gitea deployment. + +```bash +./setup-ssh-keys.sh +``` + +**What it does:** +- Generates an SSH key pair for deployment +- Shows you the private key to add to Gitea secrets +- Optionally deploys the public key to your server +- Tests the SSH connection + +### 2. Setup Server Environment (`setup-server-env.sh`) + +Configure `.env` files on your deployment servers. + +```bash +./setup-server-env.sh +``` + +**What it does:** +- Guides you through environment configuration +- Creates `.env` file on your server +- Shows you which Gitea secrets are needed +- Supports both production and development environments + +## Manual Setup (Alternative) + +If you prefer manual setup, follow these steps: + +### Step 1: Generate SSH Keys + +```bash +# Generate SSH key +ssh-keygen -t ed25519 -C "gitea-deploy-key" -f ~/.ssh/gitea_deploy_key -N "" + +# View private key (for Gitea) +cat ~/.ssh/gitea_deploy_key + +# View public key (for server) +cat ~/.ssh/gitea_deploy_key.pub +``` + +### Step 2: Add Public Key to Server + +```bash +# SSH to your server +ssh user@your-server + +# Add public key +mkdir -p ~/.ssh +echo "your-public-key-here" >> ~/.ssh/authorized_keys +chmod 600 ~/.ssh/authorized_keys +``` + +### Step 3: Create .env Files on Server + +**Production Server:** +```bash +ssh user@prod-server + +mkdir -p /var/www/merchbay_admin +cat > /var/www/merchbay_admin/.env << 'EOF' +APP_ENV=production +APP_DEBUG=false +APP_URL=https://merchbay.com +DB_HOST=localhost +DB_PORT=3306 +DB_DATABASE=merchbay_prod +DB_USERNAME=merchbay_user +DB_PASSWORD=your_secure_password +DOMAIN=merchbay.com +EOF + +chmod 600 /var/www/merchbay_admin/.env +``` + +**Development Server:** +```bash +ssh user@dev-server + +mkdir -p /var/www/merchbay_admin_dev +cat > /var/www/merchbay_admin_dev/.env << 'EOF' +APP_ENV=staging +APP_DEBUG=false +APP_URL=https://dev.merchbay.app +DB_HOST=localhost +DB_PORT=3306 +DB_DATABASE=merchbay_dev +DB_USERNAME=merchbay_user +DB_PASSWORD=your_dev_password +DOMAIN=dev.merchbay.app +EOF + +chmod 600 /var/www/merchbay_admin_dev/.env +``` + +### Step 4: Add Secrets to Gitea + +Go to your Gitea repository → Settings → Secrets + +**For Production (deploy.yml):** +- `PROD_DEPLOY_SSH_KEY` - Your private SSH key content +- `PROD_DEPLOY_USER` - SSH username (e.g., `root`) +- `PROD_DEPLOY_HOST` - Server IP/hostname + +**For Development (deploy-dev.yml):** +- `DEPLOY_SSH_KEY` - Your private SSH key content +- `DEPLOY_USER` - SSH username (e.g., `root`) +- `DEPLOY_HOST` - Server IP/hostname + +**For Docker Registry (build-push.yml):** +- `DOCKER_REGISTRY_URL` - Your registry URL +- `DOCKER_USERNAME` - Registry username +- `DOCKER_PASSWORD` - Registry password + +## Benefits of This Approach + +✅ **Fewer Secrets** - Only 3 secrets per environment instead of 8+ +✅ **Centralized** - All database/app secrets stay on the server +✅ **Reusable** - Same SSH credentials work for all apps +✅ **Secure** - Secrets never appear in CI/CD logs +✅ **Easy Updates** - Edit `.env` files directly on server + +## Troubleshooting + +### SSH Connection Issues + +```bash +# Test SSH connection +ssh -i ~/.ssh/gitea_deploy_key user@server + +# Check SSH key permissions +chmod 600 ~/.ssh/gitea_deploy_key +chmod 644 ~/.ssh/gitea_deploy_key.pub +``` + +### Workflow Fails with "Could not resolve hostname" + +- Make sure all secrets are added to Gitea +- Verify `DEPLOY_HOST` / `PROD_DEPLOY_HOST` is correct +- Check `DEPLOY_USER` / `PROD_DEPLOY_USER` is set + +### .env File Not Found + +- Run `./setup-server-env.sh` to create it +- Or manually create `.env` file on server at: + - Production: `/var/www/merchbay_admin/.env` + - Development: `/var/www/merchbay_admin_dev/.env` + +## Multiple Applications + +To deploy multiple applications using the same setup: + +1. **Use the same SSH keys** - No need to generate new ones +2. **Create separate .env files** - One per app on the server +3. **Only 3 Gitea secrets total** - Reuse across all apps! + +Example for another app: +```bash +# Same SSH key works! +# Just create new .env file +ssh user@server +mkdir -p /var/www/another_app +cat > /var/www/another_app/.env << 'EOF' +# App-specific configuration +EOF +``` + +## Security Best Practices + +- ✅ Never commit `.env` files to git +- ✅ Keep private keys secure +- ✅ Use strong database passwords +- ✅ Restrict SSH key permissions (600) +- ✅ Use different passwords for prod/dev +- ✅ Regularly rotate credentials diff --git a/setup-server-env.sh b/setup-server-env.sh new file mode 100755 index 0000000..0196fca --- /dev/null +++ b/setup-server-env.sh @@ -0,0 +1,153 @@ +#!/bin/bash + +# Server Environment Setup Script +# This script helps you set up .env files on your deployment servers + +set -e + +echo "================================================" +echo "Server Environment Setup for MerchBay Admin" +echo "================================================" +echo "" + +# Color codes for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Function to prompt for input with default value +prompt_input() { + local prompt="$1" + local default="$2" + local value + + if [ -n "$default" ]; then + read -p "$prompt [$default]: " value + echo "${value:-$default}" + else + read -p "$prompt: " value + echo "$value" + fi +} + +# Function to prompt for password (hidden input) +prompt_password() { + local prompt="$1" + local value + + read -s -p "$prompt: " value + echo "" + echo "$value" +} + +# Choose environment +echo "Which environment are you setting up?" +echo "1) Production" +echo "2) Development" +read -p "Enter choice [1-2]: " env_choice + +case $env_choice in + 1) + ENV_TYPE="production" + DEPLOY_DIR="/var/www/merchbay_admin" + DEFAULT_DOMAIN="merchbay.com" + DEFAULT_APP_URL="https://merchbay.com" + DEFAULT_APP_ENV="production" + DEFAULT_DB_NAME="merchbay_prod" + ;; + 2) + ENV_TYPE="development" + DEPLOY_DIR="/var/www/merchbay_admin_dev" + DEFAULT_DOMAIN="dev.merchbay.app" + DEFAULT_APP_URL="https://dev.merchbay.app" + DEFAULT_APP_ENV="staging" + DEFAULT_DB_NAME="merchbay_dev" + ;; + *) + echo -e "${RED}Invalid choice${NC}" + exit 1 + ;; +esac + +echo -e "\n${GREEN}Setting up $ENV_TYPE environment${NC}\n" + +# Collect information +echo "=== Application Settings ===" +APP_ENV=$(prompt_input "APP_ENV" "$DEFAULT_APP_ENV") +APP_DEBUG=$(prompt_input "APP_DEBUG (true/false)" "false") +APP_URL=$(prompt_input "APP_URL" "$DEFAULT_APP_URL") +DOMAIN=$(prompt_input "DOMAIN" "$DEFAULT_DOMAIN") + +echo -e "\n=== Database Settings ===" +DB_HOST=$(prompt_input "DB_HOST" "localhost") +DB_PORT=$(prompt_input "DB_PORT" "3306") +DB_DATABASE=$(prompt_input "DB_DATABASE" "$DEFAULT_DB_NAME") +DB_USERNAME=$(prompt_input "DB_USERNAME" "merchbay_user") +DB_PASSWORD=$(prompt_password "DB_PASSWORD") + +echo -e "\n=== Server Connection ===" +SERVER_USER=$(prompt_input "SSH Username" "root") +SERVER_HOST=$(prompt_input "Server IP/Hostname" "") + +if [ -z "$SERVER_HOST" ]; then + echo -e "${RED}Error: Server hostname is required${NC}" + exit 1 +fi + +# Generate .env content +ENV_CONTENT="APP_ENV=$APP_ENV +APP_DEBUG=$APP_DEBUG +APP_URL=$APP_URL +DB_HOST=$DB_HOST +DB_PORT=$DB_PORT +DB_DATABASE=$DB_DATABASE +DB_USERNAME=$DB_USERNAME +DB_PASSWORD=$DB_PASSWORD +DOMAIN=$DOMAIN" + +# Show summary +echo -e "\n${YELLOW}=== Configuration Summary ===${NC}" +echo "Environment: $ENV_TYPE" +echo "Deploy Directory: $DEPLOY_DIR" +echo "Server: $SERVER_USER@$SERVER_HOST" +echo "Domain: $DOMAIN" +echo "Database: $DB_DATABASE" +echo "" + +# Ask for confirmation +read -p "Deploy this configuration to the server? (y/n): " confirm + +if [ "$confirm" != "y" ]; then + echo "Aborted." + exit 0 +fi + +# Deploy to server +echo -e "\n${GREEN}Deploying configuration to server...${NC}" + +# Create deployment directory and .env file +ssh "$SERVER_USER@$SERVER_HOST" "mkdir -p $DEPLOY_DIR" + +# Upload .env file +echo "$ENV_CONTENT" | ssh "$SERVER_USER@$SERVER_HOST" "cat > $DEPLOY_DIR/.env && chmod 600 $DEPLOY_DIR/.env" + +echo -e "\n${GREEN}✓ Configuration deployed successfully!${NC}" +echo -e "\nThe .env file has been created at: ${YELLOW}$DEPLOY_DIR/.env${NC}" +echo "" + +# Display Gitea secrets needed +echo -e "${YELLOW}=== Gitea Secrets Required ===${NC}" +if [ "$ENV_TYPE" = "production" ]; then + echo "Add these secrets to your Gitea repository:" + echo " • PROD_DEPLOY_SSH_KEY: Your SSH private key" + echo " • PROD_DEPLOY_USER: $SERVER_USER" + echo " • PROD_DEPLOY_HOST: $SERVER_HOST" +else + echo "Add these secrets to your Gitea repository:" + echo " • DEPLOY_SSH_KEY: Your SSH private key" + echo " • DEPLOY_USER: $SERVER_USER" + echo " • DEPLOY_HOST: $SERVER_HOST" +fi + +echo -e "\n${GREEN}Setup complete!${NC}" diff --git a/setup-ssh-keys.sh b/setup-ssh-keys.sh new file mode 100755 index 0000000..d1ccaa7 --- /dev/null +++ b/setup-ssh-keys.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +# SSH Key Generation Script for Gitea Deployment +# This script generates SSH keys and helps you set them up + +set -e + +echo "================================================" +echo "SSH Key Setup for Gitea Deployment" +echo "================================================" +echo "" + +# Color codes +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +SSH_KEY_PATH="$HOME/.ssh/gitea_deploy_key" + +# Check if key already exists +if [ -f "$SSH_KEY_PATH" ]; then + echo -e "${YELLOW}Warning: SSH key already exists at $SSH_KEY_PATH${NC}" + read -p "Do you want to overwrite it? (y/n): " overwrite + if [ "$overwrite" != "y" ]; then + echo "Using existing key." + else + rm -f "$SSH_KEY_PATH" "$SSH_KEY_PATH.pub" + echo "Generating new SSH key..." + ssh-keygen -t ed25519 -C "gitea-deploy-key" -f "$SSH_KEY_PATH" -N "" + fi +else + echo "Generating new SSH key..." + ssh-keygen -t ed25519 -C "gitea-deploy-key" -f "$SSH_KEY_PATH" -N "" +fi + +echo -e "\n${GREEN}✓ SSH key generated successfully!${NC}\n" + +# Display private key for Gitea +echo -e "${YELLOW}=== PRIVATE KEY (for Gitea Secrets) ===${NC}" +echo -e "${BLUE}Copy this ENTIRE content for your Gitea secret:${NC}\n" +cat "$SSH_KEY_PATH" +echo "" + +# Display public key for server +echo -e "\n${YELLOW}=== PUBLIC KEY (for Server) ===${NC}" +echo -e "${BLUE}Copy this content to add to your server's ~/.ssh/authorized_keys:${NC}\n" +cat "$SSH_KEY_PATH.pub" +echo "" + +# Ask if user wants to deploy to server now +echo -e "\n${YELLOW}=== Deploy Public Key to Server ===${NC}" +read -p "Do you want to add the public key to a server now? (y/n): " deploy_now + +if [ "$deploy_now" = "y" ]; then + read -p "Enter SSH username: " ssh_user + read -p "Enter server IP/hostname: " ssh_host + + echo -e "\nAdding public key to $ssh_user@$ssh_host..." + + # Copy public key to server + ssh-copy-id -i "$SSH_KEY_PATH.pub" "$ssh_user@$ssh_host" 2>/dev/null || \ + ssh "$ssh_user@$ssh_host" "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys" < "$SSH_KEY_PATH.pub" + + echo -e "\n${GREEN}✓ Public key added to server!${NC}" + + # Test connection + echo -e "\nTesting SSH connection..." + if ssh -i "$SSH_KEY_PATH" -o StrictHostKeyChecking=no "$ssh_user@$ssh_host" "echo 'Connection successful!'" 2>/dev/null; then + echo -e "${GREEN}✓ SSH connection test successful!${NC}" + else + echo -e "${YELLOW}⚠ SSH connection test failed. Please check your server configuration.${NC}" + fi +fi + +# Summary +echo -e "\n${GREEN}=== Setup Complete! ===${NC}" +echo -e "\n${YELLOW}Next Steps:${NC}" +echo "1. Copy the PRIVATE KEY above and add it to Gitea Secrets as:" +echo " • DEPLOY_SSH_KEY (for dev)" +echo " • PROD_DEPLOY_SSH_KEY (for production)" +echo "" +echo "2. If you didn't deploy the public key yet, manually add it to your server:" +echo " ssh user@server" +echo " echo '$(cat "$SSH_KEY_PATH.pub")' >> ~/.ssh/authorized_keys" +echo "" +echo "3. The key files are saved at:" +echo " Private: $SSH_KEY_PATH" +echo " Public: $SSH_KEY_PATH.pub" +echo ""