[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7145M7DGC7P8J52JYBAV0QR":3,"skill-same:01M7145M7DGC7P8J52JYBAV0QR":69},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":49,"commitSha":50,"skillDirectory":51,"forksCount":14,"repositoryHtmlUrl":52,"repositoryHomepageUrl":6,"ownerHtmlUrl":53,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":54,"install":55,"resources":68},"01M7145M7DGC7P8J52JYBAV0QR","odoo-docker-deployment",null,"Production-ready Docker and docker-compose setup for Odoo with PostgreSQL, persistent volumes, environment-based configuration, and Nginx reverse proxy.","sapsapshen\u002Fai-memory-router","sapsapshen","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F20347959?v=4","01M6XDQEF1DP50DKF37H81J3J5","shenmian","01M6XDQEJPE41Y3DT2763X8ZJN",0,"MIT","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fodoo-docker-deployment\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"odoo","docker deployment","odoo docker deployment","deployment","docker","nginx","Production","environment","ready","compose","safe","postgresql","self","docker-compose","with","reverse proxy","reverse","production-ready","for","proxy","2026-11-10 10:12:30",false,"---\nname: odoo-docker-deployment\ndescription: \"Production-ready Docker and docker-compose setup for Odoo with PostgreSQL, persistent volumes, environment-based configuration, and Nginx reverse proxy.\"\nrisk: safe\nsource: \"self\"\n---\n\n# Odoo Docker Deployment\n\n## Overview\n\nThis skill provides a complete, production-ready Docker setup for Odoo, including PostgreSQL, persistent file storage, environment variable configuration, and an optional Nginx reverse proxy with SSL. It covers both development and production configurations.\n\n## When to Use This Skill\n\n- Spinning up a local Odoo development environment with Docker.\n- Deploying Odoo to a VPS or cloud server (AWS, DigitalOcean, etc.).\n- Troubleshooting Odoo container startup failures or database connection errors.\n- Adding a reverse proxy with SSL to an existing Odoo Docker setup.\n\n## How It Works\n\n1. **Activate**: Mention `@odoo-docker-deployment` and describe your deployment scenario.\n2. **Generate**: Receive a complete `docker-compose.yml` and `odoo.conf` ready to run.\n3. **Debug**: Describe your container error and get a diagnosis with a fix.\n\n## Examples\n\n### Example 1: Production docker-compose.yml\n\n```yaml\n# Note: The top-level 'version' key is deprecated in Docker Compose v2+\n# and can be safely omitted. Remove it to avoid warnings.\n\nservices:\n  db:\n    image: postgres:15\n    restart: always\n    environment:\n      POSTGRES_DB: odoo\n      POSTGRES_USER: odoo\n      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n    volumes:\n      - postgres-data:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n    networks:\n      - odoo-net\n\n  odoo:\n    image: odoo:17.0\n    restart: always\n    depends_on:\n      db:\n        condition: service_healthy\n    ports:\n      - \"8069:8069\"\n      - \"8072:8072\"   # Longpolling for live chat \u002F bus\n    environment:\n      HOST: db\n      USER: odoo\n      PASSWORD: ${POSTGRES_PASSWORD}\n    volumes:\n      - odoo-web-data:\u002Fvar\u002Flib\u002Fodoo\n      - .\u002Faddons:\u002Fmnt\u002Fextra-addons   # Custom modules\n      - .\u002Fodoo.conf:\u002Fetc\u002Fodoo\u002Fodoo.conf\n    networks:\n      - odoo-net\n\nvolumes:\n  postgres-data:\n  odoo-web-data:\n\nnetworks:\n  odoo-net:\n```\n\n### Example 2: odoo.conf\n\n```ini\n[options]\nadmin_passwd = ${ODOO_MASTER_PASSWORD}    ; set via env or .env file\ndb_host = db\ndb_port = 5432\ndb_user = odoo\ndb_password = ${POSTGRES_PASSWORD}        ; set via env or .env file\n\n; addons_path inside the official Odoo Docker image (Debian-based)\naddons_path = \u002Fmnt\u002Fextra-addons,\u002Fusr\u002Flib\u002Fpython3\u002Fdist-packages\u002Fodoo\u002Faddons\n\nlogfile = \u002Fvar\u002Flog\u002Fodoo\u002Fodoo.log\nlog_level = warn\n\n; Worker tuning for a 4-core \u002F 8GB server:\nworkers = 9                ; (CPU cores × 2) + 1\nmax_cron_threads = 2\nlimit_memory_soft = 1610612736   ; 1.5 GB — soft kill threshold\nlimit_memory_hard = 2147483648   ; 2.0 GB — hard kill threshold\nlimit_time_cpu = 600\nlimit_time_real = 1200\nlimit_request = 8192\n```\n\n### Example 3: Common Commands\n\n```bash\n# Start all services in background\ndocker compose up -d\n\n# Stream Odoo logs in real time\ndocker compose logs -f odoo\n\n# Restart Odoo only (not DB — avoids data risk)\ndocker compose restart odoo\n\n# Stop all services\ndocker compose down\n\n# Backup the database to a local SQL dump\ndocker compose exec db pg_dump -U odoo odoo > backup_$(date +%Y%m%d).sql\n\n# Update a custom module without restarting the server\ndocker compose exec odoo odoo -d odoo --update my_module --stop-after-init\n```\n\n## Best Practices\n\n- ✅ **Do:** Store all secrets in a `.env` file and reference them with `${VAR}` — never hardcode passwords in `docker-compose.yml`.\n- ✅ **Do:** Use `depends_on: condition: service_healthy` with a PostgreSQL healthcheck to prevent Odoo starting before the DB is ready.\n- ✅ **Do:** Put Nginx in front of Odoo for SSL termination (Let's Encrypt \u002F Certbot) — never expose Odoo directly on port 80\u002F443.\n- ✅ **Do:** Set `workers = (CPU cores × 2) + 1` in `odoo.conf` — `workers = 0` uses single-threaded mode and blocks all users.\n- ❌ **Don't:** Expose port 5432 (PostgreSQL) to the public internet — keep it on the internal Docker network only.\n- ❌ **Don't:** Use the `latest` or `17` Docker image tags in production — always pin to a specific patch-level tag (e.g., `odoo:17.0`).\n- ❌ **Don't:** Mount `odoo.conf` and rely on it for secrets in CI\u002FCD — use Docker secrets or environment variables instead.\n\n## Limitations\n\n- This skill covers **self-hosted Docker deployments** — Odoo.sh (cloud-managed hosting) has a completely different deployment model.\n- **Horizontal scaling** (multiple Odoo containers behind a load balancer) requires shared filestore (NFS or S3-compatible storage) not covered here.\n- Does not include an Nginx configuration template — consult the [official Odoo Nginx docs](https:\u002F\u002Fwww.odoo.com\u002Fdocumentation\u002F17.0\u002Fadministration\u002Finstall\u002Fdeploy.html) for the full reverse proxy config.\n- The `addons_path` inside the Docker image may change with new base image versions — always verify after upgrading the Odoo image.\n","# Odoo Docker Deployment\n\n## Overview\n\nThis skill provides a complete, production-ready Docker setup for Odoo, including PostgreSQL, persistent file storage, environment variable configuration, and an optional Nginx reverse proxy with SSL. It covers both development and production configurations.\n\n## When to Use This Skill\n\n- Spinning up a local Odoo development environment with Docker.\n- Deploying Odoo to a VPS or cloud server (AWS, DigitalOcean, etc.).\n- Troubleshooting Odoo container startup failures or database connection errors.\n- Adding a reverse proxy with SSL to an existing Odoo Docker setup.\n\n## How It Works\n\n1. **Activate**: Mention `@odoo-docker-deployment` and describe your deployment scenario.\n2. **Generate**: Receive a complete `docker-compose.yml` and `odoo.conf` ready to run.\n3. **Debug**: Describe your container error and get a diagnosis with a fix.\n\n## Examples\n\n### Example 1: Production docker-compose.yml\n\n```yaml\n# Note: The top-level 'version' key is deprecated in Docker Compose v2+\n# and can be safely omitted. Remove it to avoid warnings.\n\nservices:\n  db:\n    image: postgres:15\n    restart: always\n    environment:\n      POSTGRES_DB: odoo\n      POSTGRES_USER: odoo\n      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n    volumes:\n      - postgres-data:\u002Fvar\u002Flib\u002Fpostgresql\u002Fdata\n    networks:\n      - odoo-net\n\n  odoo:\n    image: odoo:17.0\n    restart: always\n    depends_on:\n      db:\n        condition: service_healthy\n    ports:\n      - \"8069:8069\"\n      - \"8072:8072\"   # Longpolling for live chat \u002F bus\n    environment:\n      HOST: db\n      USER: odoo\n      PASSWORD: ${POSTGRES_PASSWORD}\n    volumes:\n      - odoo-web-data:\u002Fvar\u002Flib\u002Fodoo\n      - .\u002Faddons:\u002Fmnt\u002Fextra-addons   # Custom modules\n      - .\u002Fodoo.conf:\u002Fetc\u002Fodoo\u002Fodoo.conf\n    networks:\n      - odoo-net\n\nvolumes:\n  postgres-data:\n  odoo-web-data:\n\nnetworks:\n  odoo-net:\n```\n\n### Example 2: odoo.conf\n\n```ini\n[options]\nadmin_passwd = ${ODOO_MASTER_PASSWORD}    ; set via env or .env file\ndb_host = db\ndb_port = 5432\ndb_user = odoo\ndb_password = ${POSTGRES_PASSWORD}        ; set via env or .env file\n\n; addons_path inside the official Odoo Docker image (Debian-based)\naddons_path = \u002Fmnt\u002Fextra-addons,\u002Fusr\u002Flib\u002Fpython3\u002Fdist-packages\u002Fodoo\u002Faddons\n\nlogfile = \u002Fvar\u002Flog\u002Fodoo\u002Fodoo.log\nlog_level = warn\n\n; Worker tuning for a 4-core \u002F 8GB server:\nworkers = 9                ; (CPU cores × 2) + 1\nmax_cron_threads = 2\nlimit_memory_soft = 1610612736   ; 1.5 GB — soft kill threshold\nlimit_memory_hard = 2147483648   ; 2.0 GB — hard kill threshold\nlimit_time_cpu = 600\nlimit_time_real = 1200\nlimit_request = 8192\n```\n\n### Example 3: Common Commands\n\n```bash\n# Start all services in background\ndocker compose up -d\n\n# Stream Odoo logs in real time\ndocker compose logs -f odoo\n\n# Restart Odoo only (not DB — avoids data risk)\ndocker compose restart odoo\n\n# Stop all services\ndocker compose down\n\n# Backup the database to a local SQL dump\ndocker compose exec db pg_dump -U odoo odoo > backup_$(date +%Y%m%d).sql\n\n# Update a custom module without restarting the server\ndocker compose exec odoo odoo -d odoo --update my_module --stop-after-init\n```\n\n## Best Practices\n\n- ✅ **Do:** Store all secrets in a `.env` file and reference them with `${VAR}` — never hardcode passwords in `docker-compose.yml`.\n- ✅ **Do:** Use `depends_on: condition: service_healthy` with a PostgreSQL healthcheck to prevent Odoo starting before the DB is ready.\n- ✅ **Do:** Put Nginx in front of Odoo for SSL termination (Let's Encrypt \u002F Certbot) — never expose Odoo directly on port 80\u002F443.\n- ✅ **Do:** Set `workers = (CPU cores × 2) + 1` in `odoo.conf` — `workers = 0` uses single-threaded mode and blocks all users.\n- ❌ **Don't:** Expose port 5432 (PostgreSQL) to the public internet — keep it on the internal Docker network only.\n- ❌ **Don't:** Use the `latest` or `17` Docker image tags in production — always pin to a specific patch-level tag (e.g., `odoo:17.0`).\n- ❌ **Don't:** Mount `odoo.conf` and rely on it for secrets in CI\u002FCD — use Docker secrets or environment variables instead.\n\n## Limitations\n\n- This skill covers **self-hosted Docker deployments** — Odoo.sh (cloud-managed hosting) has a completely different deployment model.\n- **Horizontal scaling** (multiple Odoo containers behind a load balancer) requires shared filestore (NFS or S3-compatible storage) not covered here.\n- Does not include an Nginx configuration template — consult the [official Odoo Nginx docs](https:\u002F\u002Fwww.odoo.com\u002Fdocumentation\u002F17.0\u002Fadministration\u002Finstall\u002Fdeploy.html) for the full reverse proxy config.\n- The `addons_path` inside the Docker image may change with new base image versions — always verify after upgrading the Odoo image.\n",{"name":5,"risk":34,"source":36,"description":7},"main","7a38d8e7073e61c16eda85681cb32fb68a8657a5","skills-store\u002Fcopilot\u002Fodoo-docker-deployment","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router","https:\u002F\u002Fgithub.com\u002Fsapsapshen","2026-04-14 21:12:12",{"source":8,"skillName":5,"commands":56,"prompt":66,"zipAvailable":67},[57,60,63],{"tool":58,"command":59},"npx","npx skills add sapsapshen\u002Fai-memory-router --skill odoo-docker-deployment",{"tool":61,"command":62},"bunx","bunx skills add sapsapshen\u002Fai-memory-router --skill odoo-docker-deployment",{"tool":64,"command":65},"pnpm","pnpm dlx skills add sapsapshen\u002Fai-memory-router --skill odoo-docker-deployment","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fcopilot\u002Fodoo-docker-deployment\u002FSKILL.md",true,[],[70,93,119,129,142,159],{"skillNo":71,"name":72,"nameZh":6,"description":73,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":74,"categories":75,"keywords":81,"publishedAt":44},"01M71ATQRKG48SH06FQ697T5G9","wechat-search","Search WeChat Official Account articles using OpenClaw's web search and fetch capabilities with compliance-focused design.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fwechat-search-release\u002FSKILL.md",[76],{"categoryNo":77,"categoryName":78,"taxonomyType":79,"taxonomyTypeDesc":80},"01JBSEEDCAT000000000000037","律师与法务","PROFESSION","适用职业",[82,83,84,85,86,87,88,89,90,91,92,38],"wechat search","wechat","search","capabilities","openclaw","design","web search","compliance","web","official","fetch",{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":44},"01M71ATNAVGZB35PFYM2GC5N00","trend-tap","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend tap', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-tap\u002FSKILL.md",[],[100,101,102,103,104,105,84,106,107,108,109,110,111,112,113,114,115,116,117,118],"trend","trend tap","tap","api keys","Bash","time","trending","hacker","aggregator","do","when","brew","live","data","google","install","read","across","api",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":44},"01M71ATJ9AM5KM15AA8PS302EB","trend-radar","Real-time trending topics aggregator across 7 platforms (X\u002FTwitter, Reddit, Google Trends, Hacker News, Zhihu, Bilibili, Weibo). Trigger: when user says 'trend', 'trends', 'trend pulse', '热点', '热搜', or asks what is trending\u002Fhot. Do NOT use web_search — this skill already fetches live data from all platforms with zero API keys.","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftrend-radar\u002FSKILL.md",[],[126,127,100,111,112,113,114,104,84,116,128,117,118,110,108,107,106,115,105,103],"trend radar","radar","pulse",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":133,"categories":134,"keywords":135,"publishedAt":44},"01M71ATGF095N3EJM9G8SD0BB5","tech-news-daily","每日科技新闻汇——从全球多个 RSS 源抓取最新科技新闻，翻译（英→中）、去重、排版成每日简报。当用户询问科技新闻、科技新鲜事、每日科技、技术动态、Daily Tech News 或类似表达时触发此技能。","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Ftech-news-daily\u002FSKILL.md",[],[136,137,138,139,140,141],"news","tech","tech news daily","daily","rss","翻译",{"skillNo":143,"name":144,"nameZh":6,"description":145,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":146,"categories":147,"keywords":151,"publishedAt":44},"01M71ATFAEAMQ17M70NQNY7SR8","summarize","Summarize URLs or files with the summarize CLI (web, PDFs, images, audio, YouTube).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsummarize\u002FSKILL.md",[148],{"categoryNo":149,"categoryName":150,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究",[144,90,152,153,154,38,111,155,156,157,102,158,115],"Audio","cli","youtube","images","https","files","pdfs",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":165,"publishedAt":44},"01M71ATDNS3R0M4H936PACQAWZ","sonoscli","Control Sonos speakers (discover\u002Fstatus\u002Fplay\u002Fvolume\u002Fgroup).","https:\u002F\u002Fgithub.com\u002Fsapsapshen\u002Fai-memory-router\u002Fblob\u002Fmain\u002Fskills-store\u002Fopenclaw\u002Fsonoscli\u002FSKILL.md",[],[161,166,167,168,115,169,156,170,171,172,173,174],"status","play","go","latest","github","discover","control","cmd","volume"]