You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写Makefile实现本地操作后自动在SSH远程VM执行命令?

实现SCP上传+远程Docker命令全自动化的Makefile方案

方法1:直接在SSH命令中串联远程执行逻辑

不用单独建立交互式SSH连接,直接通过ssh命令的参数传递要执行的远程指令,和SCP步骤串联起来即可,整个流程会自动完成无需手动干预。

示例Makefile:

# 配置VM信息
VM_HOST = your-vm-ip
VM_USER = vm-username
REMOTE_WORKDIR = /opt/app/deploy

deploy:
	# 打包本地构建产物(根据实际文件调整)
	tar -czf build.tar.gz ./dist ./Dockerfile
	# 上传压缩包到VM指定目录
	scp build.tar.gz $(VM_USER)@$(VM_HOST):$(REMOTE_WORKDIR)/
	# 远程执行Docker相关命令
	ssh $(VM_USER)@$(VM_HOST) "\
		cd $(REMOTE_WORKDIR) && \
		# 加载镜像
		docker load -i build.tar.gz && \
		# 清理旧容器(容器不存在时不中断流程)
		docker stop flask-app-container || true && \
		docker rm flask-app-container || true && \
		# 启动新容器
		docker run -d --name flask-app-container -p 5000:5000 your-flask-image:latest \
	"

关键注意点:

  • 用双引号包裹所有远程命令,换行用反斜杠\保持格式清晰
  • 用&&串联命令,确保前一步成功才执行下一步
  • 清理旧容器时加|| true,避免容器不存在导致整个脚本中断

方法2:上传本地脚本到VM后执行

如果远程执行逻辑复杂,把命令写成单独的Shell脚本会更易维护。

  1. 本地创建remote-deploy.sh脚本:
#!/bin/bash
set -e  # 遇到错误立即退出

WORKDIR="/opt/app/deploy"
IMAGE_TAG="your-flask-image:latest"
CONTAINER_NAME="flask-app-container"

# 进入工作目录
cd $WORKDIR

# 加载Docker镜像
docker load -i build.tar.gz

# 停止并删除旧容器
docker stop $CONTAINER_NAME || true
docker rm $CONTAINER_NAME || true

# 启动新容器
docker run -d --name $CONTAINER_NAME -p 5000:5000 $IMAGE_TAG
  1. 修改Makefile,同时上传压缩包和脚本,然后远程执行:
VM_HOST = your-vm-ip
VM_USER = vm-username
REMOTE_WORKDIR = /opt/app/deploy

deploy:
	tar -czf build.tar.gz ./dist ./Dockerfile
	# 同时上传压缩包和脚本
	scp build.tar.gz remote-deploy.sh $(VM_USER)@$(VM_HOST):$(REMOTE_WORKDIR)/
	# 远程赋予脚本执行权限并运行
	ssh $(VM_USER)@$(VM_HOST) "\
		chmod +x $(REMOTE_WORKDIR)/remote-deploy.sh && \
		$(REMOTE_WORKDIR)/remote-deploy.sh \
	"

常见问题处理

  • 需要sudo权限执行Docker:
    要么给VM用户添加Docker组(sudo usermod -aG docker $USER,需重新登录生效),要么在SSH命令中添加sudo并配合-t参数分配伪终端:

    ssh -t $(VM_USER)@$(VM_HOST) "sudo docker load -i build.tar.gz && ..."
    

    建议提前配置用户免密sudo,避免脚本执行时需要输入密码。

  • 远程环境变量缺失:
    远程非交互式Shell不会加载.bashrc或.profile,如果Docker命令不在默认PATH中,可使用绝对路径(比如/usr/bin/docker),或者在命令前手动加载配置:

    ssh $(VM_USER)@$(VM_HOST) "source ~/.bashrc && cd $(REMOTE_WORKDIR) && docker load ..."
    
  • 远程目录不存在:
    在远程命令开头添加mkdir -p $(REMOTE_WORKDIR)确保目录存在。

内容的提问来源于stack exchange,提问作者charnould

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 21:01:05