linux宝塔面板使用API自动部署更新文件 次两次更新还好,多网站,多频次更新,还是需要一个简单脚本实现自动化更新部署.2. 开启API访问登录宝塔面板,找到设置/面板设置API接口,点击API接口配置获取接口密钥,以及配置IP白名单.配置图如下3. 访问签名处理访问接口时,需要添加签名参数,签名参数生成规是token: md5(str(时间戳) 密钥MD5),Python实现代码如下# self.api_key 是在接口配置获取的接口密钥 # 公众号: 小满小慢 def _generate_sign(self) - dict: now_time int(time.time()) api_key_md5 hashlib.md5(self.api_key.encode()).hexdigest() token_str str(now_time) api_key_md5 token hashlib.md5(token_str.encode()).hexdigest() return { request_token: token, request_time: now_time }4. 通用请求处理API所有的请求都需要带上签名信息,我们这里对访问的接口做一个统一的封装,使调用接口只关心业务参数,对一封装代码如下# self.panel_url 配置的宝塔面板地址 # 公众号: 小满小慢 def _post(self, endpoint: str, data: dict None) - dict: if data is None: data {} sign_params self._generate_sign() all_data {**data, **sign_params} url urljoin(self.panel_url, endpoint) try: response requests.post( url, dataall_data, timeoutself.request_timeout, verifyFalse ) response.raise_for_status() result response.json() if result.get(status) False: raise Exception(f地心侠士: API 错误: {result.get(msg, 未知错误)}) return result except requests.exceptions.RequestException as e: raise Exception(f地心侠士: 请求失败: {e})5. 文件上传文件上传比较特殊,这里需读取本地文件,并上传到服务器指定目录,这里单独封成一个方法.# 公众号: 小满小慢 # 小游戏: 地心侠士 def upload_file(self, local_path: str, remote_path: str) - bool: try: file_name os.path.basename(local_path) file_size os.path.getsize(local_path) remote_dir os.path.dirname(remote_path) print(f 地心侠士 准备上传: {file_name} ({file_size} bytes) - {remote_path}) sign_data self._generate_sign() data { f_path: remote_dir, f_name: remote_path, f_size: file_size, f_start: 0, request_token: sign_data[request_token], request_time: sign_data[request_time] } files { blob: (file_name, open(local_path, rb), application/octet-stream) } endpoint /files?actionupload url urljoin(self.panel_url, endpoint) headers { Accept: */*, Accept-Encoding: zh-CN,zh;q0.9, Connection: keep-alive } response requests.post( url, headersheaders, datadata, filesfiles, timeoutself.request_timeout, verifyFalse ) files[blob][1].close() response.raise_for_status() result response.json() if result.get(status) False: raise Exception(f地心侠士 API 错误: {result.get(msg, 未知错误)}) print(f 地心侠士 [成功] 文件上传完成: {file_name}) return True except Exception as e: print(f 地心侠士 [错误] 文件上传失败: {e}) return False6. 文件解压文件解压接口,根据文件上传的路径,调用文件解压接口,实现文件解压功能,以及删除解压完成的zip文件,核心代码如下# remote_zip 是服务上传的zip文件路径 # web_site_path 是网站解压路径 # 公众号: 小满小慢 try: unzip_result api._post(/files?actionUnZip, { sfile: remote_zip, dfile: web_site_path, encoding: utf-8 }) if unzip_result.get(status): print(f 地心侠士 [成功] ZIP文件已解压到: {web_site_path}) try: api._post(/files?actionDeleteFile, { path: remote_zip }) print(f 地心侠士 [成功] 已清理临时ZIP文件) except: pass else: print(f 地心侠士 [警告] 解压可能有问题: {unzip_result.get(msg, 未知错误)}) print(f 地心侠士 请手动解压: {remote_zip} - {web_site_path})7. 停用启用网站文件部署完成后,针对后端的任务,如果没有开启热启动,这里我们需要先获取站点信息,然后停用网站,再启动网站获取网站信息# 公众号: 小满小慢 # 返回信息说明: name 网站名称 path 网站路径 site_id 网站ID sites_result api._post(/data?actiongetData, { table: sites, limit: 1000 })停用网站stop_result api._post(/site?actionSiteStop, { id: site_id, name: site_name })启动网站start_result api._post(/site?actionSiteStart, { id: site_id, name: site_name })8. 总结使用脚本自动化部署,最重要的好处就是在脚本编写完成后,完全解放双手,并且不易出错,当然也得做好备份.目前宝塔的API信息不多,当前部署需要的api信息汇总如下功能接口地址方法测试连接/system?actionGetNetWorkPOST文件上传/files?actionuploadPOST文件解压/files?actionUnZipPOST删除文件/files?actionDeleteFilePOST获取网站列表/data?actiongetDataPOST停用网站/site?actionSiteStopPOST启用网站/site?actionSiteStartPOST