diff --git a/.changeset/docker-development-setup.md b/.changeset/docker-development-setup.md new file mode 100644 index 0000000..cab3d24 --- /dev/null +++ b/.changeset/docker-development-setup.md @@ -0,0 +1,5 @@ +--- +"@jmfederico/pi-web": patch +--- + +Add a Docker development setup that builds from the local checkout while keeping the session daemon separate from autoreloading web/API/client services. diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..34f60e9 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,9 @@ +.git +node_modules +dist +.pi-web +.playwright-cli +dev-plugins +*.log +.env +.DS_Store diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev new file mode 100644 index 0000000..cdd5afc --- /dev/null +++ b/docker/Dockerfile.dev @@ -0,0 +1,52 @@ +# syntax=docker/dockerfile:1.7 + +ARG NODE_VERSION=22-bookworm-slim +ARG DOCKER_CLI_VERSION=29-cli + +FROM docker:${DOCKER_CLI_VERSION} AS docker-cli + +FROM node:${NODE_VERSION} AS dev + +ENV NODE_ENV=development \ + NPM_CONFIG_UPDATE_NOTIFIER=false \ + NPM_CONFIG_CACHE=/data/npm-cache \ + HOME=/data/home \ + XDG_CONFIG_HOME=/data/config \ + PI_WEB_DATA_DIR=/data/pi-web \ + PI_WEB_SESSIOND_SOCKET=/data/pi-web/sessiond.sock \ + PI_CODING_AGENT_DIR=/data/pi-agent \ + HOSTEXEC_IMAGE=alpine:3.22 \ + SHELL=/bin/bash \ + TERM=xterm-256color + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + bash \ + ca-certificates \ + curl \ + g++ \ + git \ + make \ + openssh-client \ + procps \ + python3 \ + tini \ + && rm -rf /var/lib/apt/lists/* + +WORKDIR /workspace + +COPY package.json package-lock.json ./ +COPY scripts/install-git-hooks.mjs scripts/install-git-hooks.mjs +RUN npm ci \ + && npm cache clean --force \ + && mkdir -p /data/home /data/config /data/npm-cache /data/pi-web /data/pi-agent \ + && chmod -R a+rwX /workspace/node_modules /data \ + && chmod 0777 /workspace + +COPY --from=docker-cli /usr/local/bin/docker /usr/local/bin/docker +COPY --chmod=0755 docker/bin/hostexec /usr/local/bin/hostexec + +EXPOSE 8504 8505 + +ENTRYPOINT ["tini", "--"] +CMD ["npm", "run", "dev"] diff --git a/docker/compose.dev.yml b/docker/compose.dev.yml new file mode 100644 index 0000000..c85fe2a --- /dev/null +++ b/docker/compose.dev.yml @@ -0,0 +1,95 @@ +name: pi-web-dev + +x-pi-web-dev-build: &pi-web-dev-build + context: .. + dockerfile: docker/Dockerfile.dev + +x-pi-web-dev-environment: &pi-web-dev-environment + HOME: /data/home + XDG_CONFIG_HOME: /data/config + PI_WEB_DATA_DIR: /data/pi-web + PI_WEB_SESSIOND_SOCKET: /data/pi-web/sessiond.sock + PI_CODING_AGENT_DIR: /data/pi-agent + HOSTEXEC_IMAGE: ${HOSTEXEC_IMAGE:-alpine:3.22} + PI_WEB_MAX_UPLOAD_BYTES: ${PI_WEB_MAX_UPLOAD_BYTES:-67108864} + NPM_CONFIG_UPDATE_NOTIFIER: "false" + NPM_CONFIG_CACHE: /data/npm-cache + +x-pi-web-dev-volumes: &pi-web-dev-volumes + - type: bind + source: .. + target: /workspace + - type: volume + source: node_modules + target: /workspace/node_modules + - type: volume + source: data + target: /data + - type: bind + source: /var/run/docker.sock + target: /var/run/docker.sock + - type: bind + source: /srv + target: /srv + - type: bind + source: /opt + target: /opt + - type: bind + source: /home + target: /home + - type: bind + source: / + target: /host + read_only: true + +services: + sessiond: + build: *pi-web-dev-build + image: ${PI_WEB_DEV_IMAGE:-pi-web:dev} + command: ["npm", "run", "start:sessiond"] + working_dir: /workspace + user: "${PI_WEB_UID:-1000}:${PI_WEB_GID:-1000}" + group_add: + - "${DOCKER_GID:-0}" + security_opt: + - label=disable + environment: *pi-web-dev-environment + volumes: *pi-web-dev-volumes + healthcheck: + test: ["CMD-SHELL", "test -S /data/pi-web/sessiond.sock"] + interval: 5s + timeout: 3s + retries: 24 + start_period: 5s + + web: + build: *pi-web-dev-build + image: ${PI_WEB_DEV_IMAGE:-pi-web:dev} + command: ["bash", "-lc", "trap 'kill 0' EXIT; npm run dev:web & npm run dev:client & wait"] + working_dir: /workspace + depends_on: + sessiond: + condition: service_healthy + user: "${PI_WEB_UID:-1000}:${PI_WEB_GID:-1000}" + group_add: + - "${DOCKER_GID:-0}" + security_opt: + - label=disable + environment: + <<: *pi-web-dev-environment + PI_WEB_HOST: 0.0.0.0 + PI_WEB_PORT: "8504" + ports: + - "${PI_WEB_DEV_API_BIND_ADDR:-127.0.0.1}:${PI_WEB_DEV_API_PORT:-8504}:8504" + - "${PI_WEB_DEV_BIND_ADDR:-127.0.0.1}:${PI_WEB_DEV_PORT:-8505}:8505" + volumes: *pi-web-dev-volumes + healthcheck: + test: ["CMD-SHELL", "curl -fsS http://127.0.0.1:8504/api/pi-web/runtime >/dev/null"] + interval: 10s + timeout: 5s + retries: 12 + start_period: 10s + +volumes: + data: + node_modules: