feat: skill expansion — browser, security, SQL, files (16 skills total)
Novas skills instaladas: - openclaw-agent-browser v1.0.0 CLI Chromium — navegação, login, screenshots, state - skill-security-audit v1.0.0 SAST scanning, prompt injection, secrets audit - sql-toolkit v1.0.0 PostgreSQL/MySQL/SQLite — schema, query, otimização - file v1.0.0 Organização de arquivos por contexto - file-summary v1.0.0 Extração e resumo de PDFs, Word, Excel Workspace expandido: - TOOLS.md: +Browser automation, Security audit, SQL, File management - AGENTS.md: +Linux Analyst section (comandos, logs, rede, scripts) + Full-stack strategy - MEMORY.md: 16 skills indexadas, stack map, comandos Linux ref - SESSION-STATE.md: atualizado com contexto completo - lock.json: sincronizado com 16 skills instaladas
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
# Scenario: Build-from-Source Apps
|
||||
|
||||
## Detection
|
||||
|
||||
This scenario applies when `docker-compose.yml` contains a `build:` directive:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: my-app:latest # local tag — not a public registry
|
||||
```
|
||||
|
||||
## Solution Overview
|
||||
|
||||
1. Set up GitHub Actions to build the image and push to GHCR on every push to `main`
|
||||
2. Replace `build:` with `image: ghcr.io/OWNER/REPO:latest` in the compose
|
||||
3. xCloud pulls the pre-built image automatically on each deploy
|
||||
|
||||
## Step 1 — Modify docker-compose.yml
|
||||
|
||||
Remove the `build:` block, replace `image:` with the GHCR reference:
|
||||
|
||||
```yaml
|
||||
# BEFORE
|
||||
services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: my-app:latest
|
||||
|
||||
# AFTER
|
||||
services:
|
||||
app:
|
||||
image: ghcr.io/OWNER/REPO:latest
|
||||
# build: removed
|
||||
```
|
||||
|
||||
Replace `OWNER` with the GitHub username/org, `REPO` with the repository name.
|
||||
|
||||
## Step 2 — Generate GitHub Actions Workflow
|
||||
|
||||
Use the template at `assets/github-actions-build.yml`. Replace placeholders:
|
||||
- `IMAGE_NAME` — repository name (lowercase, e.g., `vidify-app`)
|
||||
- `REGISTRY` — `ghcr.io`
|
||||
|
||||
The workflow:
|
||||
- Triggers on push to `main`
|
||||
- Builds the Docker image from `Dockerfile`
|
||||
- Tags as `ghcr.io/OWNER/REPO:latest` and `ghcr.io/OWNER/REPO:sha-XXXXXX`
|
||||
- Pushes to GHCR using `GITHUB_TOKEN` (no extra secrets needed for public repos)
|
||||
|
||||
Save to `.github/workflows/docker-build.yml`.
|
||||
|
||||
## Step 3 — Make GHCR Image Public
|
||||
|
||||
After first push:
|
||||
1. Go to `github.com/OWNER/REPO` → Packages
|
||||
2. Find the package → Settings → Change visibility to **Public**
|
||||
|
||||
Or configure in `docker-build.yml` using `packages: write` permission (already in template).
|
||||
|
||||
## Step 4 — xCloud Webhook for Auto-Deploy
|
||||
|
||||
After GHCR push, trigger xCloud to redeploy. Add this step to the GitHub Actions workflow:
|
||||
|
||||
```yaml
|
||||
- name: Trigger xCloud deploy
|
||||
run: |
|
||||
curl -X POST "${{ secrets.XCLOUD_DEPLOY_WEBHOOK }}" \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
Get the webhook URL from xCloud site settings → Git Deploy → Webhook URL.
|
||||
Add it as a GitHub secret `XCLOUD_DEPLOY_WEBHOOK`.
|
||||
|
||||
## Step 5 — .env.example
|
||||
|
||||
Extract all `${VAR_NAME}` references from the compose and generate a `.env.example`:
|
||||
|
||||
```bash
|
||||
# Auto-extract env vars from docker-compose.yml
|
||||
grep -oP '\$\{\K[^}]+' docker-compose.yml | sort -u | sed 's/^/# /; s/$/=/' > .env.example
|
||||
```
|
||||
|
||||
## Multiple Services with build:
|
||||
|
||||
If multiple services have `build:` directives, each needs its own image and GitHub Actions job:
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build-app:
|
||||
# builds ghcr.io/owner/repo-app:latest
|
||||
build-worker:
|
||||
# builds ghcr.io/owner/repo-worker:latest
|
||||
```
|
||||
|
||||
Or use a matrix strategy (see template).
|
||||
@@ -0,0 +1,141 @@
|
||||
# Scenario C: Multi-Service Build
|
||||
|
||||
## Detection
|
||||
|
||||
This scenario applies when **two or more services** in `docker-compose.yml` have `build:` directives:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
frontend:
|
||||
build: ./frontend
|
||||
backend:
|
||||
build: ./backend
|
||||
worker:
|
||||
build: ./worker
|
||||
```
|
||||
|
||||
## Solution Overview
|
||||
|
||||
Each service needs its own image in GHCR. Use a GitHub Actions **matrix strategy** to build all images in parallel, then reference each in the compose file.
|
||||
|
||||
## Step 1 — Assign GHCR Image Names
|
||||
|
||||
For each service with `build:`, assign a GHCR image path:
|
||||
|
||||
| Service | GHCR Image |
|
||||
|---------|-----------|
|
||||
| frontend | `ghcr.io/OWNER/REPO/frontend:latest` |
|
||||
| backend | `ghcr.io/OWNER/REPO/backend:latest` |
|
||||
| worker | `ghcr.io/OWNER/REPO/worker:latest` |
|
||||
|
||||
## Step 2 — Modified docker-compose.yml
|
||||
|
||||
```yaml
|
||||
services:
|
||||
frontend:
|
||||
image: ghcr.io/OWNER/REPO/frontend:latest
|
||||
# build: removed
|
||||
ports:
|
||||
- "3080:3000"
|
||||
environment:
|
||||
- BACKEND_URL=${BACKEND_URL}
|
||||
|
||||
backend:
|
||||
image: ghcr.io/OWNER/REPO/backend:latest
|
||||
# build: removed
|
||||
expose:
|
||||
- "8000"
|
||||
environment:
|
||||
- DATABASE_URL=${DATABASE_URL}
|
||||
|
||||
worker:
|
||||
image: ghcr.io/OWNER/REPO/worker:latest
|
||||
# build: removed
|
||||
environment:
|
||||
- REDIS_URL=${REDIS_URL}
|
||||
|
||||
db:
|
||||
image: postgres:15-alpine # ← unchanged, already public image
|
||||
expose:
|
||||
- "5432"
|
||||
environment:
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
|
||||
```
|
||||
|
||||
## Step 3 — GitHub Actions Matrix Workflow
|
||||
|
||||
```yaml
|
||||
name: Build and Push Docker Images
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
REPO: ${{ github.event.repository.name }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
service: [frontend, backend, worker]
|
||||
include:
|
||||
- service: frontend
|
||||
context: ./frontend
|
||||
dockerfile: ./frontend/Dockerfile
|
||||
- service: backend
|
||||
context: ./backend
|
||||
dockerfile: ./backend/Dockerfile
|
||||
- service: worker
|
||||
context: ./worker
|
||||
dockerfile: ./worker/Dockerfile
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to GHCR
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push ${{ matrix.service }}
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: ${{ matrix.context }}
|
||||
file: ${{ matrix.dockerfile }}
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/${{ matrix.service }}:latest
|
||||
${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.REPO }}/${{ matrix.service }}:sha-${{ github.sha }}
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger xCloud deploy
|
||||
if: ${{ secrets.XCLOUD_DEPLOY_WEBHOOK != '' }}
|
||||
run: |
|
||||
curl -X POST "${{ secrets.XCLOUD_DEPLOY_WEBHOOK }}" \
|
||||
-H "Content-Type: application/json"
|
||||
```
|
||||
|
||||
## Step 4 — Make GHCR Images Public
|
||||
|
||||
After first push, for each image:
|
||||
1. Go to `github.com/OWNER/REPO` → Packages
|
||||
2. Find each package → Settings → Change visibility to **Public**
|
||||
|
||||
## xCloud Configuration
|
||||
|
||||
- **Exposed port:** The single port the frontend/nginx-router exposes (e.g., `3080`)
|
||||
- All env vars added via xCloud UI
|
||||
- No special config needed — xCloud pulls all GHCR images on deploy
|
||||
@@ -0,0 +1,155 @@
|
||||
# Scenario: Proxy/SSL Conflict & Multi-Port Apps
|
||||
|
||||
## Detection
|
||||
|
||||
This scenario applies when `docker-compose.yml` contains any of:
|
||||
- A Caddy, Traefik, nginx-proxy, or similar reverse-proxy service
|
||||
- Multiple exposed ports (e.g., `3001` for API, `3002` for frontend)
|
||||
- External config files referenced via volume mounts (e.g., `./nginx.conf:/etc/nginx/nginx.conf`)
|
||||
- SSL/TLS config (certresolver, Let's Encrypt, ACME)
|
||||
|
||||
**Real example — Rybbit Analytics:**
|
||||
```yaml
|
||||
services:
|
||||
caddy: # ← conflicts with xCloud's nginx
|
||||
image: caddy
|
||||
ports: ["80:80", "443:443"]
|
||||
clickhouse: ...
|
||||
backend:
|
||||
ports: ["3001:3001"] # ← multiple ports
|
||||
frontend:
|
||||
ports: ["3002:3002"] # ← multiple ports
|
||||
```
|
||||
|
||||
## Solution Overview
|
||||
|
||||
1. Remove the proxy/SSL service (Caddy/Traefik/nginx-proxy)
|
||||
2. Remove SSL-related labels and config
|
||||
3. Add a lightweight `nginx-router` service that routes internal traffic
|
||||
4. Embed the nginx config inline using the `configs:` block (no external files)
|
||||
5. Expose a single port (e.g., `3080`) for xCloud to proxy to
|
||||
|
||||
## Architecture After Fix
|
||||
|
||||
```
|
||||
xCloud Nginx (443) → nginx-router:3080 → backend:3001 (API)
|
||||
→ frontend:3002 (UI)
|
||||
```
|
||||
|
||||
## Step 1 — Remove Proxy Service
|
||||
|
||||
Delete the entire Caddy/Traefik/nginx-proxy service block.
|
||||
Remove any `labels:` containing `traefik.*` or Caddy directives from other services.
|
||||
Remove port mappings `"80:80"` and `"443:443"`.
|
||||
|
||||
## Step 2 — Remove External Port Mappings from App Services
|
||||
|
||||
Backend and frontend services should NOT expose ports directly to the host.
|
||||
Remove their `ports:` sections — they communicate internally via Docker network.
|
||||
|
||||
```yaml
|
||||
# BEFORE
|
||||
backend:
|
||||
ports:
|
||||
- "3001:3001"
|
||||
|
||||
# AFTER
|
||||
backend:
|
||||
expose:
|
||||
- "3001" # internal only — accessible within Docker network
|
||||
```
|
||||
|
||||
## Step 3 — Add nginx-router Service with Embedded Config
|
||||
|
||||
Use the `configs:` top-level block to embed nginx config inline:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
nginx-router:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "3080:80" # ← single port xCloud proxies to
|
||||
configs:
|
||||
- source: nginx_config
|
||||
target: /etc/nginx/conf.d/default.conf
|
||||
depends_on:
|
||||
- backend
|
||||
- frontend
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
configs:
|
||||
nginx_config:
|
||||
content: |
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend:3001/;
|
||||
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;
|
||||
}
|
||||
|
||||
location / {
|
||||
proxy_pass http://frontend:3002/;
|
||||
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;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The `configs:` inline `content:` feature requires Docker Compose v2.23+ / Docker Engine 25+. For older versions, use a heredoc in a startup command instead (see below).
|
||||
|
||||
## Alternative: Inline Config via Command
|
||||
|
||||
If `configs.content` is not supported:
|
||||
|
||||
```yaml
|
||||
nginx-router:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "3080:80"
|
||||
command: >
|
||||
sh -c "echo 'server {
|
||||
listen 80;
|
||||
location /api/ { proxy_pass http://backend:3001/; }
|
||||
location / { proxy_pass http://frontend:3002/; }
|
||||
}' > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
|
||||
```
|
||||
|
||||
## Step 4 — Ensure Shared Network
|
||||
|
||||
All services must be on the same Docker network for internal routing:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
nginx-router:
|
||||
networks: [app-network]
|
||||
backend:
|
||||
networks: [app-network]
|
||||
frontend:
|
||||
networks: [app-network]
|
||||
|
||||
networks:
|
||||
app-network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
## Step 5 — xCloud Configuration
|
||||
|
||||
- **Exposed port:** `3080` (or whatever single port you chose)
|
||||
- **No SSL config needed** — xCloud handles it
|
||||
- All env vars added via xCloud UI
|
||||
|
||||
## Common Routing Patterns
|
||||
|
||||
| App type | Route pattern |
|
||||
|----------|--------------|
|
||||
| API + SPA | `/api/* → backend`, `/* → frontend` |
|
||||
| API + SSR | `/api/* → api-service`, `/* → web-service` |
|
||||
| Multiple APIs | `/api/v1/* → service-a`, `/api/v2/* → service-b` |
|
||||
| WebSocket | Add `proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";` |
|
||||
@@ -0,0 +1,56 @@
|
||||
# xCloud Docker Deployment — Constraints & Architecture
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Internet → Cloudflare → xCloud Nginx (port 443, SSL) → Docker container (single exposed port)
|
||||
```
|
||||
|
||||
xCloud manages:
|
||||
- SSL/TLS termination (via Let's Encrypt or Cloudflare)
|
||||
- Reverse proxy (nginx)
|
||||
- Domain routing
|
||||
|
||||
Your Docker stack must NOT include: Caddy, Traefik, nginx-proxy, or any SSL-terminating proxy.
|
||||
|
||||
## xCloud Git Deployment Behavior
|
||||
|
||||
When you push to git, xCloud runs:
|
||||
```bash
|
||||
git pull
|
||||
docker-compose pull # pulls images from registry — does NOT build
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
**Critical:** xCloud never runs `docker build`. Images must be pre-built and available in a public registry.
|
||||
|
||||
## docker-compose.yml Constraints
|
||||
|
||||
| Rule | Detail |
|
||||
|------|--------|
|
||||
| Single file only | No external `.conf`, `.env`, or override files at deploy time |
|
||||
| Public images only | All `image:` must reference a public registry (`docker.io`, `ghcr.io`, etc.) |
|
||||
| No `build:` directives | Will be silently ignored or fail |
|
||||
| Single exposed port | One port proxied by xCloud's nginx |
|
||||
| Env vars via UI | Set in xCloud dashboard, not in compose |
|
||||
| Volume paths | Use relative paths; xCloud sets working directory to repo root |
|
||||
|
||||
## Deployment Steps in xCloud
|
||||
|
||||
1. Server → New Site → Custom Docker
|
||||
2. Connect git repo (GitHub/GitLab/Bitbucket)
|
||||
3. Paste `docker-compose.yml` or point to repo file
|
||||
4. Set exposed port (the port xCloud proxies to)
|
||||
5. Add env vars in xCloud UI
|
||||
6. Deploy
|
||||
|
||||
## Supported Public Registries
|
||||
|
||||
- `ghcr.io` (GitHub Container Registry) — free for public repos
|
||||
- `docker.io` / `hub.docker.com` — free for public images
|
||||
- `registry.gitlab.com` — GitLab registry
|
||||
- Any public registry URL
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Never hardcode secrets in `docker-compose.yml`. Use `${VAR_NAME}` syntax — xCloud injects them via the UI. Always provide a `.env.example` listing all required variables.
|
||||
@@ -0,0 +1,61 @@
|
||||
# xCloud Deployment Paths: Docker vs Native
|
||||
|
||||
## Two Paths Available
|
||||
|
||||
### Path 1 — xCloud Native (Git Push Deploy)
|
||||
|
||||
xCloud natively supports these stacks without Docker:
|
||||
- **WordPress** — managed WordPress hosting with auto-config
|
||||
- **Laravel** — PHP-FPM, Composer install, artisan commands
|
||||
- **PHP** — generic PHP apps (CodeIgniter, Symfony, etc.)
|
||||
- **Node.js** — npm/yarn install, process management
|
||||
|
||||
How it works:
|
||||
```
|
||||
git push → xCloud: git pull + composer install (or npm install) + reload
|
||||
```
|
||||
|
||||
Advantages:
|
||||
- Simpler setup — no Dockerfile needed
|
||||
- Faster deploys (no image build/pull)
|
||||
- xCloud manages PHP version, extensions, process manager
|
||||
- Direct file access via SFTP
|
||||
|
||||
When to choose Native:
|
||||
- Standard single-language app
|
||||
- Standard database (MySQL/MariaDB only)
|
||||
- No custom runtime dependencies
|
||||
|
||||
### Path 2 — Custom Docker Deploy
|
||||
|
||||
Use Docker when:
|
||||
- App requires non-standard runtime (Python, Go, Rust, Java)
|
||||
- Multiple services (API + queue worker + Redis)
|
||||
- Framework requires build step (Next.js, Nuxt.js, NestJS)
|
||||
- Custom dependencies not available via apt/pecl
|
||||
- Already containerized (existing docker-compose.yml)
|
||||
|
||||
How it works:
|
||||
```
|
||||
git push → xCloud: git pull + docker-compose pull + docker-compose up -d
|
||||
```
|
||||
|
||||
Constraints (see xcloud-constraints.md for full list):
|
||||
- No `build:` in compose — images must be pre-built in public registry
|
||||
- Single exposed port
|
||||
- No Caddy/Traefik/nginx-proxy (xCloud handles SSL + reverse proxy)
|
||||
|
||||
## Decision Matrix
|
||||
|
||||
| Stack | DB Needs | Background Jobs | Recommended Path |
|
||||
|---|---|---|---|
|
||||
| WordPress | MySQL only | No | Native |
|
||||
| Laravel | MySQL only | No | Native |
|
||||
| Laravel | MySQL + Redis + Queue workers | Yes | Docker |
|
||||
| PHP generic | MySQL only | No | Native |
|
||||
| Node.js (Express/Fastify) | Any | No | Native |
|
||||
| Next.js | Any | No | Docker |
|
||||
| NestJS | Any | Any | Docker |
|
||||
| Python (FastAPI/Django) | Any | Any | Docker |
|
||||
| Go / Rust / Java | Any | Any | Docker |
|
||||
| Multi-service app | Any | Any | Docker |
|
||||
@@ -0,0 +1,83 @@
|
||||
# xCloud Native Laravel Deployment
|
||||
|
||||
## Repository Setup (Required)
|
||||
|
||||
File structure xCloud expects:
|
||||
```
|
||||
your-repo/
|
||||
├── app/
|
||||
├── public/ ← web root
|
||||
├── storage/ ← must be writable
|
||||
├── bootstrap/
|
||||
├── config/
|
||||
├── routes/
|
||||
├── .env.example ← commit this
|
||||
├── composer.json
|
||||
├── artisan
|
||||
└── ...
|
||||
```
|
||||
|
||||
Critical: Never commit `.env`. Set all variables in xCloud UI.
|
||||
|
||||
.env.example (minimum required):
|
||||
```env
|
||||
APP_NAME=MyApp
|
||||
APP_ENV=production
|
||||
APP_KEY=
|
||||
APP_DEBUG=false
|
||||
APP_URL=https://yourdomain.com
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=
|
||||
DB_USERNAME=
|
||||
DB_PASSWORD=
|
||||
|
||||
CACHE_DRIVER=file
|
||||
QUEUE_CONNECTION=sync
|
||||
SESSION_DRIVER=file
|
||||
```
|
||||
|
||||
## xCloud UI Steps
|
||||
|
||||
1. Server → New Site → Laravel tab
|
||||
2. Connect Git repo (GitHub/GitLab/Bitbucket)
|
||||
3. Set branch (usually `main` or `master`)
|
||||
4. PHP version: select 8.2 or 8.3
|
||||
5. Add environment variables (from your .env.example)
|
||||
- Generate APP_KEY locally: `php artisan key:generate --show`
|
||||
6. Deploy hooks — add these commands in order:
|
||||
```bash
|
||||
composer install --no-dev --optimize-autoloader
|
||||
php artisan config:cache
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
php artisan migrate --force
|
||||
php artisan storage:link
|
||||
```
|
||||
7. Click Deploy
|
||||
|
||||
## Queue Workers (if using)
|
||||
|
||||
In xCloud site settings → Supervisor → Add worker:
|
||||
```
|
||||
php artisan queue:work --sleep=3 --tries=3 --max-time=3600
|
||||
```
|
||||
|
||||
## Scheduler (if using)
|
||||
|
||||
In xCloud site settings → Cron Jobs → Add:
|
||||
```
|
||||
* * * * * php artisan schedule:run >> /dev/null 2>&1
|
||||
```
|
||||
|
||||
## Common Issues
|
||||
|
||||
| Issue | Fix |
|
||||
|---|---|
|
||||
| 500 error after deploy | Check APP_KEY is set |
|
||||
| Assets not loading | Run `npm run build` locally, commit public/build/ |
|
||||
| Queue jobs not processing | Add supervisor worker |
|
||||
| Storage files missing | Ensure storage:link is in deploy hooks |
|
||||
| Migration errors | Check DB credentials, ensure --force flag |
|
||||
@@ -0,0 +1,48 @@
|
||||
# xCloud Native Node.js Deployment
|
||||
|
||||
## Repository Setup (Required)
|
||||
|
||||
package.json must have a `start` script:
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"build": "tsc -p tsconfig.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Port must use process.env.PORT:
|
||||
```javascript
|
||||
const port = process.env.PORT || 3000;
|
||||
app.listen(port, () => console.log(`Server running on port ${port}`));
|
||||
```
|
||||
|
||||
xCloud injects PORT automatically. Your app MUST listen on this port.
|
||||
|
||||
.env.example:
|
||||
```env
|
||||
NODE_ENV=production
|
||||
PORT=3000
|
||||
DATABASE_URL=
|
||||
JWT_SECRET=
|
||||
```
|
||||
|
||||
## xCloud UI Steps
|
||||
|
||||
1. Server → New Site → Node.js tab
|
||||
2. Connect Git repo
|
||||
3. Set branch
|
||||
4. Node.js version: 18, 20, or 22
|
||||
5. Start command: `npm start` (or `node server.js`)
|
||||
6. Build command (if TypeScript): `npm run build`
|
||||
7. Add environment variables
|
||||
8. Click Deploy
|
||||
|
||||
## Common Issues
|
||||
|
||||
| Issue | Fix |
|
||||
|---|---|
|
||||
| App crashes on start | Check PORT env var is used (not hardcoded) |
|
||||
| Module not found | Ensure node_modules is in .gitignore |
|
||||
| TypeScript errors | Add build script, set build command in xCloud |
|
||||
@@ -0,0 +1,44 @@
|
||||
# xCloud Native PHP Deployment
|
||||
|
||||
## Repository Setup
|
||||
|
||||
Web root: xCloud serves from `public/` by default.
|
||||
|
||||
Required files:
|
||||
```
|
||||
your-repo/
|
||||
├── public/
|
||||
│ └── index.php
|
||||
├── .env.example
|
||||
└── ...
|
||||
```
|
||||
|
||||
.env.example:
|
||||
```env
|
||||
APP_ENV=production
|
||||
DB_HOST=
|
||||
DB_DATABASE=
|
||||
DB_USERNAME=
|
||||
DB_PASSWORD=
|
||||
```
|
||||
|
||||
## xCloud UI Steps
|
||||
|
||||
1. Server → New Site → PHP tab
|
||||
2. Connect Git repo
|
||||
3. PHP version: 7.4, 8.0, 8.1, 8.2, or 8.3
|
||||
4. Web root: `public` (or `/` if serving from root)
|
||||
5. Add environment variables
|
||||
6. Deploy hooks (if using Composer):
|
||||
```bash
|
||||
composer install --no-dev --optimize-autoloader
|
||||
```
|
||||
7. Click Deploy
|
||||
|
||||
## Common Issues
|
||||
|
||||
| Issue | Fix |
|
||||
|---|---|
|
||||
| 403 Forbidden | Check web root config |
|
||||
| Missing extensions | Use Docker path for custom extensions |
|
||||
| Composer errors | Ensure composer.json is committed, vendor/ in .gitignore |
|
||||
@@ -0,0 +1,45 @@
|
||||
# xCloud Native WordPress Deployment
|
||||
|
||||
WordPress on xCloud is fully managed — no Docker needed.
|
||||
|
||||
## Method 1: One-Click Install (Recommended for new sites)
|
||||
|
||||
1. Server → New Site → WordPress tab
|
||||
2. Fill in: site title, admin email, admin username, admin password
|
||||
3. PHP version: 8.1 or 8.2 recommended
|
||||
4. Web stack: NGINX (recommended) or OpenLiteSpeed
|
||||
5. Click Deploy — WordPress installed automatically
|
||||
|
||||
## Method 2: Git Deploy (existing WordPress sites)
|
||||
|
||||
Repository setup:
|
||||
```
|
||||
your-repo/
|
||||
├── wp-content/
|
||||
│ ├── plugins/
|
||||
│ ├── themes/
|
||||
│ └── uploads/ ← add to .gitignore
|
||||
├── wp-config.php ← use env vars for DB credentials
|
||||
└── ...
|
||||
```
|
||||
|
||||
wp-config.php — use environment variables:
|
||||
```php
|
||||
define('DB_NAME', getenv('DB_NAME'));
|
||||
define('DB_USER', getenv('DB_USER'));
|
||||
define('DB_PASSWORD', getenv('DB_PASSWORD'));
|
||||
define('DB_HOST', getenv('DB_HOST') ?: 'localhost');
|
||||
```
|
||||
|
||||
xCloud UI Steps:
|
||||
1. Server → New Site → WordPress tab → Git option
|
||||
2. Connect repo
|
||||
3. Add DB environment variables
|
||||
4. Deploy
|
||||
|
||||
## Performance Recommendations
|
||||
|
||||
- Enable NGINX FastCGI Cache in xCloud site settings
|
||||
- Enable Redis Object Cache (available as xCloud addon)
|
||||
- Set PHP version to 8.2+
|
||||
- Enable AI Bot Blocker in security settings
|
||||
Reference in New Issue
Block a user