mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
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:
@@ -0,0 +1,60 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
FROM golang:1.25-alpine
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
RUN go install github.com/air-verse/air@latest
|
||||
|
||||
RUN apk add --no-cache \
|
||||
bash \
|
||||
ca-certificates \
|
||||
cni-plugins \
|
||||
containerd \
|
||||
containerd-ctr \
|
||||
git \
|
||||
iptables \
|
||||
make \
|
||||
tzdata \
|
||||
wget \
|
||||
&& mkdir -p /opt/cni/bin \
|
||||
&& (cp -a /usr/lib/cni/. /opt/cni/bin/ 2>/dev/null || true) \
|
||||
&& (cp -a /usr/libexec/cni/. /opt/cni/bin/ 2>/dev/null || true) \
|
||||
&& mkdir -p /etc/cni/net.d /var/lib/cni /run/containerd /var/lib/containerd /opt/memoh/data
|
||||
|
||||
RUN printf '%s\n' \
|
||||
'{' \
|
||||
' "cniVersion": "1.0.0",' \
|
||||
' "name": "memoh-cni",' \
|
||||
' "plugins": [' \
|
||||
' {' \
|
||||
' "type": "bridge",' \
|
||||
' "bridge": "cni0",' \
|
||||
' "isGateway": true,' \
|
||||
' "ipMasq": true,' \
|
||||
' "hairpinMode": true,' \
|
||||
' "ipam": {' \
|
||||
' "type": "host-local",' \
|
||||
' "ranges": [[' \
|
||||
' { "subnet": "10.88.0.0/16" }' \
|
||||
' ]],' \
|
||||
' "routes": [' \
|
||||
' { "dst": "0.0.0.0/0" }' \
|
||||
' ]' \
|
||||
' }' \
|
||||
' },' \
|
||||
' {' \
|
||||
' "type": "portmap",' \
|
||||
' "capabilities": { "portMappings": true }' \
|
||||
' }' \
|
||||
' ]' \
|
||||
'}' > /etc/cni/net.d/10-memoh.conflist
|
||||
|
||||
COPY docker/server-dev-entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
VOLUME ["/var/lib/containerd", "/opt/memoh/data"]
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM node:25-alpine
|
||||
RUN npm install -g pnpm@10
|
||||
WORKDIR /workspace
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Setup cgroup v2 delegation for nested containerd.
|
||||
if [ -f /sys/fs/cgroup/cgroup.controllers ]; then
|
||||
mkdir -p /sys/fs/cgroup/init
|
||||
while read -r pid; do
|
||||
echo "$pid" > /sys/fs/cgroup/init/cgroup.procs 2>/dev/null || true
|
||||
done < /sys/fs/cgroup/cgroup.procs
|
||||
|
||||
sed -e 's/ / +/g' -e 's/^/+/' < /sys/fs/cgroup/cgroup.controllers \
|
||||
> /sys/fs/cgroup/cgroup.subtree_control 2>/dev/null || true
|
||||
fi
|
||||
|
||||
mkdir -p /run/containerd
|
||||
containerd &
|
||||
CONTAINERD_PID=$!
|
||||
|
||||
echo "Waiting for containerd..."
|
||||
for i in $(seq 1 30); do
|
||||
if ctr version >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if ! ctr version >/dev/null 2>&1; then
|
||||
echo "ERROR: containerd not responsive after 30s"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "containerd is ready, starting server command..."
|
||||
|
||||
trap 'kill ${SERVER_PID:-0} 2>/dev/null || true; kill ${CONTAINERD_PID:-0} 2>/dev/null || true; wait' TERM INT
|
||||
|
||||
"$@" &
|
||||
SERVER_PID=$!
|
||||
|
||||
wait $SERVER_PID
|
||||
EXIT_CODE=$?
|
||||
|
||||
kill $CONTAINERD_PID 2>/dev/null || true
|
||||
wait $CONTAINERD_PID 2>/dev/null || true
|
||||
|
||||
exit $EXIT_CODE
|
||||
Reference in New Issue
Block a user