Sign inSign up

codeyhj/opencode-docker

By codeyhj

•Updated 3 months ago

Image
1

10K+

codeyhj/opencode-docker repository overview

⁠opencode 容器

⁠内置环境

  • nodejs@24

⁠内置默认 opencode.json 配置

{
  "$schema": "https://opencode.ai/config.json",
  "instructions": ["/root/.config/opencode/AGENTS.md"],
  "autoupdate": false,
  "username": "xxx",
  "provider": {
    "deepseek": {
      "models": {
        "deepseek-chat": {
          "limit": {
            "context": 131000,
            "output": 8192
          }
        }
      }
    },
    "zijie": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "字节",
      "options": {
        "baseURL": "https://ark.cn-beijing.volces.com/api/v3/",
        "apiKey": ""
      },
      "models": {
        "ep-20250824014338-qzsrc": {
          "name": "DeepSeek V3.1"
        },
        "ep-20250824015723-gv5pd": {
          "name": "Kimi K2"
        },
        "ep-20250824020300-vgvm2": {
          "name": "Doubao Seed 1.6 Thinking"
        }
      }
    },

    "modelscope": {
      "options": {
        "baseURL": "https://api-inference.modelscope.cn/v1/"
      },
      "models": {
        "ZhipuAI/GLM-4.5": {
          "name": "ZhipuAI/GLM-4.5",
          "tool_call": true
        },
        "ZhipuAI/GLM-4.6": {
          "name": "ZhipuAI/GLM-4.6",
          "tool_call": true
        },
        "moonshotai/Kimi-K2-Instruct": {
          "name": "moonshotai/Kimi-K2-Instruct"
        },
        "Qwen/Qwen3-Coder-480B-A35B-Instruct": {
          "name": "Qwen/Qwen3-Coder-480B-A35B-Instruct"
        },
        "Qwen/Qwen3-Coder-30B-A3B-Instruct": {
          "name": "Qwen/Qwen3-Coder-30B-A3B-Instruct"
        },
        "Qwen/Qwen3-30B-A3B-Instruct-2507": {
          "name": "Qwen/Qwen3-30B-A3B-Instruct-2507"
        },
        "Qwen/Qwen3-30B-A3B-Thinking-2507": {
          "name": "Qwen/Qwen3-30B-A3B-Thinking-2507"
        },
        "Qwen/Qwen3-235B-A22B-Instruct-2507": {
          "name": "Qwen/Qwen3-235B-A22B-Instruct-2507"
        },
        "Qwen/Qwen3-235B-A22B-Thinking-2507": {
          "name": "Qwen/Qwen3-235B-A22B-Thinking-2507"
        }
      }
    },
    "bigmodel": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "bigmodel",
      "options": {
        "baseURL": "https://open.bigmodel.cn/api/paas/v4"
      },
      "models": {
        "glm-4.5-air": {
          "name": "glm-4.5-air"
        }
      }
    },
    "moonshot": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "moonshot",
      "options": {
        "baseURL": "https://api.moonshot.cn/v1"
      },
      "models": {
        "kimi-k2-0711-preview": {
          "id": "kimi-k2-0711-preview",
          "limit": {
            "context": 131000,
            "output": 8192
          }
        }
      }
    },
    "openrouter": {
      "name": "openrouter",
      "options": {
        "baseURL": "https://openrouter.ai/api/v1"
      },
      "models": {
        "z-ai/glm-4.5-air:free": {
          "name": "z-ai/glm-4.5-air:free",
          "tool_call": true
        }
      }
    }
  },
  "theme": "system"
}

⁠config-protection.ts

opencode 将会自动读取

容器内存放路径: .config/opencode/plugin/config-protection.ts

import type { Plugin } from "@opencode-ai/plugin";

export const ConfigProtection: Plugin = async ({
  project,
  client,
  $,
  directory,
  worktree,
}) => {
  // 定义受保护的文件模式
  const protectedPatterns = [
    // 环境变量文件
    ".env",
    ".env.local",
    ".env.development",
    ".env.production",
    ".env.test",

    // 密钥和凭证文件
    "secrets.json",
    "credentials.yml",
    "credentials.yaml",
    ".aws/credentials",
    ".ssh/id_rsa",
    ".ssh/id_ed25519",

    // 数据库配置
    "database.yml",
    "database.json",

    // API 密钥
    "api-keys.json",
    ".apikeys",
  ];

  // 可选:定义允许的例外情况
  const allowedPatterns = [".env.example", ".env.template"];

  return {
    "tool.execute.before": async (input, output) => {
      // 只拦截 read 工具
      if (input.tool !== "read") return;

      const filePath = output.args.filePath;

      // 检查是否在允许列表中
      const isAllowed = allowedPatterns.some((pattern) =>
        filePath.includes(pattern)
      );
      if (isAllowed) return;

      // 检查是否匹配受保护的模式
      const isProtected = protectedPatterns.some((pattern) =>
        filePath.includes(pattern)
      );

      if (isProtected) {
        throw new Error(
          `🔒 Access denied: "${filePath}" is a protected configuration file.\n` +
            `This file contains sensitive information and cannot be read by AI agents.`
        );
      }
    },
  };
};

⁠run

version: "3.9"

services:
  claude-dev:
    image: dockerhub.pi-hcm.com/codeyhj/opencode-docker:latest
    container_name: opencode
    init: true # 对应 runArgs: ["--init"]
    user: root # remoteUser
    working_dir: /workspace # workspaceFolder
    volumes:
      # pnpm store
      - ${HOME}/.pnpm-store:/pnpm-store
      # 开发目录
      - ${HOME}/xxxx:/workspace/xxxx:cached
      # 持久化所有会话历史、消息记录和认证信息
      - ${HOME}/code/config/opencode/share/opencode:/root/.local/share/opencode:cached
      # 持久化全局配置、自定义 agents 和 commands
      - ${HOME}/code/config/opencode/.config/opencode:/root/.config/opencode:cached
      # 挂载状态目录(输入历史)
      - ${HOME}/code/config/opencode/state/opencode:/root/.local/state/opencode
    tty: true
    stdin_open: true
    command: /bin/bash -c "echo '🚀 Dev container ready!' && bash"

Tag summary

Content type

Image

Digest

sha256:3d298b67c…

Size

531.7 MB

Last updated

3 months ago

docker pull codeyhj/opencode-docker