Remove outdated deployment and configuration files; consolidate deployment instructions into README and update project structure.
All checks were successful
Deploy Development / deploy (push) Successful in 1m20s
All checks were successful
Deploy Development / deploy (push) Successful in 1m20s
This commit is contained in:
@@ -1,405 +0,0 @@
|
||||
# Deployment with Portainer and Traefik
|
||||
|
||||
This guide covers deploying MerchBay Admin using your existing Portainer and Traefik setup.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- ✅ Gitea self-hosted with Gitea runners configured
|
||||
- ✅ Portainer installed and accessible
|
||||
- ✅ Traefik reverse proxy running with:
|
||||
- `web` entrypoint (port 80)
|
||||
- `websecure` entrypoint (port 443)
|
||||
- Let's Encrypt certificate resolver named `letsencrypt`
|
||||
- External network named `traefik`
|
||||
|
||||
## Deployment Methods
|
||||
|
||||
### Method 1: Portainer Stack Deployment (Recommended)
|
||||
|
||||
#### Step 1: Prepare the Image
|
||||
|
||||
Build the Docker image via Gitea Actions or manually:
|
||||
|
||||
```bash
|
||||
# Using Gitea Actions (will build automatically on push)
|
||||
git push origin main
|
||||
|
||||
# OR build manually
|
||||
docker build -t merchbay_admin:latest .
|
||||
```
|
||||
|
||||
#### Step 2: Deploy in Portainer
|
||||
|
||||
1. **Access Portainer** → `Stacks` → `Add stack`
|
||||
|
||||
2. **Stack Configuration:**
|
||||
- Name: `merchbay-admin`
|
||||
- Build method: `Web editor`
|
||||
|
||||
3. **Paste the content from `docker-compose.portainer.yml`** and update:
|
||||
- `APP_URL`: Your domain (e.g., `https://merchbay-admin.yourdomain.com`)
|
||||
- `DB_HOST`: Your MySQL host
|
||||
- `DB_DATABASE`: Database name
|
||||
- `DB_USERNAME`: Database username
|
||||
- `DB_PASSWORD`: Database password
|
||||
- Traefik Host rule: Replace `merchbay-admin.yourdomain.com` with your actual domain
|
||||
|
||||
4. **Deploy the stack**
|
||||
|
||||
5. **Run Initial Setup:**
|
||||
- Go to `Containers` → Find `merchbay_admin_app`
|
||||
- Click `Console` → Connect with `/bin/bash`
|
||||
- Run:
|
||||
```bash
|
||||
php artisan migrate --force
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
```
|
||||
|
||||
### Method 2: Gitea Actions CI/CD (Automated)
|
||||
|
||||
#### Step 1: Configure Gitea Secrets
|
||||
|
||||
In your Gitea repository → `Settings` → `Secrets` → `Actions`, add:
|
||||
|
||||
| Secret Name | Value | Description |
|
||||
|------------|-------|-------------|
|
||||
| `DEPLOY_HOST` | `192.168.1.100` | Your server IP/hostname |
|
||||
| `DEPLOY_USER` | `deploy` | SSH username |
|
||||
| `DEPLOY_SSH_KEY` | `-----BEGIN RSA...` | Private SSH key |
|
||||
| `DEPLOY_PORT` | `22` | SSH port (optional) |
|
||||
| `DEPLOY_DIR` | `/var/www/merchbay_admin` | Deployment directory |
|
||||
| `DOMAIN` | `merchbay-admin.yourdomain.com` | Your domain for Traefik |
|
||||
|
||||
#### Step 2: Prepare Deployment Server
|
||||
|
||||
```bash
|
||||
# SSH into your server
|
||||
ssh deploy@your-server
|
||||
|
||||
# Create deployment directory
|
||||
sudo mkdir -p /var/www/merchbay_admin
|
||||
sudo chown $USER:$USER /var/www/merchbay_admin
|
||||
cd /var/www/merchbay_admin
|
||||
|
||||
# Create .env file
|
||||
nano .env
|
||||
```
|
||||
|
||||
Add to `.env`:
|
||||
```env
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_URL=https://merchbay-admin.yourdomain.com
|
||||
DB_HOST=your-mysql-host
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=merchbay_admin
|
||||
DB_USERNAME=your-mysql-user
|
||||
DB_PASSWORD=your-mysql-password
|
||||
DOMAIN=merchbay-admin.yourdomain.com
|
||||
```
|
||||
|
||||
#### Step 3: Ensure Traefik Network Exists
|
||||
|
||||
```bash
|
||||
docker network inspect traefik >/dev/null 2>&1 || docker network create traefik
|
||||
```
|
||||
|
||||
#### Step 4: Deploy
|
||||
|
||||
Simply push to your main branch:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Deploy application"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
Gitea Actions will automatically:
|
||||
1. Build the Docker image
|
||||
2. Transfer to your server
|
||||
3. Deploy with docker-compose
|
||||
4. Connect to Traefik network
|
||||
5. Run migrations
|
||||
6. Cache configurations
|
||||
|
||||
### Method 3: Manual Deployment with Script
|
||||
|
||||
```bash
|
||||
# On your server
|
||||
cd /var/www/merchbay_admin
|
||||
|
||||
# Pull latest code
|
||||
git pull origin main
|
||||
|
||||
# Run deployment script
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
## Traefik Configuration
|
||||
|
||||
### Verify Traefik Setup
|
||||
|
||||
Ensure your Traefik configuration includes:
|
||||
|
||||
```yaml
|
||||
# traefik.yml or docker-compose.yml
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
websecure:
|
||||
address: ":443"
|
||||
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
email: your-email@example.com
|
||||
storage: /letsencrypt/acme.json
|
||||
httpChallenge:
|
||||
entryPoint: web
|
||||
```
|
||||
|
||||
### External Network
|
||||
|
||||
Ensure Traefik network exists and is external:
|
||||
|
||||
```bash
|
||||
# Create network if it doesn't exist
|
||||
docker network create traefik
|
||||
|
||||
# Verify
|
||||
docker network inspect traefik
|
||||
```
|
||||
|
||||
## DNS Configuration
|
||||
|
||||
Point your domain to your server:
|
||||
|
||||
```
|
||||
Type: A Record
|
||||
Name: merchbay-admin (or @ for root domain)
|
||||
Value: YOUR_SERVER_IP
|
||||
TTL: 3600
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
### 1. Check Container Status
|
||||
|
||||
**Via Portainer:**
|
||||
- Navigate to `Containers`
|
||||
- Verify `merchbay_admin_app` is running
|
||||
|
||||
**Via CLI:**
|
||||
```bash
|
||||
docker ps | grep merchbay_admin
|
||||
```
|
||||
|
||||
### 2. Check Traefik Dashboard
|
||||
|
||||
If you have Traefik dashboard enabled:
|
||||
- Look for `merchbay-admin@docker` router
|
||||
- Verify it's connected to the correct service
|
||||
|
||||
### 3. Test Application
|
||||
|
||||
```bash
|
||||
# Test HTTPS
|
||||
curl -I https://merchbay-admin.yourdomain.com
|
||||
|
||||
# Should return: HTTP/2 200
|
||||
```
|
||||
|
||||
### 4. Check Logs
|
||||
|
||||
**Via Portainer:**
|
||||
- `Containers` → `merchbay_admin_app` → `Logs`
|
||||
|
||||
**Via CLI:**
|
||||
```bash
|
||||
docker logs merchbay_admin_app -f
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue: Container not accessible via domain
|
||||
|
||||
**Check Traefik labels:**
|
||||
```bash
|
||||
docker inspect merchbay_admin_app | grep -A 20 Labels
|
||||
```
|
||||
|
||||
**Verify network connection:**
|
||||
```bash
|
||||
docker network inspect traefik | grep merchbay_admin
|
||||
```
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Reconnect to Traefik network
|
||||
docker network connect traefik merchbay_admin_app
|
||||
```
|
||||
|
||||
### Issue: SSL certificate not generating
|
||||
|
||||
**Check Traefik logs:**
|
||||
```bash
|
||||
docker logs traefik | grep letsencrypt
|
||||
```
|
||||
|
||||
**Common fixes:**
|
||||
1. Ensure port 80 is accessible (Let's Encrypt HTTP challenge)
|
||||
2. Verify DNS is pointing to your server
|
||||
3. Check email in Traefik's ACME configuration
|
||||
4. Ensure `acme.json` has correct permissions (600)
|
||||
|
||||
### Issue: Database connection failed
|
||||
|
||||
**Check environment variables:**
|
||||
```bash
|
||||
docker exec merchbay_admin_app env | grep DB_
|
||||
```
|
||||
|
||||
**Test connection:**
|
||||
```bash
|
||||
docker exec merchbay_admin_app php artisan tinker
|
||||
>>> DB::connection()->getPdo();
|
||||
```
|
||||
|
||||
### Issue: 502 Bad Gateway
|
||||
|
||||
**Possible causes:**
|
||||
1. Application not fully started
|
||||
2. Wrong port in Traefik label (should be 80)
|
||||
3. Application crashed
|
||||
|
||||
**Check:**
|
||||
```bash
|
||||
# Container status
|
||||
docker ps -a | grep merchbay_admin
|
||||
|
||||
# Application logs
|
||||
docker logs merchbay_admin_app --tail 100
|
||||
|
||||
# Restart container
|
||||
docker restart merchbay_admin_app
|
||||
```
|
||||
|
||||
## Updating the Application
|
||||
|
||||
### Via Gitea Actions (Automatic)
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Update application"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### Via Portainer
|
||||
|
||||
1. Go to `Stacks` → `merchbay-admin`
|
||||
2. Click `Editor`
|
||||
3. Update image or configuration
|
||||
4. Click `Update the stack`
|
||||
5. Enable "Re-pull image and redeploy"
|
||||
|
||||
### Manual Update
|
||||
|
||||
```bash
|
||||
ssh deploy@your-server
|
||||
cd /var/www/merchbay_admin
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
## Rollback
|
||||
|
||||
### Via Portainer
|
||||
|
||||
1. Go to `Stacks` → `merchbay-admin`
|
||||
2. Click on the stack
|
||||
3. Find previous version in `Stack History` (if available)
|
||||
4. Revert to previous version
|
||||
|
||||
### Manual Rollback
|
||||
|
||||
```bash
|
||||
# List available backups
|
||||
ls -lh /var/www/merchbay_admin/backups/
|
||||
|
||||
# Restore from backup
|
||||
cd /var/www/merchbay_admin
|
||||
tar -xzf backups/backup_YYYYMMDD_HHMMSS.tar.gz
|
||||
|
||||
# Restart
|
||||
docker compose restart
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Use Strong Database Passwords**: Generate with `openssl rand -base64 32`
|
||||
2. **Restrict SSH Access**: Use key-based authentication only
|
||||
3. **Firewall Rules**: Only allow necessary ports (80, 443, 22)
|
||||
4. **Regular Backups**: Automated backups of database and storage
|
||||
5. **Keep Docker Updated**: Regularly update Docker and images
|
||||
6. **Monitor Logs**: Set up log monitoring/alerting
|
||||
7. **Use Secrets**: Never commit sensitive data to repository
|
||||
8. **HTTPS Only**: Ensure HTTP redirects to HTTPS
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### PHP-FPM Configuration
|
||||
|
||||
Consider switching to PHP-FPM for better performance:
|
||||
|
||||
```dockerfile
|
||||
FROM php:7.4-fpm-alpine
|
||||
# ... additional configuration
|
||||
```
|
||||
|
||||
### Use Redis for Cache/Sessions
|
||||
|
||||
```env
|
||||
CACHE_DRIVER=redis
|
||||
SESSION_DRIVER=redis
|
||||
REDIS_HOST=redis
|
||||
```
|
||||
|
||||
Add Redis service to docker-compose:
|
||||
```yaml
|
||||
services:
|
||||
redis:
|
||||
image: redis:alpine
|
||||
networks:
|
||||
- default
|
||||
```
|
||||
|
||||
### Enable OPcache
|
||||
|
||||
Already included in Dockerfile, verify:
|
||||
```bash
|
||||
docker exec merchbay_admin_app php -i | grep opcache
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### View Real-time Logs in Portainer
|
||||
|
||||
1. Navigate to `Containers`
|
||||
2. Click on `merchbay_admin_app`
|
||||
3. Select `Logs` tab
|
||||
4. Enable `Auto-refresh`
|
||||
|
||||
### Set Up Alerts
|
||||
|
||||
Configure Portainer notifications:
|
||||
1. `Settings` → `Notifications`
|
||||
2. Add webhook or email notification
|
||||
3. Set up container health checks
|
||||
|
||||
## Support
|
||||
|
||||
For issues:
|
||||
1. Check application logs in Portainer
|
||||
2. Verify Traefik configuration
|
||||
3. Test database connectivity
|
||||
4. Review Gitea Actions logs if using CI/CD
|
||||
@@ -1,187 +0,0 @@
|
||||
# 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-admin.merchbay.app
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=merchbay_dev
|
||||
DB_USERNAME=merchbay_user
|
||||
DB_PASSWORD=your_dev_password
|
||||
DOMAIN=dev-admin.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
|
||||
264
DEPLOYMENT.md
264
DEPLOYMENT.md
@@ -1,264 +0,0 @@
|
||||
# Gitea Actions Deployment Guide
|
||||
|
||||
This repository uses Gitea Actions for automated deployment to your server.
|
||||
|
||||
## Workflows
|
||||
|
||||
### 1. Deploy Workflow (`.gitea/workflows/deploy.yml`)
|
||||
Automatically deploys the application when code is pushed to `main` or `master` branch.
|
||||
|
||||
**Steps:**
|
||||
1. Builds Docker image
|
||||
2. Transfers image to deployment server
|
||||
3. Stops existing container
|
||||
4. Starts new container
|
||||
5. Runs database migrations
|
||||
6. Clears and caches Laravel configuration
|
||||
|
||||
### 2. Build and Push Workflow (`.gitea/workflows/build-push.yml`)
|
||||
Builds and pushes Docker images to a registry when a version tag is created.
|
||||
|
||||
## Required Secrets
|
||||
|
||||
Configure these secrets in your Gitea repository settings:
|
||||
`Settings` → `Secrets` → `Actions`
|
||||
|
||||
### Deployment Secrets
|
||||
|
||||
| Secret Name | Description | Example |
|
||||
|------------|-------------|---------|
|
||||
| `DEPLOY_HOST` | Deployment server hostname or IP | `192.168.1.100` or `example.com` |
|
||||
| `DEPLOY_USER` | SSH username for deployment | `deploy` or `ubuntu` |
|
||||
| `DEPLOY_SSH_KEY` | Private SSH key for authentication | `-----BEGIN RSA PRIVATE KEY-----...` |
|
||||
| `DEPLOY_PORT` | SSH port (optional, defaults to 22) | `22` |
|
||||
| `DEPLOY_DIR` | Deployment directory (optional) | `/var/www/merchbay_admin` |
|
||||
|
||||
### Docker Registry Secrets (Optional)
|
||||
|
||||
Only required if using the build-push workflow or private registry:
|
||||
|
||||
| Secret Name | Description | Example |
|
||||
|------------|-------------|---------|
|
||||
| `DOCKER_REGISTRY_URL` | Docker registry URL | `registry.example.com` or `docker.io` |
|
||||
| `DOCKER_USERNAME` | Registry username | `myuser` |
|
||||
| `DOCKER_PASSWORD` | Registry password or token | `mypassword` |
|
||||
|
||||
### Database Configuration on Server
|
||||
|
||||
Create a `.env` file in your deployment directory with database credentials:
|
||||
|
||||
```bash
|
||||
# On your deployment server
|
||||
sudo mkdir -p /var/www/merchbay_admin
|
||||
sudo nano /var/www/merchbay_admin/.env
|
||||
```
|
||||
|
||||
Add your database configuration:
|
||||
|
||||
```env
|
||||
DB_HOST=your-mysql-host
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=merchbay_admin
|
||||
DB_USERNAME=your-mysql-user
|
||||
DB_PASSWORD=your-mysql-password
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_KEY=base64:YOUR_APP_KEY_HERE
|
||||
```
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### 1. Generate SSH Key for Deployment
|
||||
|
||||
On your local machine or CI server:
|
||||
|
||||
```bash
|
||||
# Generate a new SSH key pair
|
||||
ssh-keygen -t rsa -b 4096 -f ~/.ssh/deploy_key -N ""
|
||||
|
||||
# Copy the public key to your deployment server
|
||||
ssh-copy-id -i ~/.ssh/deploy_key.pub user@your-server
|
||||
|
||||
# Copy the private key content for Gitea secret
|
||||
cat ~/.ssh/deploy_key
|
||||
```
|
||||
|
||||
### 2. Configure Gitea Secrets
|
||||
|
||||
1. Go to your Gitea repository
|
||||
2. Navigate to `Settings` → `Secrets` → `Actions`
|
||||
3. Add each required secret listed above
|
||||
4. For `DEPLOY_SSH_KEY`, paste the entire private key content
|
||||
|
||||
### 3. Prepare Deployment Server
|
||||
|
||||
On your deployment server, install Docker and Docker Compose:
|
||||
|
||||
```bash
|
||||
# Install Docker
|
||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
||||
sudo sh get-docker.sh
|
||||
|
||||
# Add your user to docker group
|
||||
sudo usermod -aG docker $USER
|
||||
|
||||
# Install Docker Compose
|
||||
sudo apt-get update
|
||||
sudo apt-get install docker-compose-plugin
|
||||
|
||||
# Create deployment directory
|
||||
sudo mkdir -p /var/www/merchbay_admin
|
||||
sudo chown $USER:$USER /var/www/merchbay_admin
|
||||
|
||||
# Create .env file with database credentials
|
||||
nano /var/www/merchbay_admin/.env
|
||||
```
|
||||
|
||||
### 4. Update docker-compose.yml for Production
|
||||
|
||||
Ensure your `docker-compose.yml` references the `.env` file:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
environment:
|
||||
- DB_HOST=${DB_HOST}
|
||||
- DB_PORT=${DB_PORT}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
```
|
||||
|
||||
## Triggering Deployment
|
||||
|
||||
### Automatic Deployment
|
||||
|
||||
Push to main/master branch:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Deploy updates"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### Manual Deployment
|
||||
|
||||
1. Go to your Gitea repository
|
||||
2. Click on `Actions`
|
||||
3. Select `Deploy MerchBay Admin` workflow
|
||||
4. Click `Run workflow`
|
||||
|
||||
## Monitoring Deployment
|
||||
|
||||
### View Workflow Logs
|
||||
|
||||
1. Go to `Actions` tab in your Gitea repository
|
||||
2. Click on the running/completed workflow
|
||||
3. View logs for each step
|
||||
|
||||
### Check Application Logs
|
||||
|
||||
On your deployment server:
|
||||
|
||||
```bash
|
||||
cd /var/www/merchbay_admin
|
||||
docker compose logs -f app
|
||||
```
|
||||
|
||||
### Verify Deployment
|
||||
|
||||
```bash
|
||||
# Check container status
|
||||
docker compose ps
|
||||
|
||||
# Test application
|
||||
curl http://localhost:8080
|
||||
|
||||
# Access application shell
|
||||
docker compose exec app bash
|
||||
```
|
||||
|
||||
## Rollback Procedure
|
||||
|
||||
If deployment fails, you can quickly rollback:
|
||||
|
||||
```bash
|
||||
# On deployment server
|
||||
cd /var/www/merchbay_admin
|
||||
|
||||
# Stop current container
|
||||
docker compose down
|
||||
|
||||
# Load previous image (if available)
|
||||
docker images # Find previous image ID
|
||||
docker tag <previous-image-id> merchbay_admin:latest
|
||||
|
||||
# Start with previous version
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### SSH Connection Issues
|
||||
|
||||
```bash
|
||||
# Test SSH connection from CI to server
|
||||
ssh -i ~/.ssh/deploy_key user@your-server
|
||||
|
||||
# Check SSH key permissions
|
||||
chmod 600 ~/.ssh/deploy_key
|
||||
```
|
||||
|
||||
### Docker Permission Issues
|
||||
|
||||
```bash
|
||||
# On deployment server, ensure user is in docker group
|
||||
sudo usermod -aG docker $USER
|
||||
newgrp docker
|
||||
```
|
||||
|
||||
### Migration Failures
|
||||
|
||||
```bash
|
||||
# Manually run migrations
|
||||
docker compose exec app php artisan migrate --force
|
||||
|
||||
# Check database connection
|
||||
docker compose exec app php artisan tinker
|
||||
>>> DB::connection()->getPdo();
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Use SSH keys, not passwords** for server authentication
|
||||
2. **Restrict SSH key** to only deployment commands if possible
|
||||
3. **Use secrets** for all sensitive data, never commit to repository
|
||||
4. **Set proper file permissions** on deployment server (755 for directories, 644 for files)
|
||||
5. **Enable firewall** on deployment server and restrict access
|
||||
6. **Use HTTPS** with SSL certificates in production
|
||||
7. **Regular backups** of database and uploaded files
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Using Docker Registry
|
||||
|
||||
To use a private registry:
|
||||
|
||||
1. Add registry secrets to Gitea
|
||||
2. Update deployment script to pull from registry instead of transferring image
|
||||
3. Use the build-push workflow to automate image publishing
|
||||
|
||||
### Zero-Downtime Deployment
|
||||
|
||||
For zero-downtime deployments, consider:
|
||||
|
||||
1. Using a load balancer
|
||||
2. Running multiple container instances
|
||||
3. Implementing blue-green deployment strategy
|
||||
|
||||
### Environment-Specific Deployments
|
||||
|
||||
Create separate workflows for staging and production:
|
||||
|
||||
- `.gitea/workflows/deploy-staging.yml` (triggered on `develop` branch)
|
||||
- `.gitea/workflows/deploy-production.yml` (triggered on `main` branch)
|
||||
165
README-DOCKER.md
165
README-DOCKER.md
@@ -1,165 +0,0 @@
|
||||
# Docker Deployment Guide for MerchBay Admin
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Docker installed on your system
|
||||
- Docker Compose installed on your system
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Build and Start Containers
|
||||
|
||||
```bash
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
This will:
|
||||
- Build the application container
|
||||
- Start MySQL database
|
||||
- Start PHPMyAdmin
|
||||
- Set up networking between containers
|
||||
|
||||
### 2. Access the Application
|
||||
|
||||
- **Application**: http://localhost:8080
|
||||
- **PHPMyAdmin**: http://localhost:8081
|
||||
|
||||
### 3. Run Database Migrations
|
||||
|
||||
```bash
|
||||
docker-compose exec app php artisan migrate
|
||||
```
|
||||
|
||||
### 4. Seed Database (if needed)
|
||||
|
||||
```bash
|
||||
docker-compose exec app php artisan db:seed
|
||||
```
|
||||
|
||||
## Useful Commands
|
||||
|
||||
### View Container Logs
|
||||
|
||||
```bash
|
||||
docker-compose logs -f app
|
||||
```
|
||||
|
||||
### Access Container Shell
|
||||
|
||||
```bash
|
||||
docker-compose exec app bash
|
||||
```
|
||||
|
||||
### Stop Containers
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### Stop and Remove Volumes (Clean Slate)
|
||||
|
||||
```bash
|
||||
docker-compose down -v
|
||||
```
|
||||
|
||||
### Rebuild Containers
|
||||
|
||||
```bash
|
||||
docker-compose up -d --build --force-recreate
|
||||
```
|
||||
|
||||
### Run Artisan Commands
|
||||
|
||||
```bash
|
||||
docker-compose exec app php artisan [command]
|
||||
```
|
||||
|
||||
### Clear Laravel Cache
|
||||
|
||||
```bash
|
||||
docker-compose exec app php artisan cache:clear
|
||||
docker-compose exec app php artisan config:clear
|
||||
docker-compose exec app php artisan route:clear
|
||||
docker-compose exec app php artisan view:clear
|
||||
```
|
||||
|
||||
### Install/Update Composer Dependencies
|
||||
|
||||
```bash
|
||||
docker-compose exec app composer install
|
||||
# or
|
||||
docker-compose exec app composer update
|
||||
```
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
Edit the `docker-compose.yml` file to customize:
|
||||
- Database credentials
|
||||
- Port mappings
|
||||
- Environment variables
|
||||
|
||||
For production deployment, update the `APP_ENV` and `APP_DEBUG` values:
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
- APP_ENV=production
|
||||
- APP_DEBUG=false
|
||||
```
|
||||
|
||||
## Database Connection
|
||||
|
||||
The application connects to the MySQL container using these credentials (defined in docker-compose.yml):
|
||||
|
||||
- **Host**: db
|
||||
- **Database**: merchbay_admin
|
||||
- **Username**: merchbay_user
|
||||
- **Password**: merchbay_password
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Permission Issues
|
||||
|
||||
If you encounter permission errors:
|
||||
|
||||
```bash
|
||||
docker-compose exec app chown -R www-data:www-data /var/www/html/storage
|
||||
docker-compose exec app chmod -R 755 /var/www/html/storage
|
||||
```
|
||||
|
||||
### Database Connection Issues
|
||||
|
||||
Ensure the database container is fully started:
|
||||
|
||||
```bash
|
||||
docker-compose logs db
|
||||
```
|
||||
|
||||
Wait a few seconds after starting containers for MySQL to initialize.
|
||||
|
||||
### Port Already in Use
|
||||
|
||||
If ports 8080 or 3306 are already in use, modify the ports in `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "8090:80" # Change 8080 to 8090 or any available port
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
For production environments:
|
||||
|
||||
1. Update `.env` file with production settings
|
||||
2. Set `APP_DEBUG=false` in docker-compose.yml
|
||||
3. Use a secure database password
|
||||
4. Consider using a reverse proxy (Nginx/Traefik) with SSL
|
||||
5. Set up proper backup strategies for database volumes
|
||||
6. Configure log rotation
|
||||
|
||||
## Volumes
|
||||
|
||||
- `db_data`: Persistent MySQL data
|
||||
- `./storage`: Laravel storage (logs, cache, sessions)
|
||||
- `./public/uploads`: User uploaded files
|
||||
|
||||
These volumes ensure data persists across container restarts.
|
||||
@@ -1,314 +0,0 @@
|
||||
# Traefik SSL Configuration for MerchBay Admin
|
||||
|
||||
This document explains how to configure paid SSL certificates for production and automatic Let's Encrypt for development.
|
||||
|
||||
## Network Configuration
|
||||
|
||||
All deployments use the external network: `traefik-public`
|
||||
|
||||
```bash
|
||||
# Ensure the network exists
|
||||
docker network inspect traefik-public >/dev/null 2>&1 || docker network create traefik-public
|
||||
```
|
||||
|
||||
## Development (dev-admin.merchbay.app) - Automatic SSL
|
||||
|
||||
Development uses Let's Encrypt for automatic SSL certificate generation.
|
||||
|
||||
### Traefik Configuration
|
||||
|
||||
Ensure your Traefik has Let's Encrypt configured:
|
||||
|
||||
```yaml
|
||||
# traefik.yml or dynamic config
|
||||
certificatesResolvers:
|
||||
letsencrypt:
|
||||
acme:
|
||||
email: admin@merchbay.app
|
||||
storage: /letsencrypt/acme.json
|
||||
httpChallenge:
|
||||
entryPoint: web
|
||||
```
|
||||
|
||||
### Application Labels (Already configured in docker-compose)
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls.certresolver=letsencrypt"
|
||||
```
|
||||
|
||||
## Production (merchbay.app) - Paid SSL Certificate
|
||||
|
||||
Production uses a paid SSL certificate (e.g., from GoDaddy, Namecheap, Cloudflare).
|
||||
|
||||
### Step 1: Prepare SSL Certificate Files
|
||||
|
||||
You should have these files from your SSL provider:
|
||||
- `merchbay.app.crt` - Certificate file
|
||||
- `merchbay.app.key` - Private key file
|
||||
- `ca-bundle.crt` - CA bundle (optional, for chain)
|
||||
|
||||
Create a combined certificate file:
|
||||
|
||||
```bash
|
||||
# Your SSL certificates are in /srv/certs
|
||||
# Verify files exist
|
||||
ls -la /srv/certs/
|
||||
|
||||
# If you have a CA bundle, create a full chain
|
||||
cd /srv/certs
|
||||
cat merchbay.app.crt ca-bundle.crt > merchbay.app-fullchain.crt
|
||||
|
||||
# Set proper permissions
|
||||
sudo chmod 600 /srv/certs/*.key
|
||||
sudo chmod 644 /srv/certs/*.crt
|
||||
```
|
||||
|
||||
### Step 2: Configure Traefik File Provider
|
||||
|
||||
Create a dynamic configuration file for Traefik:
|
||||
|
||||
```bash
|
||||
sudo nano /opt/traefik/dynamic/certs.yml
|
||||
```
|
||||
|
||||
Add:
|
||||
|
||||
```yaml
|
||||
# /opt/traefik/dynamic/certs.yml or your Traefik dynamic config location
|
||||
tls:
|
||||
certificates:
|
||||
- certFile: /srv/certs/merchbay.app-fullchain.crt
|
||||
keyFile: /srv/certs/merchbay.app.key
|
||||
stores:
|
||||
- default
|
||||
stores:
|
||||
default:
|
||||
defaultCertificate:
|
||||
certFile: /srv/certs/merchbay.app-fullchain.crt
|
||||
keyFile: /srv/certs/merchbay.app.key
|
||||
```
|
||||
|
||||
### Step 3: Update Traefik docker-compose.yml
|
||||
|
||||
Ensure Traefik has file provider enabled and certificates mounted:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v2.10
|
||||
command:
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.network=traefik-public"
|
||||
- "--providers.file.directory=/etc/traefik/dynamic"
|
||||
- "--providers.file.watch=true"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.websecure.address=:443"
|
||||
# Let's Encrypt for dev
|
||||
- "--certificatesresolvers.letsencrypt.acme.email=admin@merchbay.app"
|
||||
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
|
||||
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /srv/certs:/srv/certs:ro
|
||||
- /opt/traefik/dynamic:/etc/traefik/dynamic:ro
|
||||
- traefik-letsencrypt:/letsencrypt
|
||||
networks:
|
||||
- traefik-public
|
||||
```
|
||||
|
||||
### Step 4: Restart Traefik
|
||||
|
||||
```bash
|
||||
cd /path/to/traefik
|
||||
docker compose restart traefik
|
||||
|
||||
# Verify certificates are loaded
|
||||
docker compose logs traefik | grep -i cert
|
||||
```
|
||||
|
||||
## Application Configuration
|
||||
|
||||
### Development Branch (dev)
|
||||
|
||||
File: `docker-compose.portainer.dev.yml`
|
||||
|
||||
- Domain: `dev-admin.merchbay.app`
|
||||
- SSL: Let's Encrypt (automatic)
|
||||
- Certificate Resolver: `letsencrypt`
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- "traefik.http.routers.merchbay-admin-dev.rule=Host(`dev-admin.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls.certresolver=letsencrypt"
|
||||
```
|
||||
|
||||
### Production Branch (main)
|
||||
|
||||
File: `docker-compose.portainer.yml`
|
||||
|
||||
- Domain: `merchbay.app`
|
||||
- SSL: Paid certificate (via Traefik file provider)
|
||||
- No certresolver label (uses default store)
|
||||
|
||||
```yaml
|
||||
labels:
|
||||
- "traefik.http.routers.merchbay-admin.rule=Host(`merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin.tls=true"
|
||||
# No certresolver - uses file provider certificate
|
||||
```
|
||||
|
||||
## Gitea Secrets Configuration
|
||||
|
||||
### Development Secrets
|
||||
|
||||
```
|
||||
DEV_DB_HOST=dev-mysql-host
|
||||
DEV_DB_PORT=3306
|
||||
DEV_DB_DATABASE=merchbay_admin_dev
|
||||
DEV_DB_USERNAME=dev_user
|
||||
DEV_DB_PASSWORD=dev_password
|
||||
```
|
||||
|
||||
### Production Secrets
|
||||
|
||||
```
|
||||
PROD_DEPLOY_HOST=prod-server-ip
|
||||
PROD_DEPLOY_USER=deploy
|
||||
PROD_DEPLOY_SSH_KEY=-----BEGIN RSA PRIVATE KEY-----...
|
||||
PROD_DEPLOY_PORT=22
|
||||
PROD_DB_HOST=prod-mysql-host
|
||||
PROD_DB_PORT=3306
|
||||
PROD_DB_DATABASE=merchbay_admin
|
||||
PROD_DB_USERNAME=prod_user
|
||||
PROD_DB_PASSWORD=prod_password
|
||||
```
|
||||
|
||||
### Shared Secrets (if using same server)
|
||||
|
||||
```
|
||||
DEPLOY_HOST=your-server-ip
|
||||
DEPLOY_USER=deploy
|
||||
DEPLOY_SSH_KEY=-----BEGIN RSA PRIVATE KEY-----...
|
||||
DEPLOY_PORT=22
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
### Check Development SSL
|
||||
|
||||
```bash
|
||||
# Check certificate issuer (should be Let's Encrypt)
|
||||
echo | openssl s_client -servername dev-admin.merchbay.app -connect dev-admin.merchbay.app:443 2>/dev/null | openssl x509 -noout -issuer
|
||||
# Should show: issuer=C = US, O = Let's Encrypt, CN = R3
|
||||
```
|
||||
|
||||
### Check Production SSL
|
||||
|
||||
```bash
|
||||
# Check certificate issuer (should be your SSL provider)
|
||||
echo | openssl s_client -servername merchbay.app -connect merchbay.app:443 2>/dev/null | openssl x509 -noout -issuer
|
||||
# Should show your paid SSL provider
|
||||
|
||||
# Check certificate validity
|
||||
echo | openssl s_client -servername merchbay.app -connect merchbay.app:443 2>/dev/null | openssl x509 -noout -dates
|
||||
```
|
||||
|
||||
### Verify in Browser
|
||||
|
||||
1. Visit https://dev-admin.merchbay.app
|
||||
- Certificate should be issued by "Let's Encrypt Authority X3"
|
||||
|
||||
2. Visit https://merchbay.com
|
||||
- Certificate should be issued by your paid SSL provider
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Development SSL Not Working
|
||||
|
||||
```bash
|
||||
# Check Let's Encrypt logs
|
||||
docker logs traefik | grep letsencrypt
|
||||
|
||||
# Verify acme.json permissions
|
||||
ls -l /path/to/letsencrypt/acme.json
|
||||
# Should be: -rw------- (600)
|
||||
|
||||
# Check DNS
|
||||
dig dev-admin.merchbay.app +short
|
||||
# Should return your server IP
|
||||
```
|
||||
|
||||
### Production SSL Not Working
|
||||
|
||||
```bash
|
||||
# Verify Traefik can read certificates
|
||||
docker exec traefik ls -l /srv/certs/
|
||||
|
||||
# Check dynamic configuration is loaded
|
||||
docker exec traefik cat /etc/traefik/dynamic/certs.yml
|
||||
|
||||
# Verify certificate format
|
||||
openssl x509 -in /srv/certs/merchbay.app-fullchain.crt -text -noout
|
||||
|
||||
# Check private key
|
||||
openssl rsa -in /srv/certs/merchbay.app.key -check
|
||||
```
|
||||
|
||||
### Certificate Mismatch
|
||||
|
||||
```bash
|
||||
# Verify certificate and key match
|
||||
openssl x509 -noout -modulus -in /srv/certs/merchbay.app.crt | openssl md5
|
||||
openssl rsa -noout -modulus -in /srv/certs/merchbay.app.key | openssl md5
|
||||
# Both should output the same hash
|
||||
```
|
||||
|
||||
## Renewing Certificates
|
||||
|
||||
### Development (Let's Encrypt)
|
||||
|
||||
Automatic renewal every 60 days. No action needed.
|
||||
|
||||
### Production (Paid SSL)
|
||||
|
||||
Before certificate expiration:
|
||||
|
||||
1. Download new certificate from your SSL provider
|
||||
2. Update files in `/srv/certs/`
|
||||
3. Restart Traefik: `docker compose restart traefik`
|
||||
4. Verify: `curl -vI https://merchbay.app`
|
||||
|
||||
## DNS Configuration
|
||||
|
||||
### Development
|
||||
|
||||
```
|
||||
Type: A
|
||||
Name: dev-admin.merchbay.app
|
||||
Value: YOUR_SERVER_IP
|
||||
TTL: 3600
|
||||
```
|
||||
|
||||
### Production
|
||||
|
||||
```
|
||||
Type: A
|
||||
Name: merchbay.app (or @)
|
||||
Value: YOUR_SERVER_IP
|
||||
TTL: 3600
|
||||
|
||||
Type: A
|
||||
Name: www.merchbay.app
|
||||
Value: YOUR_SERVER_IP
|
||||
TTL: 3600
|
||||
```
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
1. **Keep certificates private**: Never commit SSL keys to git
|
||||
2. **Use strong permissions**: 600 for private keys, 644 for certificates
|
||||
3. **Monitor expiration**: Set reminders 30 days before expiration
|
||||
4. **Use HSTS**: Add header after SSL is working correctly
|
||||
5. **Enable OCSP stapling**: Improves SSL performance
|
||||
6. **Regular updates**: Keep Traefik updated for security patches
|
||||
105
deploy.sh
105
deploy.sh
@@ -1,105 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Deployment script for MerchBay Admin
|
||||
# This can be used for manual deployments or called from CI/CD
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
DEPLOY_DIR="${DEPLOY_DIR:-/var/www/merchbay_admin}"
|
||||
APP_NAME="merchbay_admin"
|
||||
BACKUP_DIR="${DEPLOY_DIR}/backups"
|
||||
|
||||
echo -e "${GREEN}Starting deployment of ${APP_NAME}...${NC}"
|
||||
|
||||
# Create backup directory
|
||||
mkdir -p "${BACKUP_DIR}"
|
||||
|
||||
# Backup current state
|
||||
if [ -d "${DEPLOY_DIR}/storage" ]; then
|
||||
echo -e "${YELLOW}Creating backup...${NC}"
|
||||
BACKUP_FILE="${BACKUP_DIR}/backup_$(date +%Y%m%d_%H%M%S).tar.gz"
|
||||
tar -czf "${BACKUP_FILE}" -C "${DEPLOY_DIR}" storage .env 2>/dev/null || true
|
||||
echo -e "${GREEN}Backup created: ${BACKUP_FILE}${NC}"
|
||||
fi
|
||||
|
||||
# Navigate to deployment directory
|
||||
cd "${DEPLOY_DIR}"
|
||||
|
||||
# Check if .env exists
|
||||
if [ ! -f .env ]; then
|
||||
echo -e "${RED}Error: .env file not found!${NC}"
|
||||
echo "Please create .env file with database credentials"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Pull latest code (if using git deployment)
|
||||
if [ -d .git ]; then
|
||||
echo -e "${YELLOW}Pulling latest code...${NC}"
|
||||
git pull origin main || git pull origin master
|
||||
fi
|
||||
|
||||
# Stop existing containers
|
||||
echo -e "${YELLOW}Stopping existing containers...${NC}"
|
||||
docker compose down
|
||||
|
||||
# Build new image
|
||||
echo -e "${YELLOW}Building Docker image...${NC}"
|
||||
docker compose build --no-cache
|
||||
|
||||
# Start containers
|
||||
echo -e "${YELLOW}Starting containers...${NC}"
|
||||
docker compose up -d
|
||||
|
||||
# Wait for container to be ready
|
||||
echo -e "${YELLOW}Waiting for application to start...${NC}"
|
||||
sleep 10
|
||||
|
||||
# Run migrations
|
||||
echo -e "${YELLOW}Running database migrations...${NC}"
|
||||
docker compose exec -T app php artisan migrate --force || {
|
||||
echo -e "${RED}Migration failed! Rolling back...${NC}"
|
||||
docker compose down
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Clear and cache configuration
|
||||
echo -e "${YELLOW}Optimizing application...${NC}"
|
||||
docker compose exec -T app php artisan config:cache
|
||||
docker compose exec -T app php artisan route:cache
|
||||
docker compose exec -T app php artisan view:cache
|
||||
|
||||
# Set proper permissions
|
||||
echo -e "${YELLOW}Setting permissions...${NC}"
|
||||
docker compose exec -T app chown -R www-data:www-data /var/www/html/storage
|
||||
docker compose exec -T app chmod -R 755 /var/www/html/storage
|
||||
|
||||
# Health check
|
||||
echo -e "${YELLOW}Performing health check...${NC}"
|
||||
sleep 5
|
||||
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8080)
|
||||
|
||||
if [ "$HTTP_STATUS" -eq 200 ]; then
|
||||
echo -e "${GREEN}✓ Deployment successful! Application is running.${NC}"
|
||||
echo -e "${GREEN}✓ HTTP Status: ${HTTP_STATUS}${NC}"
|
||||
|
||||
# Keep only last 5 backups
|
||||
cd "${BACKUP_DIR}"
|
||||
ls -t backup_*.tar.gz 2>/dev/null | tail -n +6 | xargs -r rm
|
||||
|
||||
echo -e "${GREEN}Deployment completed successfully!${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ Health check failed! HTTP Status: ${HTTP_STATUS}${NC}"
|
||||
echo -e "${YELLOW}Check logs: docker compose logs app${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display container status
|
||||
echo -e "${YELLOW}Container status:${NC}"
|
||||
docker compose ps
|
||||
@@ -1,48 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
# Development Stack - Portainer Configuration
|
||||
# Deploy this through Portainer UI: Stacks -> Add Stack -> Web Editor
|
||||
# Branch: dev
|
||||
|
||||
services:
|
||||
app:
|
||||
image: merchbay_admin:dev
|
||||
container_name: merchbay_admin_dev
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=staging
|
||||
- APP_DEBUG=false
|
||||
- APP_URL=https://dev-admin.merchbay.app
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=${DB_HOST}
|
||||
- DB_PORT=${DB_PORT:-3306}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
volumes:
|
||||
- app_storage_dev:/var/www/html/storage
|
||||
- app_uploads_dev:/var/www/html/public/uploads
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.merchbay-admin-dev.rule=Host(`dev-admin.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-dev.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls=true"
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.merchbay-admin-dev.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.merchbay-admin-dev-http.rule=Host(`dev-admin.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-dev-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-admin-dev-http.middlewares=https-redirect"
|
||||
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
|
||||
networks:
|
||||
- traefik-public
|
||||
|
||||
volumes:
|
||||
app_storage_dev:
|
||||
driver: local
|
||||
app_uploads_dev:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
@@ -1,49 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
# Production Stack - Portainer Configuration
|
||||
# Deploy this through Portainer UI: Stacks -> Add Stack -> Web Editor
|
||||
# Branch: main - Uses paid SSL certificate
|
||||
|
||||
services:
|
||||
app:
|
||||
image: merchbay_admin:latest
|
||||
container_name: merchbay_admin_prod
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=production
|
||||
- APP_DEBUG=false
|
||||
- APP_URL=https://merchbay.com
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=your-mysql-host
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=merchbay_admin
|
||||
- DB_USERNAME=your-mysql-user
|
||||
- DB_PASSWORD=your-mysql-password
|
||||
volumes:
|
||||
- app_storage:/var/www/html/storage
|
||||
- app_uploads:/var/www/html/public/uploads
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.merchbay-admin.rule=Host(`merchbay.com`)"
|
||||
- "traefik.http.routers.merchbay-admin.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-admin.tls=true"
|
||||
# Use custom TLS configuration (file provider for paid cert)
|
||||
# Ensure Traefik has file provider configured with your paid SSL cert
|
||||
- "traefik.http.services.merchbay-admin.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.merchbay-admin-http.rule=Host(`merchbay.com`)"
|
||||
- "traefik.http.routers.merchbay-admin-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-admin-http.middlewares=https-redirect"
|
||||
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
|
||||
networks:
|
||||
- traefik-public
|
||||
|
||||
volumes:
|
||||
app_storage:
|
||||
driver: local
|
||||
app_uploads:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
181
readme.md
181
readme.md
@@ -1,27 +1,178 @@
|
||||
# Laravel PHP Framework
|
||||
# MerchBay Admin Panel
|
||||
|
||||
[](https://travis-ci.org/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
A comprehensive administration platform built with Laravel 5.2 for managing e-commerce operations, product catalogs, and customer relationships.
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, queueing, and caching.
|
||||
## Overview
|
||||
|
||||
Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked.
|
||||
MerchBay Admin is a web-based administration interface designed to streamline business operations for custom merchandise and sportswear management. The platform provides robust tools for inventory control, order processing, and analytics.
|
||||
|
||||
## Official Documentation
|
||||
## Technology Stack
|
||||
|
||||
Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs).
|
||||
- **Framework**: Laravel 5.2
|
||||
- **PHP Version**: 7.4
|
||||
- **Web Server**: Apache 2.4
|
||||
- **Database**: MySQL
|
||||
- **Reverse Proxy**: Traefik with Let's Encrypt SSL
|
||||
- **Containerization**: Docker & Docker Compose
|
||||
- **CI/CD**: Gitea Actions
|
||||
|
||||
## Contributing
|
||||
## Features
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions).
|
||||
- User authentication and role-based access control
|
||||
- Product and inventory management
|
||||
- Order processing and tracking
|
||||
- Customer relationship management
|
||||
- Analytics and reporting dashboard
|
||||
- RESTful API endpoints
|
||||
- Secure HTTPS communication
|
||||
|
||||
## Security Vulnerabilities
|
||||
## Requirements
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.
|
||||
- Docker Engine 20.10+
|
||||
- Docker Compose 2.0+
|
||||
- PHP 7.4 (for local development)
|
||||
- Composer 1.x
|
||||
- MySQL 5.7+ or MariaDB 10.3+
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Docker (Recommended)
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repository-url>
|
||||
cd merchbay_admin
|
||||
|
||||
# Copy environment file
|
||||
cp .env.example .env
|
||||
|
||||
# Configure your environment variables
|
||||
vim .env
|
||||
|
||||
# Build and start containers
|
||||
docker-compose up -d
|
||||
|
||||
# Install dependencies
|
||||
docker exec merchbay_admin_app composer install
|
||||
|
||||
# Generate application key
|
||||
docker exec merchbay_admin_app php artisan key:generate
|
||||
|
||||
# Run migrations
|
||||
docker exec merchbay_admin_app php artisan migrate
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
```bash
|
||||
# Install PHP dependencies
|
||||
composer install
|
||||
|
||||
# Copy environment file
|
||||
cp .env.example .env
|
||||
|
||||
# Generate application key
|
||||
php artisan key:generate
|
||||
|
||||
# Configure database in .env file
|
||||
# Run migrations
|
||||
php artisan migrate
|
||||
|
||||
# Start development server
|
||||
php artisan serve
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Key environment variables to configure:
|
||||
|
||||
- `APP_URL` - Application URL (e.g., https://admin.merchbay.app)
|
||||
- `DB_HOST` - Database host
|
||||
- `DB_DATABASE` - Database name
|
||||
- `DB_USERNAME` - Database username
|
||||
- `DB_PASSWORD` - Database password
|
||||
|
||||
### SSL/HTTPS Configuration
|
||||
|
||||
The application uses Traefik as a reverse proxy with automatic Let's Encrypt SSL certificates. Ensure your DNS is properly configured and the following Traefik labels are set in `docker-compose.yml`.
|
||||
|
||||
## Deployment
|
||||
|
||||
This project includes automated CI/CD pipelines via Gitea Actions:
|
||||
|
||||
- **Development**: Auto-deploys on push to `dev` branch
|
||||
- **Production**: Auto-deploys on push to `main`/`master` branch
|
||||
- **Manual Builds**: Trigger builds with custom tags
|
||||
|
||||
Refer to [DEPLOYMENT.md](DEPLOYMENT.md) and [DEPLOYMENT-PORTAINER.md](DEPLOYMENT-PORTAINER.md) for detailed deployment instructions.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
merchbay_admin/
|
||||
├── app/ # Application core files
|
||||
│ ├── Http/ # Controllers, middleware, routes
|
||||
│ ├── Models/ # Eloquent models
|
||||
│ └── Providers/ # Service providers
|
||||
├── config/ # Configuration files
|
||||
├── database/ # Migrations and seeds
|
||||
├── public/ # Public assets
|
||||
├── resources/ # Views, assets, lang files
|
||||
├── storage/ # Application storage
|
||||
├── .gitea/workflows/ # CI/CD pipelines
|
||||
└── docker-compose.yml # Docker configuration
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Run PHPUnit tests
|
||||
docker exec merchbay_admin_app vendor/bin/phpunit
|
||||
|
||||
# Or locally
|
||||
./vendor/bin/phpunit
|
||||
```
|
||||
|
||||
### Artisan Commands
|
||||
|
||||
```bash
|
||||
# List all available commands
|
||||
docker exec merchbay_admin_app php artisan list
|
||||
|
||||
# Clear application cache
|
||||
docker exec merchbay_admin_app php artisan cache:clear
|
||||
|
||||
# Run database migrations
|
||||
docker exec merchbay_admin_app php artisan migrate
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- All HTTP traffic is automatically redirected to HTTPS
|
||||
- Environment variables are managed securely via `.env` files
|
||||
- SQL injection prevention via Eloquent ORM
|
||||
- CSRF protection enabled on all forms
|
||||
- XSS protection via Blade templating
|
||||
|
||||
For security vulnerabilities, please contact the development team directly.
|
||||
|
||||
## Documentation
|
||||
|
||||
Additional documentation is available:
|
||||
|
||||
- [Docker Setup Guide](README-DOCKER.md)
|
||||
- [Deployment Guide](DEPLOYMENT.md)
|
||||
- [Portainer Deployment](DEPLOYMENT-PORTAINER.md)
|
||||
- [Traefik SSL Configuration](TRAEFIK-SSL-CONFIG.md)
|
||||
|
||||
## Support
|
||||
|
||||
For issues, questions, or contributions, please contact the development team or open an issue in the repository.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
|
||||
This project is proprietary software. All rights reserved.
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
#!/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-admin.merchbay.app"
|
||||
DEFAULT_APP_URL="https://dev-admin.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}"
|
||||
@@ -1,90 +0,0 @@
|
||||
#!/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 ""
|
||||
Reference in New Issue
Block a user