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,8 @@
|
||||
{
|
||||
"version": 1,
|
||||
"registry": "https://clawhub.ai",
|
||||
"slug": "xcloud-docker-deploy",
|
||||
"installedVersion": "1.2.1",
|
||||
"installedAt": 1779234226416,
|
||||
"fingerprint": "6ef42f1d3041820f4fc72e86baabdcd73d8697c8abd73866e768e354c1bbf767"
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
github: Asif2BD
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
[](https://github.com/Asif2BD/xCloud-Docker-Deploy-Skill/releases)
|
||||
[](LICENSE)
|
||||
[](https://skillsmp.com)
|
||||
[](https://clawhub.ai/Asif2BD/xcloud-docker-deploy)
|
||||
[](#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.
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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"
|
||||
}
|
||||
Reference in New Issue
Block a user