sotashimozono_obsidian-remo.../deploy/docker/entrypoint.sh
Souta adf068c944 feat(deploy): Phase E4-a.A — turn-key docker-compose sshd container (0.4.36)
First piece of E4-a (turn-key deploy). Drops a docker-compose +
Dockerfile under `deploy/docker/` so a user can stand up an SSH
endpoint the plugin can connect to without touching the host's own
sshd. Three commands and a public key get them going:

  cp ~/.ssh/id_ed25519.pub ./authorized_keys
  mkdir -p ./vault ./hostkeys
  docker compose up -d --build

Pieces:

- `deploy/docker/Dockerfile` — Alpine + openssh-server + a single
  `obsidian` user (uid 1000). Pubkey-only auth, no root login,
  StrictModes ON. tini for PID 1 reaping.
- `deploy/docker/entrypoint.sh` — generates persistent host keys on
  first launch (kept in a bind-mount volume so container recreates
  don't trigger a TOFU storm), re-owns the bind-mounted vault dir
  to uid 1000, then exec's sshd.
- `deploy/docker/docker-compose.yml` — vault + authorized_keys +
  hostkeys volumes. Defaults to host port 2222; every knob is
  env-var overridable.
- `deploy/docker/.env.example` — copy-and-tweak template.
- `deploy/docker/README.md` — quick-start, customisation table,
  operational notes (multiple keys, backup, rotation, firewall),
  troubleshooting table.
- `deploy/docker/.gitignore` — ignores per-deployment artefacts so
  users running compose from a `git clone` don't accidentally
  commit their authorized_keys / vault / hostkeys.
- `deploy/README.md` — top-level overview comparing this option
  against the planned systemd + one-line-installer paths.
- `.gitattributes` (new) — forces LF for shell scripts,
  Dockerfiles, .mjs, Makefiles, .go so a Windows checkout can't
  commit CRLF and break the container build.

CI:

- `.github/workflows/ci.yml` — adds a `deploy-docker` job that
  builds the deploy Dockerfile so a regression surfaces in CI
  rather than when a user actually tries to deploy.

Plugin: no plugin code changes; the existing auto-deploy flow lands
the daemon binary under `~/.obsidian-remote/` on first connect, same
as before. Version bump to 0.4.36 keeps the per-PR cadence consistent.

E4-a.B (systemd unit + shared daemon for multi-device) and E4-a.C
(`curl ... | bash` installer) are deferred per the deploy README's
status table — the shared-daemon model needs plugin changes that are
better grouped with E3 (multi-vault per session).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 16:20:11 +09:00

47 lines
1.7 KiB
Bash

#!/bin/sh
# entrypoint:
# - generate persistent host keys on first launch (none yet present
# in the bind-mounted /etc/ssh/keys volume),
# - re-own the bind-mounted vault dir so the in-container `obsidian`
# user (uid 1000) can write into it regardless of what host uid
# created the dir,
# - then exec the CMD (sshd by default).
set -e
KEYDIR=/etc/ssh/keys
mkdir -p "$KEYDIR"
# Each algorithm gets its own key file. Generate only the ones that
# don't already exist in the persistent volume.
for algo in rsa ecdsa ed25519; do
key="$KEYDIR/ssh_host_${algo}_key"
if [ ! -f "$key" ]; then
echo "entrypoint: generating $algo host key (one-time, persisted in volume)"
ssh-keygen -q -t "$algo" -N '' -f "$key"
fi
done
chmod 600 "$KEYDIR"/ssh_host_*_key 2>/dev/null || true
# Re-own the bind-mounted vault. Bind mounts inherit the host uid,
# which almost certainly isn't 1000; chown lets the obsidian user
# read/write its own vault. `|| true` so a noop run (no bind mount)
# still starts up.
chown -R obsidian:obsidian /home/obsidian/vault 2>/dev/null || true
# Bind-mounted authorized_keys files arrive read-only (recommended
# in compose) so we can't chmod/chown them, but sshd is happy with
# any owner as long as StrictModes can verify the path. If the
# bind-mount is owned by a different host uid sshd will refuse it;
# tell the user how to fix in that case rather than silently
# falling back to no-auth.
if [ -f /home/obsidian/.ssh/authorized_keys ]; then
if ! sshd -t 2>/tmp/sshd-check.err; then
echo "entrypoint: sshd config failed pre-check:"
cat /tmp/sshd-check.err >&2
echo "entrypoint: hint — authorized_keys must be readable by uid 1000 (the obsidian user)" >&2
exit 1
fi
fi
exec "$@"