mirror of
https://github.com/penpot/penpot.git
synced 2026-10-28 21:40:34 +00:00
🔧 Install opencode on demand instead of baking it in
The opencode build stage was already commented out, so the image carried a dead block and a commented COPY. Drop both: opencode now comes from scripts/setup-opencode, which installs @opencode/cli as a global pnpm package in the penpot user's $PNPM_HOME. That dir sits in the user-data volume, so the install survives a container re-creation and needs no root. pnpm 12 keeps the global binaries in $PNPM_HOME/bin, so put that dir on PATH in the bashrc (and make the guard check the same path) instead of $PNPM_HOME, which left the commands unreachable. The entrypoint now also chowns ~/.local, ~/.cache and the dotfiles it copies from /root. EXTERNAL_UID remaps penpot to the host UID on every start, so the ownership the image set at build time stops matching; that broke global pnpm installs and pnpm's own packageManager download. AI-assisted-by: deepseek-v4.1-flash
This commit is contained in:
parent
d1aa36b814
commit
016c3976d0
@ -60,6 +60,7 @@ The memory is structured in a way that you can get the critical information abou
|
||||
- `scripts/changelog.py` — Changelog checks for the `update-changelog` skill: `check-merged` (PR merge status), `cross-ref` (milestone PRs vs changelog section), `report` (anomaly report to CHANGES-ISSUES.md). Calls `scripts/gh.py` via subprocess. See `mem:scripts/changelog`.
|
||||
- `scripts/error-reports.mjs` — Query error reports via RPC API with token authentication. Supports list/get operations with filtering and pagination. See `mem:scripts/error-reports`.
|
||||
- `scripts/clean-node-modules` — Remove stale `node_modules` from all pnpm workspaces (root, modules, member packages). Keeps the shared pnpm store at `<repo>/.pnpm-store` unless `--store`; ignores `external/` and `.opencode/`. Usage and reinstall steps: `mem:workflow/updating-pnpm`.
|
||||
- `scripts/setup-opencode` — Install the opencode CLI in-container as a global pnpm package in `$PNPM_HOME`. Not part of the devenv image; see `mem:devenv/core`.
|
||||
- `scripts/ci` — CI orchestration script: runs lint, tests, and format checks per module (`frontend backend common render-wasm exporter mcp plugins library`). Logs go to `.ci-logs/`; read the log file on failure. See `mem:scripts/ci`.
|
||||
|
||||
# Dependency graph
|
||||
|
||||
@ -24,6 +24,8 @@ Compose-based dev environment under `docker/devenv/`, driven by `manage.sh`. Par
|
||||
- Network aliases (`- main`, `- redis`) are not declared in main.yml. Compose's auto-service-alias still registers `redis` on the shared network, so DNS for `redis` is non-deterministic with multiple instances. Backend uses `PENPOT_REDIS_URI=redis://penpot-devenv-wsN-valkey/0` (container_name) instead.
|
||||
- No cross-project `depends_on`. `manage.sh ensure-infra-up` uses Compose `--wait`; PostgreSQL, RustFS, and Mailpit expose healthchecks. PostgreSQL checks TCP so its temporary init server cannot report ready.
|
||||
- `JAVA_OPTS` in `manage.sh` is shadowed inside the container by `_env`. The `-e JAVA_OPTS=...` flag only matters for processes that don't source `_env`.
|
||||
- opencode is not part of the devenv image. `scripts/setup-opencode` installs the `@opencode/cli` global pnpm package into the penpot user's `$PNPM_HOME` (`/home/penpot/.local/share/pnpm`, inside the user-data volume, so it survives a container re-creation); nothing pins the version in the repo, it tracks the `latest` dist-tag at install time. pnpm 12 puts the global packages in `$PNPM_HOME/global` and the bin dir in `$PNPM_HOME/bin`, and aborts with `ERR_PNPM_GLOBAL_BIN_DIR_NOT_IN_PATH` unless that bin dir is on `PATH`; `files/bashrc` and the script both add it. The script exports `PNPM_HOME` itself because non-interactive shells never read `~/.bashrc`.
|
||||
- `files/entrypoint.sh` chowns penpot's whole `~/.local` and `~/.cache` on every start, because `EXTERNAL_UID` remaps penpot's UID to the host user and build-time ownership then stops matching. That covers pnpm's global dir, store, `package-manager-store` and metadata cache, plus opencode's own state; without it, global installs and pnpm's `packageManager` auto-download fail on permissions. The dotfiles copied from `/root` (`.bashrc`, `.vimrc`, `.tmux.conf`) are chowned in the same pass. `~/.config` stays out on purpose (the opencode overlay bind-mounts a host directory inside it) and so does `/home/penpot` itself, which holds the repo bind mount.
|
||||
|
||||
## Worker policy
|
||||
|
||||
|
||||
@ -33,7 +33,9 @@ file (never pipe tool output through filters).
|
||||
images). Nothing may call corepack: it is gone from Node 25+. pnpm
|
||||
auto-downloads the `packageManager` version on mismatch
|
||||
(`pmOnFail: download`, the default), so drift self-heals; aligned pins
|
||||
just skip the download.
|
||||
just skip the download. Inside the devenv that download lands in the
|
||||
penpot user's `package-manager-store`, which `files/entrypoint.sh` chowns
|
||||
to penpot on every start (see `mem:devenv/core`).
|
||||
- The pnpm version pin lives in three places that move together:
|
||||
`PNPM_VERSION` (+ arch SHAs) in `docker/devenv/Dockerfile` and in
|
||||
`docker/images/Dockerfile.{media-processor,exporter,mcp}`, and the
|
||||
|
||||
@ -103,37 +103,6 @@ RUN set -eux; \
|
||||
find /opt/node/include/node/openssl/archs -mindepth 1 -maxdepth 1 ! -name "$OPENSSL_ARCH" -exec rm -rf {} \; ; \
|
||||
rm -f /tmp/nodejs.tar.gz /tmp/pnpm.tar.gz;
|
||||
|
||||
################################################################################
|
||||
## OPENCODE SETUP
|
||||
################################################################################
|
||||
|
||||
# FROM base AS setup-opencode
|
||||
|
||||
# ENV OPENCODE_VERSION=2.0.29
|
||||
|
||||
# RUN set -eux; \
|
||||
# ARCH="$(dpkg --print-architecture)"; \
|
||||
# case "${ARCH}" in \
|
||||
# aarch64|arm64) \
|
||||
# BINARY_URL="https://registry.npmjs.org/@opencode/cli-linux-arm64/-/cli-linux-arm64-${OPENCODE_VERSION}.tgz"; \
|
||||
# ESUM='0af39e75dbdfacc20f8f531ef35fb4dcc0b44c08084203518614272f232283ae'; \
|
||||
# ;; \
|
||||
# amd64|x86_64) \
|
||||
# BINARY_URL="https://registry.npmjs.org/@opencode/cli-linux-x64/-/cli-linux-x64-${OPENCODE_VERSION}.tgz"; \
|
||||
# ESUM='14b5a6638a1a093ac9d484599c844b10c29b445d04844b682ccc668ce26530a2'; \
|
||||
# ;; \
|
||||
# *) \
|
||||
# echo "Unsupported arch: ${ARCH}"; exit 1; \
|
||||
# ;; \
|
||||
# esac; \
|
||||
# curl -LfsSo /tmp/opencode.tgz "${BINARY_URL}"; \
|
||||
# echo "${ESUM} */tmp/opencode.tgz" | sha256sum -c -; \
|
||||
# mkdir -p /tmp/opencode; \
|
||||
# tar -xzf /tmp/opencode.tgz -C /tmp/opencode --strip-components=2 package/bin; \
|
||||
# chmod +x /tmp/opencode/opencode; \
|
||||
# rm -f /tmp/opencode.tgz;
|
||||
|
||||
|
||||
################################################################################
|
||||
## CADDYSERVER SETUP
|
||||
################################################################################
|
||||
@ -558,7 +527,6 @@ COPY --from=setup-rust /opt/cargo /opt/cargo
|
||||
COPY --from=setup-rust /opt/rustup /opt/rustup
|
||||
COPY --from=setup-rust /opt/emsdk /opt/emsdk
|
||||
COPY --from=setup-caddy /usr/bin/caddy /usr/bin/caddy
|
||||
# COPY --from=setup-opencode /tmp/opencode/opencode /opt/utils/bin/opencode
|
||||
|
||||
COPY files/nginx.conf /etc/nginx/nginx.conf
|
||||
COPY files/nginx-mime.types /etc/nginx/mime.types
|
||||
|
||||
@ -27,7 +27,7 @@ fi
|
||||
# pnpm
|
||||
export PNPM_HOME="/home/penpot/.local/share/pnpm"
|
||||
case ":$PATH:" in
|
||||
*":$PNPM_HOME:"*) ;;
|
||||
*) export PATH="$PNPM_HOME:$PATH" ;;
|
||||
*":$PNPM_HOME/bin:"*) ;;
|
||||
*) export PATH="$PNPM_HOME/bin:$PATH" ;;
|
||||
esac
|
||||
# pnpm end
|
||||
|
||||
@ -10,6 +10,10 @@ cp /root/.bashrc /home/penpot/.bashrc
|
||||
cp /root/.vimrc /home/penpot/.vimrc
|
||||
cp /root/.tmux.conf /home/penpot/.tmux.conf
|
||||
|
||||
chown -R penpot:penpot /home/penpot/.bashrc
|
||||
chown -R penpot:penpot /home/penpot/.vimrc
|
||||
chown -R penpot:penpot /home/penpot/.tmux.conf
|
||||
|
||||
# Seed SERENA_HOME with default config on first run
|
||||
mkdir -p ${SERENA_HOME}
|
||||
if [ ! -f "${SERENA_HOME}/serena_config.yml" ]; then
|
||||
@ -21,6 +25,16 @@ chown penpot:users /home/penpot
|
||||
# we need to be able to install rust-analyzer and possibly other dependencies with rustup
|
||||
chown -R penpot:penpot /opt/rustup
|
||||
|
||||
# pnpm keeps its global dir (bin, global, store, package-manager-store)
|
||||
# under ~/.local and its metadata cache under ~/.cache; opencode and other
|
||||
# user-space tools write there too. Hand both trees back to penpot so
|
||||
# packages, and pnpm itself, can be updated without root. Needed because the
|
||||
# UID remap above can leave everything the image created owned by the old
|
||||
# UID. ~/.config is deliberately excluded: the opencode overlay bind-mounts
|
||||
# a host directory inside it.
|
||||
mkdir -p /home/penpot/.local /home/penpot/.cache
|
||||
chown -R penpot:penpot /home/penpot/.local /home/penpot/.cache
|
||||
|
||||
rsync -ar --chown=penpot:users /opt/cargo/ /home/penpot/.cargo/
|
||||
|
||||
export JAVA_OPTS="-Djava.net.preferIPv4Stack=true"
|
||||
|
||||
35
scripts/setup-opencode
Executable file
35
scripts/setup-opencode
Executable file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Install the opencode CLI as a global pnpm package.
|
||||
#
|
||||
# opencode is not part of the devenv image: run this when you want the
|
||||
# `opencode` and `opencode2` commands. The install lives in $PNPM_HOME, which
|
||||
# inside the devenv is the penpot home (the user-data volume), so it survives
|
||||
# a container re-creation.
|
||||
#
|
||||
# Usage: scripts/setup-opencode
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v pnpm >/dev/null 2>&1; then
|
||||
echo "setup-opencode: pnpm is not on PATH." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# pnpm installs global packages under $PNPM_HOME and refuses to run when its
|
||||
# bin dir is not on PATH: without this the install aborts with
|
||||
# ERR_PNPM_GLOBAL_BIN_DIR_NOT_IN_PATH. Non-interactive shells do not read
|
||||
# ~/.bashrc, so both are set here. The default is the directory pnpm itself
|
||||
# uses on Linux.
|
||||
export PNPM_HOME="${PNPM_HOME:-$HOME/.local/share/pnpm}"
|
||||
path_hint=0
|
||||
case ":$PATH:" in
|
||||
*":$PNPM_HOME/bin:"*) ;;
|
||||
*) path_hint=1; export PATH="$PNPM_HOME/bin:$PATH" ;;
|
||||
esac
|
||||
|
||||
pnpm add -g --allow-build=@opencode/cli @opencode/cli
|
||||
opencode --version
|
||||
|
||||
if [[ $path_hint -eq 1 ]]; then
|
||||
echo "note: $PNPM_HOME/bin is not on your PATH; add it to run 'opencode' directly." >&2
|
||||
fi
|
||||
Loading…
x
Reference in New Issue
Block a user