Skip to content

fix(container): pass --ssh-identity-file to scp in container cp - #2187

Merged
martin-helmich merged 2 commits into
masterfrom
fix/container-cp-identity-file
Nov 2, 2026
Merged

martin-helmich merged 2 commits into
masterfrom
fix/container-cp-identity-file

Conversation

@Hermsi1337

@Hermsi1337 Hermsi1337 commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

Closes #2186

container cp had --ssh-identity-file in its flags but never handed it to scp. The scp args are now built in buildScpArgs (src/lib/resources/ssh/scp.ts), which adds -i <file> when set, same as buildSSHClientFlags does for ssh. Without the flag the args are exactly as before.

Unit tests cover -i placement, paths with spaces, the unset case and -p/-r.

This also matters for the Docker image (#2183): there the key gets mounted at an arbitrary path and passed via MITTWALD_SSH_IDENTITY_FILE, which so far only worked for everything except container cp.

ScpArgsOptions requires the ssh-identity-file key (Pick<SSHConnectionFlags, ...>), so a caller dropping it fails to compile instead of silently losing the key again.

martin-helmich pushed a commit that referenced this pull request Nov 2, 2026
Closes #2182

The Docker image had no `ssh` and no `rsync`, so every SSH-based command
(`container exec|cp|port-forward`, `app ssh`, `app download|upload`,
...) failed in the container.

- install `openssh-client` and `rsync` in the runtime image
- `GatewayPorts yes` in `/etc/ssh/ssh_config.d/`, so `port-forward`
binds to the container interface and the port can be published with
`docker run -p`. This only affects the container's own network
namespace. With `--network host` the forwarding would listen on all host
interfaces though, so the README example uses `-p 127.0.0.1:...`
- README: how to mount the SSH key and set `MITTWALD_SSH_IDENTITY_FILE`
- README: shell function for `~/.bashrc`/`~/.zshrc` to use the image
like a local `mw`. It only adds `-t` when stdin and stdout are
terminals, so pipes work, and the key is configurable via `MW_SSH_KEY`
(only that one key gets mounted). Keys are mounted with `--mount
...,readonly`, so a missing key fails instead of docker creating a
directory. Plus notes on root-owned downloads on Linux, paths outside
the working dir, and not combining port forwarding with `--network host`
- CI: the docker job checks that `ssh`, `scp`, `ssh-keygen`, `rsync` and
`GatewayPorts yes` are in the image

Tested with an image built from this Dockerfile and the v1.28.1
linux-arm64 release tarball: `container exec`, `app download --dry-run`
and `container port-forward` (HTTP 301 from the container through `-p
127.0.0.1:18080:18080`) worked against a real project.




`container cp` only honors `MITTWALD_SSH_IDENTITY_FILE` with #2187,
until then it only finds keys at the default `~/.ssh/id_*` paths.

Follow-ups after testing: the `mw()` function only mounts the key if it
exists (token-only commands work without a key), the port-forward
example passes `--project-id` (no persisted context in a fresh
container), and the ownership note now also covers rsync keeping the
remote numeric owner.
@martin-helmich
martin-helmich merged commit e1f5ce9 into master Nov 2, 2026
11 checks passed
@martin-helmich
martin-helmich deleted the fix/container-cp-identity-file branch November 2, 2026 09:49
mittwald-machine added a commit that referenced this pull request Nov 2, 2026
# [1.29.0](v1.28.1...v1.29.0) (2026-11-02)

### Bug Fixes

* **container:** pass --ssh-identity-file to scp in container cp ([#2187](#2187)) ([e1f5ce9](e1f5ce9)), closes [#2186](#2186) [#2183](#2183)

### Features

* **docker:** run as the host user via MW_UID/MW_GID ([#2189](#2189)) ([4e2fcb7](4e2fcb7)), closes [#2188](#2188)
* **docker:** support ssh-based commands in the docker image ([#2183](#2183)) ([59059fa](59059fa)), closes [#2182](#2182) [#2187](#2187)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

container cp ignores --ssh-identity-file

2 participants