chore: Refactor deployment scripts and workflows for improved clarity and efficiency
This commit is contained in:
@ -1,247 +1,53 @@
|
|||||||
name: Deploy to Testing Server
|
name: Deploy to Testing Server
|
||||||
|
|
||||||
on:
|
on:
|
||||||
pull_request:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- develop
|
- develop
|
||||||
types: [opened, synchronize, reopened]
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
deploy:
|
deploy:
|
||||||
name: Deploy to Testing Server
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
if: github.event.pull_request.merged == false # Only for open PRs
|
name: Deploy to Testing Environment
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v3
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
- name: Deploy via SSH
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: "18"
|
|
||||||
cache: "yarn"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Run linting
|
|
||||||
run: yarn lint:check
|
|
||||||
|
|
||||||
- name: Build application
|
|
||||||
run: yarn build
|
|
||||||
|
|
||||||
- name: Build Docker image
|
|
||||||
run: |
|
|
||||||
docker build -t low-code-engine:testing-${{ github.event.pull_request.number }} .
|
|
||||||
|
|
||||||
- name: Save Docker image
|
|
||||||
run: |
|
|
||||||
docker save low-code-engine:testing-${{ github.event.pull_request.number }} | gzip > low-code-engine-testing.tar.gz
|
|
||||||
|
|
||||||
- name: Deploy to Testing Server
|
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
uses: appleboy/ssh-action@v1.0.3
|
||||||
with:
|
with:
|
||||||
host: ${{ secrets.TESTING_SERVER_HOST }}
|
host: ${{ secrets.SSH_HOST }}
|
||||||
username: ${{ secrets.TESTING_SERVER_USER }}
|
username: ${{ secrets.SSH_USERNAME }}
|
||||||
key: ${{ secrets.TESTING_SERVER_SSH_KEY }}
|
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
port: ${{ secrets.TESTING_SERVER_PORT || 22 }}
|
port: ${{ secrets.SSH_PORT || 22 }}
|
||||||
script: |
|
script: |
|
||||||
# Create application directory if it doesn't exist
|
# Navigate to project directory
|
||||||
mkdir -p /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}
|
cd ${{ secrets.PROJECT_PATH }}
|
||||||
cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}
|
|
||||||
|
|
||||||
# Stop existing containers if they exist
|
# Pull latest code
|
||||||
docker-compose down || true
|
echo "🔄 Pulling latest code from repository..."
|
||||||
|
git pull origin develop
|
||||||
|
|
||||||
# Remove old images
|
# Install dependencies
|
||||||
docker image prune -f || true
|
echo "📦 Installing dependencies with yarn..."
|
||||||
|
yarn install --frozen-lockfile
|
||||||
|
|
||||||
- name: Copy files to server
|
# Run database migrations
|
||||||
uses: appleboy/scp-action@v0.1.7
|
echo "🗄️ Running database migrations..."
|
||||||
with:
|
yarn migration:run
|
||||||
host: ${{ secrets.TESTING_SERVER_HOST }}
|
|
||||||
username: ${{ secrets.TESTING_SERVER_USER }}
|
|
||||||
key: ${{ secrets.TESTING_SERVER_SSH_KEY }}
|
|
||||||
port: ${{ secrets.TESTING_SERVER_PORT || 22 }}
|
|
||||||
source: "low-code-engine-testing.tar.gz,docker-compose.yml,docker/"
|
|
||||||
target: "/opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}/"
|
|
||||||
|
|
||||||
- name: Load and run Docker containers
|
# Build the project
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
echo "🏗️ Building the project..."
|
||||||
with:
|
yarn build
|
||||||
host: ${{ secrets.TESTING_SERVER_HOST }}
|
|
||||||
username: ${{ secrets.TESTING_SERVER_USER }}
|
|
||||||
key: ${{ secrets.TESTING_SERVER_SSH_KEY }}
|
|
||||||
port: ${{ secrets.TESTING_SERVER_PORT || 22 }}
|
|
||||||
script: |
|
|
||||||
cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}
|
|
||||||
|
|
||||||
# Load Docker image
|
# Restart PM2 process
|
||||||
gunzip -c low-code-engine-testing.tar.gz | docker load
|
echo "🔄 Restarting PM2 application..."
|
||||||
|
pm2 restart ${{ secrets.PM2_APP_NAME || 'low-code-engine' }}
|
||||||
|
|
||||||
# Create .env file for testing environment
|
# Show PM2 status
|
||||||
cat > .env << EOF
|
echo "✅ Deployment completed! PM2 status:"
|
||||||
NODE_ENV=testing
|
pm2 status
|
||||||
DB_ROOT_PASSWORD=${{ secrets.TESTING_DB_ROOT_PASSWORD }}
|
|
||||||
DB_DATABASE=low_code_engine_pr_${{ github.event.pull_request.number }}
|
|
||||||
DB_USERNAME=${{ secrets.TESTING_DB_USERNAME }}
|
|
||||||
DB_PASSWORD=${{ secrets.TESTING_DB_PASSWORD }}
|
|
||||||
DB_PORT=3306
|
|
||||||
APP_PORT=${{ vars.TESTING_BASE_PORT || 3000 }}${{ github.event.pull_request.number }}
|
|
||||||
REDIS_HOST=redis
|
|
||||||
REDIS_PORT=6379
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Create docker-compose.override.yml for testing environment
|
echo "🚀 Application deployed successfully!"
|
||||||
cat > docker-compose.override.yml << EOF
|
|
||||||
version: "3.8"
|
|
||||||
services:
|
|
||||||
app:
|
|
||||||
image: low-code-engine:testing-${{ github.event.pull_request.number }}
|
|
||||||
ports:
|
|
||||||
- "\${APP_PORT}:3000"
|
|
||||||
environment:
|
|
||||||
NODE_ENV: testing
|
|
||||||
DB_HOST: mariadb
|
|
||||||
DB_PORT: 3306
|
|
||||||
DB_USERNAME: \${DB_USERNAME}
|
|
||||||
DB_PASSWORD: \${DB_PASSWORD}
|
|
||||||
DB_DATABASE: \${DB_DATABASE}
|
|
||||||
REDIS_HOST: redis
|
|
||||||
REDIS_PORT: 6379
|
|
||||||
|
|
||||||
mariadb:
|
|
||||||
ports:
|
|
||||||
- "${{ vars.TESTING_BASE_DB_PORT || 3306 }}${{ github.event.pull_request.number }}:3306"
|
|
||||||
environment:
|
|
||||||
MYSQL_DATABASE: \${DB_DATABASE}
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7-alpine
|
|
||||||
ports:
|
|
||||||
- "${{ vars.TESTING_BASE_REDIS_PORT || 6379 }}${{ github.event.pull_request.number }}:6379"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Start containers
|
|
||||||
docker-compose up -d
|
|
||||||
|
|
||||||
# Wait for database to start
|
|
||||||
sleep 30
|
|
||||||
|
|
||||||
# Run migrations
|
|
||||||
docker-compose exec -T app yarn migration:run || true
|
|
||||||
|
|
||||||
# Check container status
|
|
||||||
docker-compose ps
|
|
||||||
|
|
||||||
- name: Health check
|
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.TESTING_SERVER_HOST }}
|
|
||||||
username: ${{ secrets.TESTING_SERVER_USER }}
|
|
||||||
key: ${{ secrets.TESTING_SERVER_SSH_KEY }}
|
|
||||||
port: ${{ secrets.TESTING_SERVER_PORT || 22 }}
|
|
||||||
script: |
|
|
||||||
cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}
|
|
||||||
|
|
||||||
# Check application availability
|
|
||||||
APP_PORT=${{ vars.TESTING_BASE_PORT || 3000 }}${{ github.event.pull_request.number }}
|
|
||||||
|
|
||||||
for i in {1..10}; do
|
|
||||||
if curl -f http://localhost:$APP_PORT/health > /dev/null 2>&1; then
|
|
||||||
echo "✅ Application is healthy on port $APP_PORT"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
echo "⏳ Waiting for application to start... (attempt $i/10)"
|
|
||||||
sleep 10
|
|
||||||
done
|
|
||||||
|
|
||||||
- name: Comment PR with deployment info
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const prNumber = context.payload.pull_request.number;
|
|
||||||
const appPort = ${{ vars.TESTING_BASE_PORT || 3000 }} + prNumber;
|
|
||||||
const dbPort = ${{ vars.TESTING_BASE_DB_PORT || 3306 }} + prNumber;
|
|
||||||
const redisPort = ${{ vars.TESTING_BASE_REDIS_PORT || 6379 }} + prNumber;
|
|
||||||
|
|
||||||
const comment = `## 🚀 Testing Deployment
|
|
||||||
|
|
||||||
Your PR has been deployed to the testing server!
|
|
||||||
|
|
||||||
**Deployment Details:**
|
|
||||||
- 🌐 Application URL: http://${{ secrets.TESTING_SERVER_HOST }}:${appPort}
|
|
||||||
- 🗄️ Database Port: ${dbPort}
|
|
||||||
- 🔴 Redis Port: ${redisPort}
|
|
||||||
- 📁 Server Path: \`/opt/low-code-engine/testing-pr-${prNumber}\`
|
|
||||||
|
|
||||||
**Available Commands on Server:**
|
|
||||||
\`\`\`bash
|
|
||||||
cd /opt/low-code-engine/testing-pr-${prNumber}
|
|
||||||
docker-compose logs app # View application logs
|
|
||||||
docker-compose logs mariadb # View database logs
|
|
||||||
docker-compose ps # Check container status
|
|
||||||
docker-compose exec app yarn migration:run # Run migrations
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
> **Note:** This deployment will be automatically cleaned up when the PR is closed or merged.
|
|
||||||
`;
|
|
||||||
|
|
||||||
github.rest.issues.createComment({
|
|
||||||
issue_number: prNumber,
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
body: comment
|
|
||||||
});
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
name: Cleanup on PR Close
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
if: github.event.pull_request.state == 'closed'
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Cleanup testing environment
|
|
||||||
uses: appleboy/ssh-action@v1.0.3
|
|
||||||
with:
|
|
||||||
host: ${{ secrets.TESTING_SERVER_HOST }}
|
|
||||||
username: ${{ secrets.TESTING_SERVER_USER }}
|
|
||||||
key: ${{ secrets.TESTING_SERVER_SSH_KEY }}
|
|
||||||
port: ${{ secrets.TESTING_SERVER_PORT || 22 }}
|
|
||||||
script: |
|
|
||||||
cd /opt/low-code-engine/testing-pr-${{ github.event.pull_request.number }}
|
|
||||||
|
|
||||||
# Stop and remove containers
|
|
||||||
docker-compose down -v || true
|
|
||||||
|
|
||||||
# Remove Docker image
|
|
||||||
docker rmi low-code-engine:testing-${{ github.event.pull_request.number }} || true
|
|
||||||
|
|
||||||
# Remove deployment directory
|
|
||||||
cd ..
|
|
||||||
rm -rf testing-pr-${{ github.event.pull_request.number }}
|
|
||||||
|
|
||||||
echo "✅ Cleanup completed for PR #${{ github.event.pull_request.number }}"
|
|
||||||
|
|
||||||
- name: Comment PR with cleanup info
|
|
||||||
uses: actions/github-script@v7
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const comment = `## 🧹 Testing Environment Cleaned Up
|
|
||||||
|
|
||||||
The testing deployment for this PR has been cleaned up:
|
|
||||||
- ✅ Docker containers stopped and removed
|
|
||||||
- ✅ Docker images cleaned up
|
|
||||||
- ✅ Server files removed
|
|
||||||
|
|
||||||
Thank you for testing! 🎉
|
|
||||||
`;
|
|
||||||
|
|
||||||
github.rest.issues.createComment({
|
|
||||||
issue_number: context.payload.pull_request.number,
|
|
||||||
owner: context.repo.owner,
|
|
||||||
repo: context.repo.repo,
|
|
||||||
body: comment
|
|
||||||
});
|
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
name: Test Runner
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- develop
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
hello-world:
|
|
||||||
runs-on: [ubuntu-latest]
|
|
||||||
steps:
|
|
||||||
- name: Test multiple commands
|
|
||||||
run: |
|
|
||||||
echo "Step 1 complete ✅"
|
|
||||||
echo "Step 2 complete ✅"
|
|
||||||
echo "All good!"
|
|
||||||
echo "Tests passed! 🎉"
|
|
||||||
209
DEPLOYMENT.md
209
DEPLOYMENT.md
@ -1,209 +0,0 @@
|
|||||||
# GitHub Actions Deployment Setup
|
|
||||||
|
|
||||||
This document describes the setup for automatic deployment to a testing server when creating a Pull Request to the `develop` branch.
|
|
||||||
|
|
||||||
## Required GitHub Secrets
|
|
||||||
|
|
||||||
Go to repository settings → Settings → Secrets and variables → Actions and add the following secrets:
|
|
||||||
|
|
||||||
### SSH Connection
|
|
||||||
|
|
||||||
- `TESTING_SERVER_HOST` - IP address or domain of the testing server
|
|
||||||
- `TESTING_SERVER_USER` - User for SSH connection (e.g., `deploy`)
|
|
||||||
- `TESTING_SERVER_SSH_KEY` - Private SSH key for server connection
|
|
||||||
- `TESTING_SERVER_PORT` - (optional) SSH port (default: 22)
|
|
||||||
|
|
||||||
### Database Configuration
|
|
||||||
|
|
||||||
- `TESTING_DB_ROOT_PASSWORD` - Root password for MariaDB
|
|
||||||
- `TESTING_DB_USERNAME` - Database user
|
|
||||||
- `TESTING_DB_PASSWORD` - Database user password
|
|
||||||
|
|
||||||
## Required GitHub Variables
|
|
||||||
|
|
||||||
Go to repository settings → Settings → Secrets and variables → Actions → Variables and add:
|
|
||||||
|
|
||||||
- `TESTING_BASE_PORT` - Base port for applications (default: 3000)
|
|
||||||
- `TESTING_BASE_DB_PORT` - Base port for databases (default: 3306)
|
|
||||||
- `TESTING_BASE_REDIS_PORT` - Base port for Redis (default: 6379)
|
|
||||||
|
|
||||||
## Testing Server Setup
|
|
||||||
|
|
||||||
### 1. Installing Docker and Docker Compose
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# System update
|
|
||||||
sudo apt update && sudo apt upgrade -y
|
|
||||||
|
|
||||||
# Docker installation
|
|
||||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
||||||
sudo sh get-docker.sh
|
|
||||||
|
|
||||||
# Add user to docker group
|
|
||||||
sudo usermod -aG docker $USER
|
|
||||||
|
|
||||||
# Install Docker Compose
|
|
||||||
sudo apt install docker-compose-plugin -y
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Creating deployment user
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create user
|
|
||||||
sudo useradd -m -s /bin/bash deploy
|
|
||||||
sudo usermod -aG docker deploy
|
|
||||||
|
|
||||||
# Create SSH keys directory
|
|
||||||
sudo mkdir -p /home/deploy/.ssh
|
|
||||||
sudo chmod 700 /home/deploy/.ssh
|
|
||||||
|
|
||||||
# Add public SSH key
|
|
||||||
sudo nano /home/deploy/.ssh/authorized_keys
|
|
||||||
# Insert public key corresponding to private key in TESTING_SERVER_SSH_KEY
|
|
||||||
|
|
||||||
sudo chmod 600 /home/deploy/.ssh/authorized_keys
|
|
||||||
sudo chown -R deploy:deploy /home/deploy/.ssh
|
|
||||||
|
|
||||||
# Create applications directory
|
|
||||||
sudo mkdir -p /opt/low-code-engine
|
|
||||||
sudo chown deploy:deploy /opt/low-code-engine
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Nginx Setup (Optional)
|
|
||||||
|
|
||||||
If you want to use domain names instead of ports:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo apt install nginx -y
|
|
||||||
|
|
||||||
# Create configuration for testing applications
|
|
||||||
sudo nano /etc/nginx/sites-available/testing-apps
|
|
||||||
```
|
|
||||||
|
|
||||||
File content:
|
|
||||||
|
|
||||||
```nginx
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name ~^pr-(?<pr_number>\d+)\.testing\.yourdomain\.com$;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
set $app_port 3000$pr_number;
|
|
||||||
proxy_pass http://127.0.0.1:$app_port;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Activate configuration
|
|
||||||
sudo ln -s /etc/nginx/sites-available/testing-apps /etc/nginx/sites-enabled/
|
|
||||||
sudo nginx -t
|
|
||||||
sudo systemctl reload nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
## How Deployment Works
|
|
||||||
|
|
||||||
### Deployment Process
|
|
||||||
|
|
||||||
1. **Trigger**: Creating or updating Pull Request to `develop` branch
|
|
||||||
2. **Build**: Building application and creating Docker image
|
|
||||||
3. **Deploy**: Copying files to server and starting containers
|
|
||||||
4. **Health Check**: Checking application availability
|
|
||||||
5. **Comment**: Adding comment to PR with deployment information
|
|
||||||
|
|
||||||
### Server Structure
|
|
||||||
|
|
||||||
```
|
|
||||||
/opt/low-code-engine/
|
|
||||||
├── testing-pr-123/ # Separate directory for each PR
|
|
||||||
│ ├── docker-compose.yml # Main docker-compose file
|
|
||||||
│ ├── docker-compose.override.yml # Testing overrides
|
|
||||||
│ ├── .env # Environment variables
|
|
||||||
│ ├── docker/ # Docker configurations
|
|
||||||
│ └── low-code-engine-testing.tar.gz # Docker image
|
|
||||||
├── testing-pr-124/
|
|
||||||
└── ...
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ports
|
|
||||||
|
|
||||||
Each PR is assigned unique ports:
|
|
||||||
|
|
||||||
- Application: `TESTING_BASE_PORT + PR_NUMBER` (e.g., 3000 + 123 = 3123)
|
|
||||||
- Database: `TESTING_BASE_DB_PORT + PR_NUMBER` (e.g., 3306 + 123 = 3429)
|
|
||||||
- Redis: `TESTING_BASE_REDIS_PORT + PR_NUMBER` (e.g., 6379 + 123 = 6502)
|
|
||||||
|
|
||||||
### Cleanup
|
|
||||||
|
|
||||||
When PR is closed or merged, automatically:
|
|
||||||
|
|
||||||
1. Stop and remove containers
|
|
||||||
2. Remove Docker images
|
|
||||||
3. Remove files on server
|
|
||||||
4. Add cleanup comment
|
|
||||||
|
|
||||||
## Security
|
|
||||||
|
|
||||||
1. **SSH Keys**: Use separate SSH key only for deployment
|
|
||||||
2. **User**: Create separate user with minimal privileges
|
|
||||||
3. **Firewall**: Configure firewall to restrict port access
|
|
||||||
4. **SSL/TLS**: Consider using SSL certificates for HTTPS
|
|
||||||
|
|
||||||
## Monitoring and Logs
|
|
||||||
|
|
||||||
### View Application Logs
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd /opt/low-code-engine/testing-pr-{PR_NUMBER}
|
|
||||||
docker-compose logs -f app
|
|
||||||
```
|
|
||||||
|
|
||||||
### View Container Status
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose ps
|
|
||||||
```
|
|
||||||
|
|
||||||
### Resource Monitoring
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker stats
|
|
||||||
```
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Port Issues
|
|
||||||
|
|
||||||
If port is occupied, check which applications are using it:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo netstat -tulpn | grep :{PORT}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Docker Issues
|
|
||||||
|
|
||||||
Clean up unused resources:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker system prune -f
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Issues
|
|
||||||
|
|
||||||
Check database connection:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose exec mariadb mysql -u root -p -e "SHOW DATABASES;"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Migration Issues
|
|
||||||
|
|
||||||
Manual migration run:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose exec app yarn migration:run
|
|
||||||
```
|
|
||||||
@ -34,36 +34,28 @@ services:
|
|||||||
retries: 10
|
retries: 10
|
||||||
interval: 10s
|
interval: 10s
|
||||||
|
|
||||||
# NestJS Application
|
# Redis Cache
|
||||||
app:
|
redis:
|
||||||
build:
|
image: redis:7-alpine
|
||||||
context: .
|
container_name: low-code-engine-redis
|
||||||
dockerfile: Dockerfile
|
|
||||||
target: development
|
|
||||||
container_name: low-code-engine-app
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
|
||||||
NODE_ENV: ${NODE_ENV:-development}
|
|
||||||
DB_HOST: mariadb
|
|
||||||
DB_PORT: 3306
|
|
||||||
DB_USERNAME: ${DB_USERNAME:-app_user}
|
|
||||||
DB_PASSWORD: ${DB_PASSWORD:-app_password}
|
|
||||||
DB_DATABASE: ${DB_DATABASE:-low_code_engine}
|
|
||||||
ports:
|
ports:
|
||||||
- "${APP_PORT:-3000}:3000"
|
- "${REDIS_PORT:-6379}:6379"
|
||||||
volumes:
|
volumes:
|
||||||
- .:/usr/src/app
|
- redis_data:/data
|
||||||
- /usr/src/app/node_modules
|
|
||||||
networks:
|
networks:
|
||||||
- app-network
|
- app-network
|
||||||
depends_on:
|
healthcheck:
|
||||||
mariadb:
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
condition: service_healthy
|
timeout: 5s
|
||||||
command: yarn start:dev
|
retries: 10
|
||||||
|
interval: 10s
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
mariadb_data:
|
mariadb_data:
|
||||||
driver: local
|
driver: local
|
||||||
|
redis_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
app-network:
|
app-network:
|
||||||
|
|||||||
37
scripts/setup-docker.sh
Normal file
37
scripts/setup-docker.sh
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "📦 Updating system packages..."
|
||||||
|
apt update -y
|
||||||
|
apt upgrade -y
|
||||||
|
|
||||||
|
echo "🔧 Installing dependencies..."
|
||||||
|
apt install -y apt-transport-https ca-certificates curl gnupg lsb-release
|
||||||
|
|
||||||
|
echo "🔑 Adding Docker’s official GPG key..."
|
||||||
|
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||||
|
|
||||||
|
echo "📂 Adding Docker repository..."
|
||||||
|
echo \
|
||||||
|
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
|
||||||
|
https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
|
||||||
|
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||||
|
|
||||||
|
echo "📦 Installing Docker Engine and Compose..."
|
||||||
|
apt update -y
|
||||||
|
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||||
|
|
||||||
|
echo "⚙️ Enabling and starting Docker service..."
|
||||||
|
systemctl enable docker
|
||||||
|
systemctl start docker
|
||||||
|
|
||||||
|
echo "👤 Adding current user to docker group..."
|
||||||
|
usermod -aG docker $USER
|
||||||
|
|
||||||
|
echo "✅ Docker and Docker Compose installation complete!"
|
||||||
|
echo "➡️ Log out and log back in (or run 'newgrp docker') to use Docker without sudo."
|
||||||
|
echo
|
||||||
|
echo "💡 Docker version:"
|
||||||
|
docker --version || echo "Docker not yet available in current shell"
|
||||||
|
echo "💡 Docker Compose version:"
|
||||||
|
docker compose version || echo "Docker Compose not yet available in current shell"
|
||||||
@ -1,293 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Quick setup script for testing server
|
|
||||||
# Run this script on your testing server to set up the environment
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🚀 Setting up testing server for Low Code Engine deployments..."
|
|
||||||
|
|
||||||
# Colors for output
|
|
||||||
RED='\033[0;31m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
# Function to print colored output
|
|
||||||
print_status() {
|
|
||||||
echo -e "${GREEN}[INFO]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_warning() {
|
|
||||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
print_error() {
|
|
||||||
echo -e "${RED}[ERROR]${NC} $1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if running as root
|
|
||||||
if [[ $EUID -eq 0 ]]; then
|
|
||||||
print_error "This script should not be run as root for security reasons"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Update system
|
|
||||||
print_status "Updating system packages..."
|
|
||||||
sudo apt update && sudo apt upgrade -y
|
|
||||||
|
|
||||||
# Install Docker
|
|
||||||
print_status "Installing Docker..."
|
|
||||||
if ! command -v docker &> /dev/null; then
|
|
||||||
curl -fsSL https://get.docker.com -o get-docker.sh
|
|
||||||
sudo sh get-docker.sh
|
|
||||||
sudo usermod -aG docker $USER
|
|
||||||
rm get-docker.sh
|
|
||||||
print_status "Docker installed successfully"
|
|
||||||
else
|
|
||||||
print_status "Docker is already installed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Install Docker Compose
|
|
||||||
print_status "Installing Docker Compose..."
|
|
||||||
if ! command -v docker-compose &> /dev/null; then
|
|
||||||
sudo apt install docker-compose-plugin -y
|
|
||||||
print_status "Docker Compose installed successfully"
|
|
||||||
else
|
|
||||||
print_status "Docker Compose is already installed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create deploy user
|
|
||||||
print_status "Creating deploy user..."
|
|
||||||
if ! id "deploy" &>/dev/null; then
|
|
||||||
sudo useradd -m -s /bin/bash deploy
|
|
||||||
sudo usermod -aG docker deploy
|
|
||||||
print_status "Deploy user created successfully"
|
|
||||||
else
|
|
||||||
print_status "Deploy user already exists"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setup SSH directory for deploy user
|
|
||||||
print_status "Setting up SSH for deploy user..."
|
|
||||||
sudo mkdir -p /home/deploy/.ssh
|
|
||||||
sudo chmod 700 /home/deploy/.ssh
|
|
||||||
sudo touch /home/deploy/.ssh/authorized_keys
|
|
||||||
sudo chmod 600 /home/deploy/.ssh/authorized_keys
|
|
||||||
sudo chown -R deploy:deploy /home/deploy/.ssh
|
|
||||||
|
|
||||||
# Create application directory
|
|
||||||
print_status "Creating application directory..."
|
|
||||||
sudo mkdir -p /opt/low-code-engine
|
|
||||||
sudo chown deploy:deploy /opt/low-code-engine
|
|
||||||
|
|
||||||
# Install nginx (optional)
|
|
||||||
print_status "Installing Nginx..."
|
|
||||||
if ! command -v nginx &> /dev/null; then
|
|
||||||
sudo apt install nginx -y
|
|
||||||
print_status "Nginx installed successfully"
|
|
||||||
else
|
|
||||||
print_status "Nginx is already installed"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create nginx configuration for testing apps
|
|
||||||
print_status "Creating Nginx configuration..."
|
|
||||||
sudo tee /etc/nginx/sites-available/testing-apps > /dev/null <<EOF
|
|
||||||
# Configuration for testing deployments
|
|
||||||
# This allows access via pr-123.testing.yourdomain.com
|
|
||||||
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name ~^pr-(?<pr_number>\d+)\.testing\.(.+)$;
|
|
||||||
|
|
||||||
# Health check endpoint
|
|
||||||
location /health {
|
|
||||||
set \$app_port 3000\$pr_number;
|
|
||||||
proxy_pass http://127.0.0.1:\$app_port;
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
|
|
||||||
# Add CORS headers for API calls
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
|
|
||||||
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization' always;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Main application
|
|
||||||
location / {
|
|
||||||
set \$app_port 3000\$pr_number;
|
|
||||||
proxy_pass http://127.0.0.1:\$app_port;
|
|
||||||
proxy_set_header Host \$host;
|
|
||||||
proxy_set_header X-Real-IP \$remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
|
||||||
|
|
||||||
# WebSocket support
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade \$http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
|
|
||||||
# Timeouts
|
|
||||||
proxy_connect_timeout 60s;
|
|
||||||
proxy_send_timeout 60s;
|
|
||||||
proxy_read_timeout 60s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Direct port access (fallback)
|
|
||||||
server {
|
|
||||||
listen 80 default_server;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
return 200 'Testing Server is running. Use pr-{NUMBER}.testing.yourdomain.com to access deployments.';
|
|
||||||
add_header Content-Type text/plain;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Enable nginx configuration
|
|
||||||
if [ ! -L /etc/nginx/sites-enabled/testing-apps ]; then
|
|
||||||
sudo ln -s /etc/nginx/sites-available/testing-apps /etc/nginx/sites-enabled/
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove default nginx site
|
|
||||||
if [ -L /etc/nginx/sites-enabled/default ]; then
|
|
||||||
sudo rm /etc/nginx/sites-enabled/default
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Test and reload nginx
|
|
||||||
sudo nginx -t && sudo systemctl reload nginx
|
|
||||||
print_status "Nginx configured successfully"
|
|
||||||
|
|
||||||
# Install useful tools
|
|
||||||
print_status "Installing additional tools..."
|
|
||||||
sudo apt install -y curl wget htop netstat-nat jq
|
|
||||||
|
|
||||||
# Create cleanup script
|
|
||||||
print_status "Creating cleanup script..."
|
|
||||||
sudo tee /usr/local/bin/cleanup-old-deployments > /dev/null <<'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
# Cleanup script for old testing deployments
|
|
||||||
|
|
||||||
DAYS_OLD=7
|
|
||||||
DEPLOYMENT_DIR="/opt/low-code-engine"
|
|
||||||
|
|
||||||
echo "Cleaning up deployments older than ${DAYS_OLD} days..."
|
|
||||||
|
|
||||||
find ${DEPLOYMENT_DIR} -name "testing-pr-*" -type d -mtime +${DAYS_OLD} | while read dir; do
|
|
||||||
echo "Cleaning up: $dir"
|
|
||||||
|
|
||||||
# Stop containers if running
|
|
||||||
if [ -f "$dir/docker-compose.yml" ]; then
|
|
||||||
cd "$dir"
|
|
||||||
docker-compose down -v 2>/dev/null || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Remove directory
|
|
||||||
rm -rf "$dir"
|
|
||||||
echo "Removed: $dir"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Clean up unused Docker resources
|
|
||||||
docker system prune -f
|
|
||||||
docker image prune -f
|
|
||||||
|
|
||||||
echo "Cleanup completed"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo chmod +x /usr/local/bin/cleanup-old-deployments
|
|
||||||
|
|
||||||
# Create cron job for cleanup
|
|
||||||
print_status "Setting up automatic cleanup..."
|
|
||||||
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/cleanup-old-deployments") | crontab -
|
|
||||||
|
|
||||||
# Create monitoring script
|
|
||||||
print_status "Creating monitoring script..."
|
|
||||||
sudo tee /usr/local/bin/monitor-deployments > /dev/null <<'EOF'
|
|
||||||
#!/bin/bash
|
|
||||||
# Monitoring script for testing deployments
|
|
||||||
|
|
||||||
DEPLOYMENT_DIR="/opt/low-code-engine"
|
|
||||||
|
|
||||||
echo "=== Testing Deployments Status ==="
|
|
||||||
echo "Date: $(date)"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Show active deployments
|
|
||||||
echo "Active Deployments:"
|
|
||||||
find ${DEPLOYMENT_DIR} -name "testing-pr-*" -type d | sort | while read dir; do
|
|
||||||
pr_number=$(basename "$dir" | sed 's/testing-pr-//')
|
|
||||||
if [ -f "$dir/docker-compose.yml" ]; then
|
|
||||||
cd "$dir"
|
|
||||||
status=$(docker-compose ps -q | wc -l)
|
|
||||||
if [ "$status" -gt 0 ]; then
|
|
||||||
app_port=$((3000 + pr_number))
|
|
||||||
echo " PR #${pr_number}: Running on port ${app_port}"
|
|
||||||
# Check if app is responding
|
|
||||||
if curl -s --max-time 5 "http://localhost:${app_port}/health" > /dev/null 2>&1; then
|
|
||||||
echo " Status: ✅ Healthy"
|
|
||||||
else
|
|
||||||
echo " Status: ❌ Unhealthy"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " PR #${pr_number}: Stopped"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "=== System Resources ==="
|
|
||||||
echo "Disk Usage:"
|
|
||||||
df -h /opt/low-code-engine
|
|
||||||
echo
|
|
||||||
echo "Docker Usage:"
|
|
||||||
docker system df
|
|
||||||
echo
|
|
||||||
echo "Memory Usage:"
|
|
||||||
free -h
|
|
||||||
EOF
|
|
||||||
|
|
||||||
sudo chmod +x /usr/local/bin/monitor-deployments
|
|
||||||
|
|
||||||
# Setup firewall (optional but recommended)
|
|
||||||
print_status "Configuring firewall..."
|
|
||||||
if command -v ufw &> /dev/null; then
|
|
||||||
sudo ufw --force enable
|
|
||||||
sudo ufw allow ssh
|
|
||||||
sudo ufw allow 80/tcp
|
|
||||||
sudo ufw allow 443/tcp
|
|
||||||
# Allow port range for testing apps (3000-3999)
|
|
||||||
sudo ufw allow 3000:3999/tcp
|
|
||||||
# Allow port range for databases (3300-3999)
|
|
||||||
sudo ufw allow 3300:3999/tcp
|
|
||||||
# Allow port range for redis (6300-6999)
|
|
||||||
sudo ufw allow 6300:6999/tcp
|
|
||||||
print_status "Firewall configured"
|
|
||||||
else
|
|
||||||
print_warning "UFW not found, skipping firewall configuration"
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_status "Setup completed successfully!"
|
|
||||||
echo
|
|
||||||
echo "🎉 Your testing server is ready!"
|
|
||||||
echo
|
|
||||||
echo "Next steps:"
|
|
||||||
echo "1. Add your public SSH key to /home/deploy/.ssh/authorized_keys"
|
|
||||||
echo "2. Configure your GitHub repository secrets:"
|
|
||||||
echo " - TESTING_SERVER_HOST: $(curl -s ifconfig.me 2>/dev/null || echo 'YOUR_SERVER_IP')"
|
|
||||||
echo " - TESTING_SERVER_USER: deploy"
|
|
||||||
echo " - TESTING_SERVER_SSH_KEY: (your private SSH key)"
|
|
||||||
echo " - TESTING_DB_ROOT_PASSWORD: (choose a strong password)"
|
|
||||||
echo " - TESTING_DB_USERNAME: app_user"
|
|
||||||
echo " - TESTING_DB_PASSWORD: (choose a strong password)"
|
|
||||||
echo
|
|
||||||
echo "Useful commands:"
|
|
||||||
echo " - Monitor deployments: sudo /usr/local/bin/monitor-deployments"
|
|
||||||
echo " - Cleanup old deployments: sudo /usr/local/bin/cleanup-old-deployments"
|
|
||||||
echo " - Check nginx status: sudo systemctl status nginx"
|
|
||||||
echo " - View nginx logs: sudo journalctl -u nginx -f"
|
|
||||||
echo
|
|
||||||
print_warning "Please reboot the server or run 'newgrp docker' to apply Docker group changes"
|
|
||||||
EOF
|
|
||||||
Reference in New Issue
Block a user