remote-docker-cli 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- remote_docker_cli-0.2.0/.gitignore +153 -0
- remote_docker_cli-0.2.0/PKG-INFO +396 -0
- remote_docker_cli-0.2.0/README.md +364 -0
- remote_docker_cli-0.2.0/pyproject.toml +68 -0
- remote_docker_cli-0.2.0/src/remote_docker/__init__.py +3 -0
- remote_docker_cli-0.2.0/src/remote_docker/__main__.py +3 -0
- remote_docker_cli-0.2.0/src/remote_docker/cli.py +986 -0
- remote_docker_cli-0.2.0/tests/docker-compose.yml +594 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
*.egg
|
|
26
|
+
MANIFEST
|
|
27
|
+
|
|
28
|
+
# PyInstaller
|
|
29
|
+
# Usually these files are written by a python script from a template
|
|
30
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
31
|
+
*.manifest
|
|
32
|
+
*.spec
|
|
33
|
+
|
|
34
|
+
# Installer logs
|
|
35
|
+
pip-log.txt
|
|
36
|
+
pip-delete-this-directory.txt
|
|
37
|
+
|
|
38
|
+
# Unit test / coverage reports
|
|
39
|
+
htmlcov/
|
|
40
|
+
.tox/
|
|
41
|
+
.nox/
|
|
42
|
+
.coverage
|
|
43
|
+
.coverage.*
|
|
44
|
+
.cache
|
|
45
|
+
nosetests.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
cover/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Django stuff:
|
|
57
|
+
*.log
|
|
58
|
+
local_settings.py
|
|
59
|
+
db.sqlite3
|
|
60
|
+
db.sqlite3-journal
|
|
61
|
+
|
|
62
|
+
# Flask stuff:
|
|
63
|
+
instance/
|
|
64
|
+
.webassets-cache
|
|
65
|
+
|
|
66
|
+
# Scrapy stuff:
|
|
67
|
+
.scrapy
|
|
68
|
+
|
|
69
|
+
# Sphinx documentation
|
|
70
|
+
docs/_build/
|
|
71
|
+
|
|
72
|
+
# PyBuilder
|
|
73
|
+
.pybuilder/
|
|
74
|
+
target/
|
|
75
|
+
|
|
76
|
+
# Jupyter Notebook
|
|
77
|
+
.ipynb_checkpoints
|
|
78
|
+
|
|
79
|
+
# IPython
|
|
80
|
+
profile_default/
|
|
81
|
+
ipython_config.py
|
|
82
|
+
|
|
83
|
+
# pyenv
|
|
84
|
+
.python-version
|
|
85
|
+
|
|
86
|
+
# pipenv
|
|
87
|
+
Pipfile.lock
|
|
88
|
+
|
|
89
|
+
# poetry
|
|
90
|
+
poetry.lock
|
|
91
|
+
|
|
92
|
+
# pdm
|
|
93
|
+
.pdm.toml
|
|
94
|
+
.pdm-python
|
|
95
|
+
.pdm-build/
|
|
96
|
+
|
|
97
|
+
# PEP 582
|
|
98
|
+
__pypackages__/
|
|
99
|
+
|
|
100
|
+
# Celery stuff
|
|
101
|
+
celerybeat-schedule
|
|
102
|
+
celerybeat.pid
|
|
103
|
+
|
|
104
|
+
# SageMath parsed files
|
|
105
|
+
*.sage.py
|
|
106
|
+
|
|
107
|
+
# Environments
|
|
108
|
+
.env
|
|
109
|
+
.envrc
|
|
110
|
+
.venv
|
|
111
|
+
env/
|
|
112
|
+
venv/
|
|
113
|
+
ENV/
|
|
114
|
+
env.bak/
|
|
115
|
+
venv.bak/
|
|
116
|
+
|
|
117
|
+
# Spyder project settings
|
|
118
|
+
.spyderproject
|
|
119
|
+
.spyproject
|
|
120
|
+
|
|
121
|
+
# Rope project settings
|
|
122
|
+
.ropeproject
|
|
123
|
+
|
|
124
|
+
# mkdocs documentation
|
|
125
|
+
/site
|
|
126
|
+
|
|
127
|
+
# mypy
|
|
128
|
+
.mypy_cache/
|
|
129
|
+
.dmypy.json
|
|
130
|
+
dmypy.json
|
|
131
|
+
|
|
132
|
+
# Pyre type checker
|
|
133
|
+
.pyre/
|
|
134
|
+
|
|
135
|
+
# pytype static type analyzer
|
|
136
|
+
.pytype/
|
|
137
|
+
|
|
138
|
+
# Cython debug symbols
|
|
139
|
+
cython_debug/
|
|
140
|
+
|
|
141
|
+
# IDE / editor
|
|
142
|
+
.idea/
|
|
143
|
+
.vscode/
|
|
144
|
+
*.swp
|
|
145
|
+
*.swo
|
|
146
|
+
*~
|
|
147
|
+
.DS_Store
|
|
148
|
+
|
|
149
|
+
# Hatch / build artifacts
|
|
150
|
+
/.hatch/
|
|
151
|
+
/build_artifacts/
|
|
152
|
+
|
|
153
|
+
uv.lock
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: remote-docker-cli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: A CLI tool for managing remote Docker hosts
|
|
5
|
+
Project-URL: Homepage, https://gitee.com/kzhuo/remote-docker
|
|
6
|
+
Project-URL: Issues, https://gitee.com/kzhuo/remote-docker/issues
|
|
7
|
+
Project-URL: Repository, https://gitee.com/kzhuo/remote-docker
|
|
8
|
+
Author-email: ZHUO kaikuo <kaikuo.zhuo@hotmail.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
Keywords: cli,devops,docker,remote,ssh
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Classifier: Topic :: System :: Systems Administration
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Requires-Dist: click
|
|
26
|
+
Requires-Dist: pyyaml
|
|
27
|
+
Provides-Extra: all
|
|
28
|
+
Requires-Dist: paramiko>=3.0; extra == 'all'
|
|
29
|
+
Provides-Extra: ssh
|
|
30
|
+
Requires-Dist: paramiko>=3.0; extra == 'ssh'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# rdocker (remote-docker)
|
|
34
|
+
|
|
35
|
+
一个类 Docker 命令行工具,通过 SSH 将 `pull` / `save` / `load` 操作代理到远程主机上的 `skopeo`。
|
|
36
|
+
解析 `docker-compose.yml`,在远端拉取所有镜像,打包成 `.tar.gz` 下载到本地,再 `docker load` 到本地 Docker 引擎。
|
|
37
|
+
|
|
38
|
+
适用场景:内网/隔离网络中,本地无法直接拉取镜像,借助能访问镜像仓库的远程"跳板机"中转。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 架构
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
本地机器 远程机器 (SSH)
|
|
46
|
+
┌────────────────────┐ ┌──────────────────────────────┐
|
|
47
|
+
│ docker-compose.yml │ │ /tmp/rdocker/<name>/ │
|
|
48
|
+
└────────┬───────────┘ │ ├── nginx_latest.tar │
|
|
49
|
+
│ 解析 + 自动补 :latest │ ├── redis_7-alpine.tar │
|
|
50
|
+
▼ │ └── ... │
|
|
51
|
+
镜像列表 ──ssh+skopeo───────────────▶ │ skopeo copy docker://... │
|
|
52
|
+
│ docker-archive:xx.tar │
|
|
53
|
+
└──────────────┬───────────────┘
|
|
54
|
+
│ tar -czf
|
|
55
|
+
▼
|
|
56
|
+
/tmp/<name>.tar.gz
|
|
57
|
+
│ scp
|
|
58
|
+
▼
|
|
59
|
+
./<name>.tar.gz ← 本地产物
|
|
60
|
+
│ docker load
|
|
61
|
+
▼
|
|
62
|
+
本地 Docker 引擎
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`skopeo copy` 会带上 `--override-arch` 选项,自动按本地机器架构 (`amd64` / `arm64` / ...) 拉取对应镜像清单。
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 安装
|
|
70
|
+
|
|
71
|
+
需要 Python ≥ 3.10。
|
|
72
|
+
|
|
73
|
+
### 使用 pip
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pip install remote-docker
|
|
77
|
+
|
|
78
|
+
# 可选:启用 paramiko 后端(当前版本使用系统 ssh,可不装)
|
|
79
|
+
pip install "remote-docker[ssh]"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 从源码安装(推荐使用 uv)
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
git clone https://github.com/kzhuo/remote-docker.git
|
|
86
|
+
cd remote-docker
|
|
87
|
+
uv sync
|
|
88
|
+
uv pip install -e .
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
安装后 `rdocker` 命令即可使用:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
rdocker --help
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### 远端机器前置条件
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 在远端 SSH 主机上:
|
|
101
|
+
skopeo --version
|
|
102
|
+
tar --version
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 快速开始
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# 1. 交互式初始化配置(写入 ~/.config/rdocker/config.yml)
|
|
111
|
+
rdocker config init
|
|
112
|
+
|
|
113
|
+
# 2. 先用 --try 预览将要执行的远程命令(推荐)
|
|
114
|
+
rdocker all docker-compose.yml --try
|
|
115
|
+
|
|
116
|
+
# 3. 一键完成:解析 → 远端拉镜像 → 打包 → 下载 → 本地 load
|
|
117
|
+
rdocker all docker-compose.yml
|
|
118
|
+
|
|
119
|
+
# 4. 完成!镜像已在本地 Docker 中
|
|
120
|
+
docker images
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 配置
|
|
126
|
+
|
|
127
|
+
配置文件位置:**`~/.config/rdocker/config.yml`**(权限:`0600`)
|
|
128
|
+
|
|
129
|
+
### config 子命令
|
|
130
|
+
|
|
131
|
+
| 命令 | 说明 |
|
|
132
|
+
|------|------|
|
|
133
|
+
| `rdocker config init` | 交互式生成配置(提示输入 host/user/port/key/auth) |
|
|
134
|
+
| `rdocker config init --force` / `-f` | 强制覆盖已有配置,不询问 |
|
|
135
|
+
| `rdocker config show` | 查看当前配置(密码自动脱敏为 `***`) |
|
|
136
|
+
| `rdocker config set <key> <value>` | 设置单个配置项 |
|
|
137
|
+
| `rdocker config unset <key>` | 删除单个配置项 |
|
|
138
|
+
| `rdocker config path` | 打印配置文件路径 |
|
|
139
|
+
|
|
140
|
+
### 配置项
|
|
141
|
+
|
|
142
|
+
| 键 | 说明 | 默认值 |
|
|
143
|
+
|----|------|--------|
|
|
144
|
+
| `host` | 远端 SSH 主机(IP 或域名) | _(必填)_ |
|
|
145
|
+
| `user` | SSH 用户名 | 当前系统用户名 (`getpass.getuser()`) |
|
|
146
|
+
| `port` | SSH 端口 | `22` |
|
|
147
|
+
| `key` | SSH 私钥路径 | _(空,使用 `ssh-agent` / `~/.ssh/id_*` 系统发现)_ |
|
|
148
|
+
| `remote_dir` | 远端工作目录 | `/tmp/rdocker` |
|
|
149
|
+
| `registry_auth` | 镜像仓库认证(`user:pass`) | _(可选)_ |
|
|
150
|
+
|
|
151
|
+
> **关于 `key`**:留空时不会向 `ssh` / `scp` 传 `-i` 参数,由 SSH 自行从 `ssh-agent` 和 `~/.ssh/id_rsa`、`id_ed25519` 等常见位置发现密钥。
|
|
152
|
+
|
|
153
|
+
### 配置优先级
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
CLI 参数 (--host) > 环境变量 (rdocker_HOST) > 配置文件 > 内置默认值
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 示例
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# 交互式初始化
|
|
163
|
+
$ rdocker config init
|
|
164
|
+
🔧 rdocker Config Init
|
|
165
|
+
──────────────────────────────────────────────────
|
|
166
|
+
Remote host (IP or domain) []: 192.168.1.100
|
|
167
|
+
SSH user [kaikuo]: deploy
|
|
168
|
+
SSH port [22]: 2222
|
|
169
|
+
SSH private key path (empty = system default) []:
|
|
170
|
+
Registry auth (user:pass, leave empty if none) []: admin:secret123
|
|
171
|
+
Remote working directory [/tmp/rdocker]: /data/rdocker
|
|
172
|
+
✅ Config saved to /home/user/.config/rdocker/config.yml
|
|
173
|
+
🔍 Testing SSH connection ...
|
|
174
|
+
✅ SSH connection successful
|
|
175
|
+
✅ skopeo is available on remote
|
|
176
|
+
|
|
177
|
+
# 查看配置(密码脱敏)
|
|
178
|
+
$ rdocker config show
|
|
179
|
+
📋 rdocker Configuration
|
|
180
|
+
──────────────────────────────────────────────────
|
|
181
|
+
Config file: /home/user/.config/rdocker/config.yml
|
|
182
|
+
Permissions: 600
|
|
183
|
+
|
|
184
|
+
host = 192.168.1.100
|
|
185
|
+
user = deploy
|
|
186
|
+
port = 2222
|
|
187
|
+
key =
|
|
188
|
+
remote_dir = /data/rdocker
|
|
189
|
+
registry_auth = admin:***
|
|
190
|
+
|
|
191
|
+
Priority: CLI flag > env var (rdocker_*) > config file > default
|
|
192
|
+
|
|
193
|
+
# 修改单个字段
|
|
194
|
+
$ rdocker config set host 10.0.0.50
|
|
195
|
+
✅ Config saved to ~/.config/rdocker/config.yml
|
|
196
|
+
host = 10.0.0.50
|
|
197
|
+
|
|
198
|
+
# 删除字段
|
|
199
|
+
$ rdocker config unset registry_auth
|
|
200
|
+
✅ Config saved to ~/.config/rdocker/config.yml
|
|
201
|
+
removed: registry_auth
|
|
202
|
+
|
|
203
|
+
# 通过环境变量临时覆盖
|
|
204
|
+
$ rdocker_HOST=override.host rdocker config show
|
|
205
|
+
# → host = override.host
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 命令
|
|
211
|
+
|
|
212
|
+
所有动作命令均支持 `--try` 干跑:仅打印将要执行的 ssh / scp / skopeo 命令,不实际执行。
|
|
213
|
+
|
|
214
|
+
`--name` 缺省规则:
|
|
215
|
+
- **compose 模式**(`pull` / `all` / `save` / `fetch` / `cleanup`) → 当前目录最后一级目录名
|
|
216
|
+
- **image 模式**(`spull`) → 镜像去除 tag 后的最后一段(如 `nginx:1.25-alpine` → `nginx`,`registry:5000/myapp:v1` → `myapp`)
|
|
217
|
+
|
|
218
|
+
### `rdocker all <compose_file> [--name <bundle>] [--try]`
|
|
219
|
+
一键完整流水线:解析 → 远端拉镜像 → 远端打包 → 下载 → 本地 load。
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
rdocker all docker-compose.yml # --name 缺省 = cwd 短名
|
|
223
|
+
rdocker all docker-compose.yml --name prod --registry-auth admin:pass --no-load
|
|
224
|
+
rdocker all docker-compose.yml --try # 干跑 4 阶段
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
选项:
|
|
228
|
+
- `--name, -n` — Bundle 名称(缺省 = cwd 短名)
|
|
229
|
+
- `--registry-auth, -a` — 镜像仓库认证 `user:pass`
|
|
230
|
+
- `--output-dir, -o` — 本地输出目录(默认:`.`)
|
|
231
|
+
- `--no-cleanup` — 不清理远端临时文件
|
|
232
|
+
- `--no-load` — 下载后跳过 `docker load`
|
|
233
|
+
- `--try` — 干跑模式
|
|
234
|
+
|
|
235
|
+
### `rdocker pull <compose_file> [--name <bundle>] [--try]`
|
|
236
|
+
解析 compose 文件并通过 skopeo 拉取所有镜像到远端主机。
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
rdocker pull docker-compose.yml
|
|
240
|
+
rdocker pull docker-compose.yml --name myapp
|
|
241
|
+
rdocker pull docker-compose.yml --name myapp --try # 干跑
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
选项:
|
|
245
|
+
- `--name, -n` — Bundle 名称(缺省 = cwd 短名)
|
|
246
|
+
- `--registry-auth, -a` — 镜像仓库认证 `user:pass`
|
|
247
|
+
- `--try` — 干跑模式
|
|
248
|
+
|
|
249
|
+
### `rdocker spull <image> [--name <bundle>] [--try]`
|
|
250
|
+
拉取**单个镜像**到远端主机(不解析 compose 文件)。
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
rdocker spull nginx:1.25-alpine # --name 缺省 = "nginx"
|
|
254
|
+
rdocker spull registry:5000/myapp:v1 --name myapp
|
|
255
|
+
rdocker spull nginx:1.25-alpine --try
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
选项:
|
|
259
|
+
- `--name, -n` — Bundle 名称(缺省 = 镜像去除 tag 后的最后一段)
|
|
260
|
+
- `--registry-auth, -a` — 镜像仓库认证 `user:pass`
|
|
261
|
+
- `--try` — 干跑模式
|
|
262
|
+
|
|
263
|
+
### `rdocker save [--name <bundle>] [--try]`
|
|
264
|
+
将远端所有 `.tar` 文件打包成一个 `.tar.gz`。
|
|
265
|
+
|
|
266
|
+
```bash
|
|
267
|
+
rdocker save # --name 缺省 = cwd 短名
|
|
268
|
+
rdocker save --name mybundle --try
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
选项:
|
|
272
|
+
- `--name, -n` — Bundle 名称(缺省 = cwd 短名)
|
|
273
|
+
- `--try` — 干跑模式
|
|
274
|
+
|
|
275
|
+
### `rdocker fetch [--name <bundle>] [--try]`
|
|
276
|
+
把远端 `.tar.gz` bundle 下载到本地。
|
|
277
|
+
|
|
278
|
+
```bash
|
|
279
|
+
rdocker fetch --output-dir ./dist
|
|
280
|
+
rdocker fetch --name mybundle --output-dir ./dist --try
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
选项:
|
|
284
|
+
- `--name, -n` — Bundle 名称(缺省 = cwd 短名)
|
|
285
|
+
- `--output-dir, -o` — 本地输出目录(默认:`.`)
|
|
286
|
+
- `--try` — 干跑模式
|
|
287
|
+
|
|
288
|
+
### `rdocker load [--name <bundle> | --file <tar.gz>] [--try]`
|
|
289
|
+
解压本地 `.tar.gz` 并依次 `docker load` 每个镜像;如果本地文件不存在且指定了 `--name`,会自动从远端 fetch。
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
rdocker load --name mybundle
|
|
293
|
+
rdocker load --file ./mybundle.tar.gz
|
|
294
|
+
rdocker load --name mybundle --try # 本地无文件时打印会触发的 scp + load
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
选项:
|
|
298
|
+
- `--name, -n` — Bundle 名称(与 `--file` 二选一)
|
|
299
|
+
- `--file, -f` — 本地 `.tar.gz` 文件路径
|
|
300
|
+
- `--try` — 干跑模式
|
|
301
|
+
|
|
302
|
+
### `rdocker cleanup [--name <bundle>] [--try]`
|
|
303
|
+
清理远端临时文件(`/tmp/rdocker/<name>` 与 `/tmp/<name>.tar.gz`)。
|
|
304
|
+
|
|
305
|
+
```bash
|
|
306
|
+
rdocker cleanup
|
|
307
|
+
rdocker cleanup --name mybundle --try
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
选项:
|
|
311
|
+
- `--name, -n` — Bundle 名称(缺省 = cwd 短名)
|
|
312
|
+
- `--try` — 干跑模式
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 环境变量
|
|
317
|
+
|
|
318
|
+
| 变量 | 对应配置 | 说明 |
|
|
319
|
+
|------|----------|------|
|
|
320
|
+
| `rdocker_HOST` | `host` | 远端 SSH 主机 |
|
|
321
|
+
| `rdocker_USER` | `user` | SSH 用户 |
|
|
322
|
+
| `rdocker_PORT` | `port` | SSH 端口 |
|
|
323
|
+
| `rdocker_KEY` | `key` | SSH 私钥路径 |
|
|
324
|
+
| `rdocker_REMOTE_DIR` | `remote_dir` | 远端工作目录 |
|
|
325
|
+
| `rdocker_REGISTRY_AUTH` | `registry_auth` | 镜像仓库认证 |
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## 工作原理
|
|
330
|
+
|
|
331
|
+
1. **解析** — `docker-compose.yml` → 提取所有 `service.image`,没有 tag 的自动补 `:latest`,正确处理 `registry:port/path:tag` 形式。
|
|
332
|
+
2. **远端拉镜像 (pull)** — SSH 到远端主机,对每个镜像执行:
|
|
333
|
+
```bash
|
|
334
|
+
skopeo copy --override-arch <arch> [--src-creds user:pass] \
|
|
335
|
+
docker://<img> \
|
|
336
|
+
docker-archive:/tmp/rdocker/<name>/<safe>.tar:<img>
|
|
337
|
+
```
|
|
338
|
+
`--override-arch` 由本地架构(`x86_64`→`amd64`、`aarch64`→`arm64` 等)自动决定,确保远端拉取的镜像清单与本地 docker 引擎匹配。
|
|
339
|
+
3. **远端打包 (save)** — `tar -czf /tmp/<name>.tar.gz -C /tmp/rdocker/<name> .`
|
|
340
|
+
4. **下载 (fetch)** — `scp user@host:/tmp/<name>.tar.gz ./`
|
|
341
|
+
5. **本地 load** — 解压 tar.gz,依次 `docker load -i <each.tar>`。
|
|
342
|
+
|
|
343
|
+
---
|
|
344
|
+
|
|
345
|
+
## Tag 自动补全规则
|
|
346
|
+
|
|
347
|
+
| compose 中的写法 | 实际使用 |
|
|
348
|
+
|------------------|----------|
|
|
349
|
+
| `nginx:1.25-alpine` | `nginx:1.25-alpine` (保持不变) |
|
|
350
|
+
| `busybox` | `busybox:latest` (自动补) |
|
|
351
|
+
| `registry:5000/app:v1` | `registry:5000/app:v1` (port 与 tag 正确识别) |
|
|
352
|
+
| `harbor:8443/lib/c:7` | `harbor:8443/lib/c:7` (port 与 tag 正确识别) |
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
## 项目结构
|
|
357
|
+
|
|
358
|
+
```
|
|
359
|
+
remote-docker/
|
|
360
|
+
├── src/
|
|
361
|
+
│ └── remote_docker/
|
|
362
|
+
│ ├── __init__.py # 包元信息 (__version__)
|
|
363
|
+
│ ├── __main__.py # python -m remote_docker 入口
|
|
364
|
+
│ └── cli.py # Click CLI 主体
|
|
365
|
+
├── pyproject.toml # 项目与依赖配置(hatchling 构建)
|
|
366
|
+
├── uv.lock # uv 锁定文件
|
|
367
|
+
└── README.md
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## 开发
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
# 安装(含 dev 依赖)
|
|
376
|
+
uv sync
|
|
377
|
+
|
|
378
|
+
# 直接运行
|
|
379
|
+
uv run rdocker --help
|
|
380
|
+
|
|
381
|
+
# 以模块方式运行
|
|
382
|
+
uv run python -m remote_docker --help
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
`pyproject.toml` 声明的入口脚本:
|
|
386
|
+
|
|
387
|
+
```toml
|
|
388
|
+
[project.scripts]
|
|
389
|
+
rdocker = "remote_docker.cli:main"
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## License
|
|
395
|
+
|
|
396
|
+
MIT
|