feat(devenv): add containerized development environment (#116)

* feat(devenv): add containerized development environment

Replace local-process dev workflow with a fully containerized stack
using docker compose. This enables consistent development across
machines without requiring local Go/Node toolchains or containerd.

- Add Dockerfile.server.dev with containerd + CNI networking support
- Add Dockerfile.web.dev for frontend dev server
- Add server-dev-entrypoint.sh for containerd lifecycle management
- Expand devenv/docker-compose.yml with server, agent, web, migrate
  and deps services with proper health checks and dependency ordering
- Update app.dev.toml to use container service names instead of localhost
- Refactor mise.toml dev tasks to drive docker compose workflow
- Support agent_gateway.server_addr in config package for inter-container
  communication

* feat(devenv): add hot-reload and registry mirror support

- Add air for Go server hot-reload in dev containers
- Fix agent_gateway host in dev config (0.0.0.0 -> agent)
- Add configurable registry mirror for China mainland users
- Unify MCP image refs via MCPConfig.ImageRef()

* feat(scripts): add China mainland mirror option to install script

Prompt users to opt-in to memoh.cn mirror during installation,
which applies docker-compose.cn.yml overlay and sets registry
in config.toml for MCP image pulls.
This commit is contained in:
BBQ
2026-02-26 17:32:19 +08:00
committed by GitHub
parent 19ab2fef3a
commit d6aebf654f
19 changed files with 354 additions and 103 deletions
+15 -14
View File
@@ -17,19 +17,20 @@ email = "dev@memoh.local"
jwt_secret = "memoh-dev-secret-do-not-use-in-production"
jwt_expires_in = "168h"
# Containerd is typically not available in local development.
# Uncomment and configure if you have containerd running locally.
# [containerd]
# socket_path = "/run/containerd/containerd.sock"
# namespace = "default"
[containerd]
socket_path = "/run/containerd/containerd.sock"
namespace = "default"
# [mcp]
# image = "docker.io/library/memoh-mcp:dev"
# snapshotter = "overlayfs"
# data_root = "data"
[mcp]
# registry = "memoh.cn" # Uncomment for China mainland mirror
image = "memohai/mcp:latest"
snapshotter = "overlayfs"
data_root = "/opt/memoh/data"
cni_bin_dir = "/opt/cni/bin"
cni_conf_dir = "/etc/cni/net.d"
[postgres]
host = "127.0.0.1"
host = "postgres"
port = 5432
user = "memoh"
password = "memoh123"
@@ -37,16 +38,16 @@ database = "memoh"
sslmode = "disable"
[qdrant]
base_url = "http://127.0.0.1:6334"
base_url = "http://qdrant:6334"
api_key = ""
collection = "memory"
timeout_seconds = 10
[agent_gateway]
host = "127.0.0.1"
host = "agent"
port = 8081
server_addr = ":8080"
server_addr = "server:8080"
[web]
host = "127.0.0.1"
host = "0.0.0.0"
port = 8082
+2 -1
View File
@@ -23,7 +23,8 @@ socket_path = "/run/containerd/containerd.sock"
namespace = "default"
[mcp]
image = "docker.io/library/memoh-mcp:latest"
# registry = "memoh.cn" # Uncomment for China mainland mirror
image = "memohai/mcp:latest"
snapshotter = "overlayfs"
data_root = "/opt/memoh/data"
+2 -1
View File
@@ -23,7 +23,8 @@ socket_path = "/run/containerd/containerd.sock"
namespace = "default"
[mcp]
image = "docker.io/library/memoh-mcp:dev"
# registry = "memoh.cn" # Uncomment for China mainland mirror
image = "memohai/mcp:latest"
snapshotter = "overlayfs"
data_root = "data"
cni_bin_dir = "/opt/cni/bin"
+2 -1
View File
@@ -24,7 +24,8 @@ socket_path = "npipe:////./pipe/containerd-containerd"
namespace = "default"
[mcp]
image = "docker.io/library/memoh-mcp:dev"
# registry = "memoh.cn" # Uncomment for China mainland mirror
image = "memohai/mcp:latest"
snapshotter = "overlayfs"
data_root = "data"