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:
Pulse
2026-05-19 20:51:05 -03:00
parent 483bcbf92e
commit 22d9f5b21d
85 changed files with 6182 additions and 38 deletions
@@ -0,0 +1,8 @@
{
"version": 1,
"registry": "https://clawhub.ai",
"slug": "xcloud-docker-deploy",
"installedVersion": "1.2.1",
"installedAt": 1779234226416,
"fingerprint": "6ef42f1d3041820f4fc72e86baabdcd73d8697c8abd73866e768e354c1bbf767"
}
+23
View File
@@ -0,0 +1,23 @@
# ClawHub Safety Manifest
# This skill contains no executable code — documentation only.
# All files listed below are verified safe for AI agent consumption.
safe_files:
- SKILL.md
- README.md
- SECURITY.md
- CHANGELOG.md
- LICENSE
- assets/github-actions-build.yml
- references/xcloud-constraints.md
- references/scenario-build-source.md
- references/scenario-proxy-conflict.md
- references/scenario-multi-service-build.md
- examples/rybbit-analytics.md
- examples/custom-app-dockerfile.md
- examples/fullstack-monorepo.md
no_executables: true
no_network_calls: true
no_subprocess: true
no_system_modifications: true
+1
View File
@@ -0,0 +1 @@
github: Asif2BD
+32
View File
@@ -0,0 +1,32 @@
# SkillsMP indexing configuration
# https://skillsmp.com
skill:
name: xcloud-docker-deploy
version: "1.2.0"
entrypoint: SKILL.md
category: "DevOps & Deployment"
tags:
- docker
- deployment
- devops
- xcloud
- docker-compose
- github-actions
- wordpress
- laravel
- nextjs
- nodejs
- python
- ci-cd
- hosting
- vibe-coding
platforms:
- claude-code
- codex
- openClaw
- any
featured_examples:
- examples/rybbit-analytics.md
- examples/nextjs-app.md
- examples/laravel-app.md
+44
View File
@@ -0,0 +1,44 @@
# Changelog
## v1.2.0 — 2026-03-03
### Added
- `skill.json` — machine-readable metadata for SkillsMP, ClawHub, and all AI agent indexers (name, version, author, tags, capabilities, supported stacks, install commands, platforms, security flags)
- `.github/skillsmp.yml` — SkillsMP indexing config (category, tags, platforms, featured examples)
- `.github/FUNDING.yml` — GitHub Sponsors maintenance signal
- `CONTRIBUTING.md` — community contribution guide (how to add stacks, fix bugs, submit PRs)
### Changed
- `SKILL.md` frontmatter enriched: YAML tags array (14 tags), `category`, `author`, `platforms` list, `version`, `homepage`, `repository`
- `README.md` rewritten: cleaner structure, usage examples, supported stacks table, full compatibility table, all install paths
- All version references bumped to 1.2.0
## v1.1.1 — 2026-03-03
### Changed
- README rewrite for SkillsMP/Claude Code/Codex CLI discoverability — SkillsMP badge, Codex CLI install path, full compatibility table
## v1.1.0 — 2026-03-03
### Added
- `DETECT.md`: Stack fingerprinting — auto-detects WordPress, Laravel, PHP, Node.js, Next.js, NestJS, Nuxt, Python, Go, Rust
- **Phase 0 routing table** in `SKILL.md` — project type detection before any Docker work
- **5 production Dockerfiles**: Laravel (PHP 8.3-fpm), Next.js (standalone), Node.js (multi-stage), PHP generic (Apache), Python/FastAPI
- **4 compose templates**: Laravel+MySQL+Redis+Queue, Next.js+Postgres, Node.js API+Postgres, FastAPI+Postgres+Celery+Redis
- **4 native deploy guides**: WordPress (one-click + Git), Laravel (composer+artisan), PHP, Node.js
- **Decision matrix** (`references/xcloud-deploy-paths.md`): Native vs Docker by stack + DB + background jobs
- **2 new examples**: Laravel native end-to-end, Next.js Docker end-to-end
### Changed
- `SKILL.md` description updated to reflect full project-aware deployment capability
- README rewritten for SkillsMP/Claude Code/Codex CLI discoverability
## v1.0.0 — 2026-03-03
### Initial Release
- Scenario A: Build-from-source (generate GitHub Actions → GHCR)
- Scenario B: Proxy conflict (remove Caddy/Traefik, add nginx-router)
- Scenario C: Multi-service build (matrix GitHub Actions workflow)
- External config file embedding via Docker `configs:` block
- References: xCloud constraints, scenario deep-dives
- Examples: Rybbit Analytics, custom Dockerfile, fullstack monorepo
@@ -0,0 +1,39 @@
# Contributing to xCloud Docker Deploy Skill
Thank you for your interest in contributing! This skill helps AI agents deploy projects to xCloud hosting.
## Ways to Contribute
### Add a New Stack
1. Add detection rules to `DETECT.md`
2. Add a reference guide to `references/xcloud-native-STACK.md` or `references/scenario-STACK.md`
3. Add a Dockerfile template to `dockerfiles/STACK.Dockerfile` (if Docker path)
4. Add a compose template to `compose-templates/STACK.yml` (if Docker path)
5. Add an example to `examples/STACK-app.md`
6. Update the routing table in `SKILL.md` Phase 0
### Fix or Improve
- Incorrect xCloud platform behavior → update `references/xcloud-constraints.md`
- Broken Dockerfile → fix `dockerfiles/`
- Better nginx config → update scenario references or compose templates
### Add Examples
Real-world deployment scenarios are welcome in `examples/`. Follow the existing format.
## Format Standards
- All files: Markdown (`.md`) or YAML/Dockerfile
- No executables, no network calls, no binary files
- Keep `SKILL.md` concise — detailed content goes in `references/`
- Test Dockerfiles with `docker build` before submitting
## Pull Request Process
1. Fork the repo
2. Create a branch: `feat/add-STACK-support` or `fix/ISSUE`
3. Make changes, update `CHANGELOG.md`
4. Open a PR against `main`
## Code of Conduct
Be respectful and constructive. This is a community tool.
+38
View File
@@ -0,0 +1,38 @@
# Project Detection — Stack Fingerprinting
The agent MUST run this detection before any other step.
## Detection Rules (check in order)
| File/Signal | Stack | Recommended Path |
|---|---|---|
| `wp-content/` dir OR `wp-config.php` | WordPress | **xCloud Native** |
| `composer.json` + `artisan` file | Laravel | **xCloud Native** (or Docker if complex) |
| `composer.json` only | PHP Generic | **xCloud Native** (or Docker) |
| `package.json` + `next.config.js` or `next.config.ts` | Next.js | **Docker** (requires build step) |
| `package.json` + `nest-cli.json` | NestJS | **Docker** |
| `package.json` + `nuxt.config.*` | Nuxt.js | **Docker** |
| `package.json` only | Node.js / Express | **xCloud Native** (or Docker) |
| `requirements.txt` or `pyproject.toml` | Python | **Docker** |
| `go.mod` | Go | **Docker** |
| `Cargo.toml` | Rust | **Docker** |
| `docker-compose.yml` exists | Existing Docker stack | **Adapt** → run Scenario A/B/C detection |
| `Dockerfile` exists (no compose) | Build-from-source | **Generate** docker-compose.yml → Scenario A |
| None of the above | Unknown | Ask user for stack type |
## Output
After detection, state:
```
Detected: [STACK]
Recommended deployment path: [Native / Docker]
Reason: [one sentence]
```
Then read the appropriate reference file:
- Native WordPress → `references/xcloud-native-wordpress.md`
- Native Laravel → `references/xcloud-native-laravel.md`
- Native Node.js → `references/xcloud-native-nodejs.md`
- Native PHP → `references/xcloud-native-php.md`
- Docker → proceed with existing Scenario A/B/C logic from SKILL.md
- Generate Dockerfile → read `dockerfiles/` templates
+151
View File
@@ -0,0 +1,151 @@
# xCloud Docker Deploy Skill
> **For AI Agents:** Auto-detect any project stack and deploy it to [xCloud](https://xcloud.host) — native or Docker path, zero config required.
[![Version](https://img.shields.io/badge/version-1.2.0-blue)](https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill/releases)
[![License](https://img.shields.io/badge/license-Apache--2.0-green)](LICENSE)
[![SkillsMP](https://img.shields.io/badge/SkillsMP-listed-purple)](https://skillsmp.com)
[![ClawHub](https://img.shields.io/badge/ClawHub-published-orange)](https://clawhub.ai/Asif2BD/xcloud-docker-deploy)
[![Platforms](https://img.shields.io/badge/platforms-Claude%20Code%20%7C%20Codex%20%7C%20OpenClaw%20%7C%20Cursor-lightgrey)](#install)
---
## What It Does
Paste a project structure or `docker-compose.yml` and ask the AI to deploy it on xCloud. The skill:
1. **Detects your stack** — WordPress, Laravel, PHP, Node.js, Next.js, NestJS, Nuxt, Python, Go, Rust, or existing Docker
2. **Picks the right path** — xCloud Native deploy vs Docker
3. **Generates all files** — Dockerfile, docker-compose.yml, GitHub Actions CI/CD, .env.example
4. **Gives exact xCloud UI steps** — copy-paste ready
### What It Handles
| Scenario | Signal | Fix |
|----------|--------|-----|
| **Stack detection** | Any project files | Auto-routes to native or Docker path |
| **Build-from-source** | `build: context: .` in compose | GitHub Actions → GHCR; replaces `build:` with `image:` |
| **Proxy conflict** | Caddy/Traefik/nginx-proxy service | Removes it, adds embedded nginx-router |
| **Multi-port** | Multiple `ports:` on different services | Routes through nginx-router, single exposed port |
| **External config** | `./nginx.conf:/etc/nginx/...` | Embeds config inline via `configs:` block |
| **No Docker at all** | WordPress/Laravel/Node.js project | Native xCloud deploy guide |
---
## Install
### Claude Code (CLI)
```bash
# From ClawHub
clawhub install xcloud-docker-deploy
# Or manually
git clone https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill.git
cp -r xCloud-Docker-Deploy-Skill ~/.claude/skills/xcloud-docker-deploy
```
### OpenAI Codex CLI
```bash
git clone https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill.git
cp -r xCloud-Docker-Deploy-Skill ~/.codex/skills/xcloud-docker-deploy
```
### OpenClaw Agent
Drop the skill folder into your agent's `skills/` workspace directory.
### Claude.ai (Projects)
Upload `SKILL.md` to your Project files. The AI will use it as context automatically.
### Cursor / Windsurf / Any AI IDE
Add `SKILL.md` contents to your system prompt or project rules file.
---
## Usage
Once installed, just describe what you want:
```
"Make this docker-compose.yml work on xCloud"
"Deploy my Laravel app to xCloud"
"My Next.js app needs to run on xCloud, help me set it up"
"Convert this Caddy + React + API stack for xCloud"
```
The agent reads DETECT.md first, identifies your stack, then follows the appropriate guide.
---
## Supported Stacks
| Stack | Deploy Path | Files Provided |
|-------|-------------|----------------|
| WordPress | xCloud Native | Step-by-step UI guide |
| Laravel | xCloud Native | Deploy hooks, queue worker config |
| PHP (generic) | xCloud Native | Web root config, Composer hooks |
| Node.js / Express | xCloud Native | PORT env setup |
| Next.js | Docker | `dockerfiles/nextjs.Dockerfile` + `compose-templates/nextjs-postgres.yml` |
| NestJS | Docker | Generated Dockerfile + compose |
| Python / FastAPI | Docker | `dockerfiles/python-fastapi.Dockerfile` + compose with Celery |
| Go | Docker | Generated Dockerfile + compose |
| Existing Docker | Adapt | Scenario A/B/C transformation |
---
## Skill Structure
```
xcloud-docker-deploy/
├── SKILL.md ← Main skill instructions (load this)
├── DETECT.md ← Stack fingerprinting rules
├── references/
│ ├── xcloud-constraints.md ← Platform rules (must-read)
│ ├── xcloud-deploy-paths.md ← Native vs Docker decision matrix
│ ├── xcloud-native-wordpress.md ← WordPress deploy guide
│ ├── xcloud-native-laravel.md ← Laravel deploy guide
│ ├── xcloud-native-nodejs.md ← Node.js deploy guide
│ ├── xcloud-native-php.md ← PHP deploy guide
│ ├── scenario-build-source.md ← Scenario A deep-dive
│ ├── scenario-proxy-conflict.md ← Scenario B deep-dive
│ └── scenario-multi-service-build.md ← Scenario C deep-dive
├── dockerfiles/
│ ├── laravel.Dockerfile ← PHP 8.3-fpm-alpine, multi-stage
│ ├── nextjs.Dockerfile ← 3-stage standalone build
│ ├── node-app.Dockerfile ← Node 20-alpine, non-root
│ ├── php-generic.Dockerfile ← PHP 8.3-apache + mod_rewrite
│ └── python-fastapi.Dockerfile ← Python 3.12-slim + uvicorn
├── compose-templates/
│ ├── laravel-mysql.yml ← PHP-FPM + nginx + MySQL + Redis
│ ├── nextjs-postgres.yml ← Next.js + PostgreSQL
│ ├── nodejs-api-postgres.yml ← Node API + PostgreSQL
│ └── python-fastapi-postgres.yml ← FastAPI + PostgreSQL + Celery
├── assets/
│ └── github-actions-build.yml ← GitHub Actions GHCR build workflow
└── examples/
├── rybbit-analytics.md ← Caddy + multi-port (Scenario B)
├── custom-app-dockerfile.md ← Build-from-source (Scenario A)
├── fullstack-monorepo.md ← Multi-service (Scenario C)
├── laravel-app.md ← Laravel native deploy
└── nextjs-app.md ← Next.js Docker deploy
```
---
## About xCloud
[xCloud](https://xcloud.host) is a git-push Docker deployment platform. Push your repo, xCloud runs `docker-compose pull && docker-compose up -d`. It handles SSL, reverse proxy, and domain routing automatically — your stack must not duplicate those.
---
## Author
**M Asif Rahman** — [@Asif2BD](https://github.com/Asif2BD)
- ClawHub: [clawhub.ai/Asif2BD/xcloud-docker-deploy](https://clawhub.ai/Asif2BD/xcloud-docker-deploy)
- SkillsMP: [skillsmp.com](https://skillsmp.com)
---
## License
Apache 2.0 — free to use, modify, and distribute.
+42
View File
@@ -0,0 +1,42 @@
# Security Policy — xCloud Docker Deploy Skill
## Overview
This skill contains **no executable scripts**. It is a pure documentation and instruction set that guides AI agents to transform `docker-compose.yml` files for xCloud deployment.
## What This Skill Contains
| File | Type | Network Access | Code Execution |
|------|------|----------------|----------------|
| `SKILL.md` | Instructions | None | None |
| `references/*.md` | Reference docs | None | None |
| `assets/github-actions-build.yml` | Template (YAML) | None — template only | None |
| `examples/*.md` | Example docs | None | None |
## What This Skill Does NOT Do
- No scripts, binaries, or executables
- No network requests of any kind
- No file system modifications
- No subprocess calls
- No data collection or telemetry
## Generated Output Security
The skill guides AI agents to generate:
1. **Modified `docker-compose.yml`** — removes `build:` directives and proxy services. No security-sensitive changes.
2. **GitHub Actions workflow** — uses `GITHUB_TOKEN` (scoped to the repository, no extra permissions). The `packages: write` permission is required only to push to GHCR.
3. **`.env.example`** — lists variable names only, no values. Never hardcodes secrets.
## Reporting Vulnerabilities
If you find a security issue with this skill or its generated output, open an issue at:
https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill/issues
## Provenance
- Source: https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill
- ClawHub: https://clawhub.ai/Asif2BD/xcloud-docker-deploy
- Author: M Asif Rahman / Asif2BD
- Audited by: Oracle (Matrix Zion) — 2026-03-03
+195
View File
@@ -0,0 +1,195 @@
---
name: xcloud-docker-deploy
description: "Deploy any project to xCloud hosting — auto-detects stack (WordPress, Laravel, PHP, Node.js, Next.js, NestJS, Python, Go, Rust), routes to native or Docker deployment, generates production-ready Dockerfile, docker-compose.yml, GitHub Actions CI/CD, and .env.example. Works from zero Docker setup."
license: Apache-2.0
version: "1.2.0"
author: "M Asif Rahman"
homepage: "https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill"
repository: "https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill"
tags:
- docker
- deployment
- devops
- xcloud
- docker-compose
- github-actions
- wordpress
- laravel
- nextjs
- nodejs
- python
- ci-cd
- hosting
- infrastructure
category: "DevOps & Deployment"
platforms:
- claude-code
- openClaw
- claude-ai
- cursor
- windsurf
- codex
- any
security:
verified: true
no_network_calls: true
no_executables: true
sandboxed: true
install: |
# Claude Code / Codex CLI
cp -r xcloud-docker-deploy ~/.claude/skills/
# OpenClaw
# Drop skill folder into agent workspace skills/
---
# xCloud Docker Deploy
Adapt any `docker-compose.yml` to work with [xCloud](https://xcloud.host) — a git-push Docker deployment platform.
## How xCloud Works
```
git push → xCloud runs: docker-compose pull && docker-compose up -d
```
**xCloud never runs `docker build`.** Images must be pre-built in a public registry. SSL, reverse proxy, and domain routing are handled by xCloud — your stack must not duplicate them.
Read `references/xcloud-constraints.md` for the full ruleset before making changes.
---
## Phase 0 — Detect Project Type First
**Before anything else, scan the project directory for these files:**
Read `DETECT.md` for full detection rules. Quick routing:
| Found in project | Stack | Action |
|---|---|---|
| `wp-config.php` or `wp-content/` | WordPress | Read `references/xcloud-native-wordpress.md` |
| `composer.json` + `artisan` | Laravel | Read `references/xcloud-native-laravel.md` |
| `package.json` + `next.config.*` | Next.js | Docker path → use `dockerfiles/nextjs.Dockerfile` + `compose-templates/nextjs-postgres.yml` |
| `package.json` (no framework config) | Node.js | Read `references/xcloud-native-nodejs.md` |
| `composer.json` (no artisan) | PHP | Read `references/xcloud-native-php.md` |
| `requirements.txt` or `pyproject.toml` | Python | Docker path → use `dockerfiles/python-fastapi.Dockerfile` |
| `go.mod` | Go | Docker path — generate Dockerfile manually |
| `docker-compose.yml` exists | Existing Docker | Proceed to Step 1 below |
| `Dockerfile` (no compose) | Build-from-source | Generate compose → Scenario A below |
See `references/xcloud-deploy-paths.md` for the Native vs Docker decision guide.
---
## Step 1 — Detect Which Scenarios Apply
Inspect the provided `docker-compose.yml`:
| Signal | Scenario |
|--------|----------|
| `build:` or `build: context: .` | **A** — Build-from-source |
| Caddy / Traefik / nginx-proxy service | **B** — Proxy conflict |
| Multiple `ports:` across services | **B** — Multi-port |
| `./nginx.conf:/etc/nginx/...` volume mount | **B** — External config |
| Multiple services each with `build:` | **C** — Multi-service build |
| `image: some-public-image`, single port | Already compatible — verify port + env vars |
A compose file can trigger **multiple scenarios** simultaneously (handle A first, then B).
---
## Scenario A — Build-from-Source
> Read `references/scenario-build-source.md` for full details.
**What to do:**
1. Remove `build:` directive from compose
2. Replace `image:` with `ghcr.io/OWNER/REPO:latest`
3. Generate `.github/workflows/docker-build.yml` using `assets/github-actions-build.yml` template
4. Generate `.env.example` from all `${VAR}` references
**Deliverables:**
- Modified `docker-compose.yml`
- `.github/workflows/docker-build.yml`
- `.env.example`
- xCloud Deploy Steps (see Output Format)
---
## Scenario B — Proxy Conflict / Multi-Port / External Config
> Read `references/scenario-proxy-conflict.md` for full details.
**What to do:**
1. Remove Caddy/Traefik/nginx-proxy service entirely
2. Remove SSL labels and multi-port `ports:` from app services (replace with `expose:`)
3. Add `nginx-router` service with inline config via `configs:` block
4. Expose single port (default: `3080`) for xCloud to proxy
**Deliverables:**
- Modified `docker-compose.yml` with `nginx-router` + `configs:` block
- `.env.example`
- xCloud Deploy Steps
---
## Scenario C — Multi-Service Build
> Read `references/scenario-multi-service-build.md` for full details.
When multiple services have `build:` directives (separate frontend + backend + worker):
**What to do:**
1. For each service with `build:`, create a separate GHCR image path
2. Generate a matrix GitHub Actions workflow that builds all images in parallel
3. Update compose to use all GHCR image references
**Deliverables:**
- Modified `docker-compose.yml` (all `build:` removed)
- `.github/workflows/docker-build.yml` (matrix strategy)
- `.env.example`
---
## Output Format
Always produce complete, copy-paste-ready output:
```
## Modified docker-compose.yml
[full file]
## .github/workflows/docker-build.yml (Scenario A/C only)
[full file]
## .env.example
[full file]
## xCloud Deploy Steps
1. Push repo to GitHub
2. (Scenario A/C) Wait for GitHub Actions to build image — check Actions tab
3. Server → New Site → Custom Docker → connect repo
4. Exposed port: [PORT]
5. Env vars to add: [list from .env.example]
6. Deploy
```
---
## Rules
- **Never** include `build:` in the final compose — xCloud silently ignores it
- **Never** expose database ports to host (remove `"5432:5432"` — use `expose:` internally)
- **Never** include Caddy, Traefik, nginx-proxy, or Let's Encrypt config
- **Always** preserve `environment:`, `volumes:`, `healthcheck:`, worker/sidecar services
- **Always** use `expose:` (internal) not `ports:` (host) for services behind nginx-router
- **WebSockets?** Add upgrade headers to nginx config (see proxy-conflict reference)
- `configs.content:` inline syntax requires Docker Compose v2.23+ — use heredoc `command:` alternative if uncertain
---
## Examples
See `examples/` for ready-made transformations:
- `examples/rybbit-analytics.md` — Caddy + multi-port app (Scenario B)
- `examples/custom-app-dockerfile.md` — build-from-source (Scenario A)
- `examples/fullstack-monorepo.md` — multi-service build (Scenario C)
+6
View File
@@ -0,0 +1,6 @@
{
"ownerId": "kn78dz5s9fev1b0vez1kxz1fj580ckv2",
"slug": "xcloud-docker-deploy",
"version": "1.2.1",
"publishedAt": 1772543644312
}
@@ -0,0 +1,81 @@
name: Build & Push Docker Image
on:
push:
branches: [main]
workflow_dispatch:
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }} # e.g. owner/repo → ghcr.io/owner/repo
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,prefix=sha-
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
# Optional: trigger xCloud to pull & redeploy
# Add XCLOUD_DEPLOY_WEBHOOK to GitHub repo secrets
- name: Trigger xCloud deploy
if: ${{ secrets.XCLOUD_DEPLOY_WEBHOOK != '' }}
run: |
curl -s -X POST "${{ secrets.XCLOUD_DEPLOY_WEBHOOK }}" \
-H "Content-Type: application/json" \
-d '{"ref": "${{ github.sha }}"}'
# ─────────────────────────────────────────────
# Multi-service variant (uncomment if needed)
# ─────────────────────────────────────────────
# jobs:
# build-and-push:
# strategy:
# matrix:
# include:
# - service: app
# dockerfile: Dockerfile
# image_suffix: app
# - service: worker
# dockerfile: Dockerfile.worker
# image_suffix: worker
# steps:
# - name: Build and push
# uses: docker/build-push-action@v5
# with:
# context: .
# file: ${{ matrix.dockerfile }}
# tags: ghcr.io/${{ github.repository }}-${{ matrix.image_suffix }}:latest
@@ -0,0 +1,121 @@
# xCloud-ready Laravel + MySQL + Redis + Queue Worker
# Replace OWNER/REPO with your GitHub username/repo
services:
app:
image: ghcr.io/OWNER/REPO:latest
expose:
- "9000"
environment:
APP_ENV: production
APP_KEY: ${APP_KEY}
APP_URL: ${APP_URL}
DB_CONNECTION: mysql
DB_HOST: db
DB_PORT: 3306
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
REDIS_HOST: redis
REDIS_PORT: 6379
CACHE_DRIVER: redis
SESSION_DRIVER: redis
QUEUE_CONNECTION: redis
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
networks:
- app-network
nginx:
image: nginx:alpine
ports:
- "8080:80"
configs:
- source: nginx_config
target: /etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- app-network
db:
image: mysql:8.0
expose:
- "3306"
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- db-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
expose:
- "6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
queue:
image: ghcr.io/OWNER/REPO:latest
command: php artisan queue:work --sleep=3 --tries=3 --max-time=3600
environment:
APP_ENV: production
APP_KEY: ${APP_KEY}
DB_CONNECTION: mysql
DB_HOST: db
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
REDIS_HOST: redis
QUEUE_CONNECTION: redis
depends_on:
- db
- redis
restart: unless-stopped
networks:
- app-network
configs:
nginx_config:
content: |
upstream php-fpm {
server app:9000;
}
server {
listen 80;
root /var/www/html/public;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass php-fpm;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
volumes:
db-data:
networks:
app-network:
driver: bridge
@@ -0,0 +1,44 @@
# xCloud-ready Next.js + PostgreSQL
# Replace OWNER/REPO with your GitHub username/repo
# REQUIRED: next.config.js must have output: 'standalone'
services:
app:
image: ghcr.io/OWNER/REPO:latest
ports:
- "3000:3000"
environment:
NODE_ENV: production
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
NEXTAUTH_URL: ${NEXTAUTH_URL}
NEXTAUTH_SECRET: ${NEXTAUTH_SECRET}
depends_on:
db:
condition: service_healthy
networks:
- app-network
db:
image: postgres:16-alpine
expose:
- "5432"
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
volumes:
db-data:
networks:
app-network:
driver: bridge
@@ -0,0 +1,43 @@
# xCloud-ready Node.js API + PostgreSQL
# Replace OWNER/REPO with your GitHub username/repo
services:
app:
image: ghcr.io/OWNER/REPO:latest
ports:
- "3000:3000"
environment:
NODE_ENV: production
PORT: 3000
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
JWT_SECRET: ${JWT_SECRET}
depends_on:
db:
condition: service_healthy
networks:
- app-network
db:
image: postgres:16-alpine
expose:
- "5432"
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
volumes:
db-data:
networks:
app-network:
driver: bridge
@@ -0,0 +1,66 @@
# xCloud-ready FastAPI + PostgreSQL + Celery worker
# Replace OWNER/REPO with your GitHub username/repo
services:
app:
image: ghcr.io/OWNER/REPO:latest
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
REDIS_URL: redis://redis:6379/0
SECRET_KEY: ${SECRET_KEY}
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
networks:
- app-network
worker:
image: ghcr.io/OWNER/REPO:latest
command: celery -A app.worker worker --loglevel=info
environment:
DATABASE_URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
REDIS_URL: redis://redis:6379/0
depends_on:
- db
- redis
restart: unless-stopped
networks:
- app-network
db:
image: postgres:16-alpine
expose:
- "5432"
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
expose:
- "6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
networks:
- app-network
volumes:
db-data:
networks:
app-network:
driver: bridge
@@ -0,0 +1,35 @@
# Multi-stage Laravel Dockerfile
# xCloud: pair with compose-templates/laravel-mysql.yml
FROM php:8.3-fpm-alpine AS base
RUN apk add --no-cache git curl libpng-dev libxml2-dev zip unzip nodejs npm
RUN docker-php-ext-install pdo pdo_mysql bcmath gd xml zip opcache
RUN pecl install redis && docker-php-ext-enable redis
RUN echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini && \
echo "opcache.memory_consumption=256" >> /usr/local/etc/php/conf.d/opcache.ini && \
echo "opcache.max_accelerated_files=20000" >> /usr/local/etc/php/conf.d/opcache.ini && \
echo "opcache.validate_timestamps=0" >> /usr/local/etc/php/conf.d/opcache.ini
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer
WORKDIR /var/www/html
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
COPY . .
RUN composer dump-autoload --optimize
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
RUN php artisan config:clear && \
php artisan route:cache && \
php artisan view:cache
EXPOSE 9000
CMD ["php-fpm"]
@@ -0,0 +1,37 @@
# Next.js Dockerfile — standalone output mode
# REQUIRED: next.config.js must have output: 'standalone'
# xCloud: pair with compose-templates/nextjs-postgres.yml
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* yarn.lock* ./
RUN if [ -f package-lock.json ]; then npm ci; \
elif [ -f yarn.lock ]; then yarn --frozen-lockfile; \
else npm install; fi
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ENV NEXT_TELEMETRY_DISABLED=1
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
RUN chown -R nextjs:nodejs /app
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
@@ -0,0 +1,25 @@
# Multi-stage Node.js Dockerfile (Express / Fastify / generic)
# xCloud: pair with compose-templates/nodejs-api-postgres.yml
FROM node:20-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json* yarn.lock* pnpm-lock.yaml* ./
RUN if [ -f package-lock.json ]; then npm ci --omit=dev; \
elif [ -f yarn.lock ]; then yarn --frozen-lockfile --production; \
else npm install --omit=dev; fi
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nodeuser && \
chown -R nodeuser:nodejs /app
USER nodeuser
EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]
@@ -0,0 +1,27 @@
# Generic PHP + Apache Dockerfile
# Works for CodeIgniter, Symfony, Slim, or any PHP app
FROM php:8.3-apache
RUN a2enmod rewrite headers
RUN docker-php-ext-install pdo pdo_mysql mysqli bcmath
COPY --from=composer:2.7 /usr/bin/composer /usr/bin/composer
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf && \
sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
WORKDIR /var/www/html
COPY composer.json composer.lock* ./
RUN composer install --no-dev --no-scripts --no-autoloader --prefer-dist
COPY . .
RUN composer dump-autoload --optimize
RUN chown -R www-data:www-data /var/www/html
EXPOSE 80
CMD ["apache2-foreground"]
@@ -0,0 +1,22 @@
# Python FastAPI Dockerfile
# xCloud: pair with compose-templates/python-fastapi-postgres.yml
FROM python:3.12-slim
WORKDIR /app
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential libpq-dev \
&& rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd -m -u 1001 appuser && chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
ENV PORT=8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "2"]
@@ -0,0 +1,124 @@
# Example: Custom App with Dockerfile (Scenario A — Build-from-Source)
## Original docker-compose.yml
```yaml
services:
app:
build:
context: .
dockerfile: Dockerfile
image: my-app:latest
ports:
- "8080:8080"
environment:
- NODE_ENV=production
- SECRET_KEY=${SECRET_KEY}
depends_on:
- db
db:
image: postgres:15
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=myapp
```
## Issues Detected
- `build: context: .` — xCloud cannot build images
- Database port `5432` exposed to host (security risk)
## Fixed docker-compose.yml
```yaml
services:
app:
image: ghcr.io/OWNER/my-app:latest
ports:
- "8080:8080"
environment:
- NODE_ENV=production
- SECRET_KEY=${SECRET_KEY}
depends_on:
- db
networks:
- app-network
db:
image: postgres:15
expose:
- "5432" # internal only — removed host port binding
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=myapp
networks:
- app-network
networks:
app-network:
driver: bridge
```
## .github/workflows/docker-build.yml
```yaml
name: Build and Push Docker Image
on:
push:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: my-app
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository_owner }}/my-app:latest
ghcr.io/${{ github.repository_owner }}/my-app:sha-${{ github.sha }}
- name: Trigger xCloud deploy
if: ${{ secrets.XCLOUD_DEPLOY_WEBHOOK != '' }}
run: curl -X POST "${{ secrets.XCLOUD_DEPLOY_WEBHOOK }}"
```
## .env.example
```
SECRET_KEY=
POSTGRES_PASSWORD=
```
## xCloud Deploy Steps
1. Push repo to GitHub — GitHub Actions builds and pushes image automatically
2. Go to GitHub → Packages → make `my-app` package **Public**
3. Add `XCLOUD_DEPLOY_WEBHOOK` secret in GitHub repo settings (from xCloud site → Deploy settings)
4. Server → New Site → Custom Docker → connect repo
5. Exposed port: **8080**
6. Env vars: `SECRET_KEY`, `POSTGRES_PASSWORD`
7. Deploy
@@ -0,0 +1,120 @@
# Example: Fullstack Monorepo (Scenario C — Multi-Service Build)
## Original docker-compose.yml
```yaml
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
backend:
build: ./backend
ports:
- "8000:8000"
environment:
- DATABASE_URL=${DATABASE_URL}
- JWT_SECRET=${JWT_SECRET}
depends_on:
- db
db:
image: postgres:15-alpine
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
```
## Issues Detected
- `build: ./frontend` and `build: ./backend` — two services need building
- Multiple exposed ports: 3000, 8000 (xCloud needs single port)
- Database port exposed to host
## Fixed docker-compose.yml
```yaml
services:
nginx-router:
image: nginx:alpine
ports:
- "3080:80"
configs:
- source: nginx_config
target: /etc/nginx/conf.d/default.conf
depends_on:
- frontend
- backend
networks:
- app-network
frontend:
image: ghcr.io/OWNER/REPO/frontend:latest
expose:
- "3000"
environment:
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
networks:
- app-network
backend:
image: ghcr.io/OWNER/REPO/backend:latest
expose:
- "8000"
environment:
- DATABASE_URL=${DATABASE_URL}
- JWT_SECRET=${JWT_SECRET}
depends_on:
- db
networks:
- app-network
db:
image: postgres:15-alpine
expose:
- "5432"
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
networks:
- app-network
configs:
nginx_config:
content: |
server {
listen 80;
location /api/ {
proxy_pass http://backend:8000/;
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:3000/;
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;
}
}
networks:
app-network:
driver: bridge
```
## xCloud Deploy Steps
1. Push to GitHub — matrix workflow builds `frontend` and `backend` images in parallel
2. Make both GHCR packages **Public** (github.com/OWNER/REPO → Packages)
3. Server → New Site → Custom Docker → connect repo
4. Exposed port: **3080**
5. Env vars: `NEXT_PUBLIC_API_URL`, `DATABASE_URL`, `JWT_SECRET`, `POSTGRES_PASSWORD`
6. Deploy
@@ -0,0 +1,59 @@
# Example: Fresh Laravel App → xCloud Native Deploy
## Project structure detected
- composer.json ✓
- artisan ✓
Detected: Laravel | Recommended: xCloud Native
## Step 1 — Prepare .env.example
```env
APP_NAME=MyLaravelApp
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
```
## Step 2 — Add to .gitignore
```
.env
/vendor
/node_modules
/public/storage
/storage/*.key
```
## Step 3 — Push to GitHub
```bash
git init && git add . && git commit -m "Initial commit"
git remote add origin https://github.com/OWNER/REPO.git
git push -u origin main
```
## Step 4 — Deploy in xCloud
1. Server → New Site → Laravel tab
2. Connect GitHub repo, PHP version: 8.2
3. Deploy hooks:
```
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
```
4. Add env vars — APP_KEY from `php artisan key:generate --show`
5. Deploy
@@ -0,0 +1,41 @@
# Example: Next.js App → xCloud via Docker
## Project structure detected
- package.json ✓
- next.config.js ✓
Detected: Next.js | Recommended: Docker (requires build step)
## Step 1 — Add standalone output to next.config.js
```js
const nextConfig = { output: 'standalone' }
module.exports = nextConfig
```
## Step 2 — Add Dockerfile
Copy `dockerfiles/nextjs.Dockerfile` → rename to `Dockerfile` in repo root.
## Step 3 — Add docker-compose.yml
Copy `compose-templates/nextjs-postgres.yml` → rename to `docker-compose.yml`. Replace OWNER/REPO.
## Step 4 — Add GitHub Actions
Copy `assets/github-actions-build.yml``.github/workflows/docker-build.yml`
## Step 5 — Add .env.example
```env
POSTGRES_DB=myapp
POSTGRES_USER=myuser
POSTGRES_PASSWORD=
NEXTAUTH_URL=https://yourdomain.com
NEXTAUTH_SECRET=
```
## Step 6 — Push and wait for GHCR build (~3-5 min)
```bash
git add . && git commit -m "Add xCloud deployment" && git push origin main
```
## Step 7 — Deploy in xCloud
1. Server → New Site → Custom Docker
2. Connect repo, exposed port: 3000
3. Add env vars, Deploy
@@ -0,0 +1,124 @@
# Example: Rybbit Analytics (Scenario B — Proxy Conflict + Multi-Port)
## Original docker-compose.yml
```yaml
services:
caddy:
image: caddy:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
clickhouse:
image: clickhouse/clickhouse-server:latest
ports:
- "8123:8123"
backend:
image: rybbit/backend:latest
ports:
- "3001:3001"
environment:
- DATABASE_URL=${DATABASE_URL}
frontend:
image: rybbit/frontend:latest
ports:
- "3002:3002"
environment:
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
```
## Issues Detected
- Caddy service (proxy conflict with xCloud nginx)
- Multiple exposed ports: 8123, 3001, 3002 (xCloud needs single port)
- External Caddyfile volume mount
## Fixed docker-compose.yml
```yaml
services:
nginx-router:
image: nginx:alpine
ports:
- "3080:80"
configs:
- source: nginx_config
target: /etc/nginx/conf.d/default.conf
depends_on:
- backend
- frontend
networks:
- app-network
clickhouse:
image: clickhouse/clickhouse-server:latest
expose:
- "8123"
networks:
- app-network
backend:
image: rybbit/backend:latest
expose:
- "3001"
environment:
- DATABASE_URL=${DATABASE_URL}
networks:
- app-network
frontend:
image: rybbit/frontend:latest
expose:
- "3002"
environment:
- NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}
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;
}
}
networks:
app-network:
driver: bridge
```
## .env.example
```
DATABASE_URL=
NEXT_PUBLIC_API_URL=
```
## xCloud Deploy Steps
1. Push repo to GitHub
2. Server → New Site → Custom Docker → connect repo
3. Exposed port: **3080**
4. Env vars to add: `DATABASE_URL`, `NEXT_PUBLIC_API_URL`
5. Deploy
@@ -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
+97
View File
@@ -0,0 +1,97 @@
{
"name": "xcloud-docker-deploy",
"displayName": "xCloud Docker Deploy",
"version": "1.2.0",
"description": "Deploy any project to xCloud hosting \u2014 auto-detects stack (WordPress, Laravel, PHP, Node.js, Next.js, NestJS, Python, Go, Rust), routes to native or Docker deployment, generates production-ready Dockerfile, docker-compose.yml, GitHub Actions CI/CD, and .env.example.",
"longDescription": "A full project-aware deployment assistant for xCloud hosting. Phase 0 auto-detects the project stack from file signals and routes to the optimal deployment path \u2014 either xCloud Native (WordPress, Laravel, PHP, Node.js) or Docker (Next.js, Python, Go, NestJS). Includes production-ready Dockerfile templates, pre-configured docker-compose stacks, GitHub Actions CI/CD workflows, and step-by-step xCloud UI guides. Works from zero \u2014 no existing Docker setup required.",
"author": {
"name": "M Asif Rahman",
"github": "Asif2BD",
"url": "https://github.com/Asif2BD"
},
"license": "Apache-2.0",
"homepage": "https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill",
"repository": "https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill",
"category": "DevOps & Deployment",
"tags": [
"docker",
"deployment",
"devops",
"xcloud",
"docker-compose",
"github-actions",
"wordpress",
"laravel",
"nextjs",
"nodejs",
"python",
"ci-cd",
"hosting",
"infrastructure",
"php",
"fastapi",
"nginx",
"ghcr",
"stack-detection",
"vibe-coding"
],
"platforms": [
"claude-code",
"codex",
"openClaw",
"claude-ai",
"cursor",
"windsurf",
"any"
],
"entrypoint": "SKILL.md",
"files": {
"main": "SKILL.md",
"detection": "DETECT.md",
"references": "references/",
"dockerfiles": "dockerfiles/",
"templates": "compose-templates/",
"examples": "examples/",
"assets": "assets/"
},
"capabilities": [
"stack-detection",
"dockerfile-generation",
"compose-generation",
"github-actions-generation",
"native-deploy-guide",
"env-generation"
],
"stacks": [
"wordpress",
"laravel",
"php",
"nodejs",
"nextjs",
"nestjs",
"nuxt",
"python",
"go",
"rust",
"docker"
],
"security": {
"verified": true,
"no_network_calls": true,
"no_executables": true,
"sandboxed": true,
"local_only": true
},
"install": {
"clawhub": "clawhub install xcloud-docker-deploy",
"claude_code": "cp -r xcloud-docker-deploy ~/.claude/skills/",
"codex": "cp -r xcloud-docker-deploy ~/.codex/skills/",
"manual": "git clone https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill.git"
},
"links": {
"clawhub": "https://clawhub.ai/Asif2BD/xcloud-docker-deploy",
"github": "https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill"
},
"publishedAt": "2026-03-01",
"updatedAt": "2026-03-03"
}