上传文件至 /

This commit is contained in:
2025-11-28 15:43:53 +08:00
parent e723eaec37
commit 3422751dcd

427
README.md Normal file
View File

@@ -0,0 +1,427 @@
# Docker 镜像一键构建 & 远程部署脚本说明
脚本文件:`docker_deplay.sh`
作用:**在本地构建 Docker 镜像 → 打包为 tar → 上传到远程服务器 → 在服务器上停止旧容器并启动新容器**支持多架构AMD64 / ARM64与“仅上传”模式。
---
## 1. 功能概述
这个脚本主要解决的一件事:
> **一条命令完成从本地构建到服务器部署的全流程。**
包含步骤:
1. 检查本地依赖(`docker``sshpass`
2. 按指定架构构建 Docker 镜像(`amd64``arm64`
3. 导出为 `xxx.tar` 文件
4. 使用 `scp` 上传 tar 到服务器 `/tmp/`
5. 在服务器上:
* 停止并删除旧容器
* 删除旧镜像
* `docker load` 导入新的 tar 镜像
* 通过 `docker run` 启动新容器
* 清理 `/tmp` 中的临时 tar
6. 输出访问地址和部署信息
---
## 2. 运行环境要求
### 本地机器(执行脚本的地方)
* 操作系统Linux / macOS支持 Bash
* 已安装:
* `docker`(且已启动)
* `docker buildx`Docker 19.03+ 一般自带)
* `sshpass`
* macOS: `brew install sshpass`
* Ubuntu: `sudo apt-get install sshpass`
### 远程服务器
* 已安装:
* `docker`
* 当前用户具备 `sudo` 权限(脚本中使用了 `sudo docker ...`
---
## 3. 快速开始(最简用法)
1. **把脚本放到项目根目录(有 Dockerfile 的目录)**
2. 修改脚本顶部“配置变量”部分为你自己的服务器信息
3. 给脚本执行权限:
```bash
chmod +x docker_deplay.sh
```
4. 直接执行(默认 AMD64 架构):
```bash
./docker_deplay.sh
```
执行成功后,脚本会告诉你类似:
* 服务器地址
* 访问端口
* 容器名、镜像名
* 访问 URL例如`http://服务器IP:8199`
---
## 4. 配置变量说明(一定要先改这里)
脚本顶部这块是你需要根据实际情况修改的:
```bash
SERVER_HOST="6.6.6.86" # 服务器IP地址
SERVER_USER="ubuntu" # 服务器用户名
SERVER_PASSWORD="qweasdzxc1"# 服务器密码
SERVER_PORT="22" # SSH端口
IMAGE_NAME="epage_server" # Docker镜像名称
IMAGE_TAG="latest" # Docker镜像标签
CONTAINER_NAME="epage_server-container" # 容器名称
LOCAL_PORT="8199" # 服务器对外暴露端口
CONTAINER_PORT="8199" # 容器内部服务端口
TAR_FILE="${IMAGE_NAME}-${IMAGE_TAG}.tar" # 压缩包文件名(后面会根据架构改名)
```
### 4.1 服务器相关变量
| 变量名 | 说明 |
| ----------------- | -------------------------------------------------------------- |
| `SERVER_HOST` | 你的服务器 IP 或域名,例如 `1.2.3.4`、`your.domain.com` |
| `SERVER_USER` | SSH 登录用户名,例如 `root`、`ubuntu` |
| `SERVER_PASSWORD` | SSH 登录密码(脚本用 `sshpass` 免交互登录)**不建议在生产环境明文写密码,推荐改为 SSH Key 方式** |
| `SERVER_PORT` | SSH 端口,默认 22一般不用改除非你自己改过 |
> ⚠️ 脚本中有一段安全检查:
>
> ```bash
> if [ "$SERVER_HOST" = "your-server-ip" ] || [ "$SERVER_PASSWORD" = "your-password" ]; then
> ...
> fi
> ```
>
> 如果你保留了默认占位字符串会直接退出,记得改成你自己的真实信息。
### 4.2 镜像 & 容器相关变量
| 变量名 | 说明 |
| ---------------- | ------------------------------------------------------- |
| `IMAGE_NAME` | 构建的镜像名字,例如 `epage_server` |
| `IMAGE_TAG` | 镜像 tag例如 `latest`、`v1.0.0` |
| `CONTAINER_NAME` | 服务器上运行的容器名称,方便后续 `docker logs/stop` 等操作 |
| `LOCAL_PORT` | 服务器对外暴露端口,比如用户访问 `http://SERVER_HOST:LOCAL_PORT` |
| `CONTAINER_PORT` | 容器内部应用监听的端口,比如你的服务在容器内跑在 `8199` |
| `TAR_FILE` | 导出的镜像文件名,如 `epage_server-latest-amd64.tar`(脚本会自动加上架构后缀) |
在服务器上运行容器时实际使用的是:
```bash
sudo docker run -d -p ${LOCAL_PORT}:${CONTAINER_PORT} --name ${CONTAINER_NAME} ${IMAGE_NAME}:${IMAGE_TAG}
```
即:**外部访问 `LOCAL_PORT` → 映射到容器内部的 `CONTAINER_PORT`**。
### 4.3 架构相关变量
```bash
PLATFORM="linux/amd64" # 默认架构
ARCH_SUFFIX="" # 架构后缀用于区分不同架构tar文件
```
* 当你执行 `-amd` 时:
* `PLATFORM="linux/amd64"`
* `ARCH_SUFFIX="-amd64"`
* `TAR_FILE="epage_server-latest-amd64.tar"`
* 当你执行 `-arm` 时:
* `PLATFORM="linux/arm64"`
* `ARCH_SUFFIX="-arm64"`
* `TAR_FILE="epage_server-latest-arm64.tar"`
这样可以在同一个目录下区分不同架构导出的镜像包。
---
## 5. 命令用法 & 参数说明
### 5.1 基本用法(不带参数)
```bash
./docker_deplay.sh
```
等价于:
* 目标架构:`linux/amd64`
* 先构建镜像 → 打包 tar → 上传 → 部署 → 清理临时文件
适用于:**大多数 x86_64 服务器普通云服务器、PC 服务器)**
---
### 5.2 指定架构构建 & 部署
#### 构建并部署 AMD64
```bash
./docker_deplay.sh -amd
```
* 使用 `linux/amd64` 平台构建
* 导出为 `epage_server-latest-amd64.tar`
* 上传 & 部署完成后删除本地 tar
#### 构建并部署 ARM64
```bash
./docker_deplay.sh -arm
```
* 使用 `linux/arm64` 平台构建
* 适用于:树莓派 4、部分 ARM 服务器 等
* 导出为 `epage_server-latest-arm64.tar`
> ✅ 如果你不确定服务器架构,一般云服务器都是 `amd64`,树莓派/部分国产 ARM 机器则是 `arm64`。
---
### 5.3 仅上传 & 部署已存在的 tar不重新构建
有时你已经在 CI 或别的机器上打好了 tar只想复用这个 tar 文件部署到服务器,可以使用 `-upload` 模式。
#### 默认 AMD64 架构,只上传 & 部署
```bash
./docker_deplay.sh -upload
```
* 不执行构建步骤
* 只会检查当前目录是否存在:
* `epage_server-latest.tar`(默认)
* 或根据你之前指定的架构自动命名的 tar 文件
如果你之前是用 `-amd` 构建过,会生成:
```bash
epage_server-latest-amd64.tar
```
那么你需要这样配合使用:
#### 仅上传之前构建好的 AMD64 包
```bash
./docker_deplay.sh -upload -amd
```
* 跳过构建
* 查找 `epage_server-latest-amd64.tar`
* 如果存在 → 上传 & 部署
* 部署成功后删除本地 tar
#### 仅上传之前构建好的 ARM64 包
```bash
./docker_deplay.sh -upload -arm
```
* 跳过构建
* 查找 `epage_server-latest-arm64.tar`
* 上传 & 部署
> ⚠️ 如果指定了 `-upload`,但当前目录没有对应 tar 文件,脚本会直接报错退出:
> `未找到tar文件: xxx.tar`
---
## 6. 脚本内部流程(帮你快速理解在干什么)
### 6.1 `check_dependencies`
* 检查 `docker` 是否存在
* 检查 `sshpass` 是否存在
如果缺少,直接提示如何安装并退出。
### 6.2 `parse_arguments "$@"`
解析命令行参数:
* `-amd`:设置 `PLATFORM="linux/amd64"``ARCH_SUFFIX="-amd64"`
* `-arm`:设置 `PLATFORM="linux/arm64"``ARCH_SUFFIX="-arm64"`
* `-upload`:设置 `UPLOAD_ONLY=true`
* 未知参数:直接报错并退出
然后根据架构拼好最终的 `TAR_FILE` 名字,并打印出来。
### 6.3 `build_image`
1. 如果已有同名 tar 文件,先删除
2. 使用 `docker buildx build` 构建并导出镜像:
```bash
docker buildx build \
--platform $PLATFORM \
-t "${IMAGE_NAME}:${IMAGE_TAG}" \
--output type=docker,dest="./${TAR_FILE}" .
```
3. 构建成功会提示 `Docker 镜像构建完成: xxx.tar`
### 6.4 `upload_to_server`
通过 `sshpass + scp` 上传:
```bash
sshpass -p "$SERVER_PASSWORD" scp -P "$SERVER_PORT" -o StrictHostKeyChecking=no "$TAR_FILE" "${SERVER_USER}@${SERVER_HOST}:/tmp/"
```
目标目录为服务器的 `/tmp/`。
### 6.5 `deploy_on_server`
在服务器上执行一段远程脚本:
1. 若存在同名容器:
* `docker stop CONTAINER_NAME`
* `docker rm CONTAINER_NAME`
2. 若存在同名镜像:
* `docker rmi IMAGE_NAME:IMAGE_TAG`
3. `docker load -i /tmp/TAR_FILE` 导入新镜像
4. `docker run -d -p LOCAL_PORT:CONTAINER_PORT --name CONTAINER_NAME IMAGE_NAME:IMAGE_TAG`
5. 判断容器是否启动成功(通过 `docker ps | grep`
6. 清理 `/tmp/TAR_FILE`
7. 打印访问地址
### 6.6 `cleanup_local`
* 本地删除临时 tar 文件,防止堆积。
### 6.7 `show_deployment_info`
最后在本地打印一份部署摘要信息,包括:
* 服务器地址
* 应用端口
* 访问 URL
* 容器名称
* 镜像名称
* 目标架构
* 镜像文件名
---
## 7. 常见操作示例
### 7.1 我就一台普通云服务器x86一键部署
```bash
./docker_deplay.sh
```
或更明确一点:
```bash
./docker_deplay.sh -amd
```
---
### 7.2 我的服务要部署到树莓派ARM
在你的开发机上:
```bash
./docker_deplay.sh -arm
```
---
### 7.3 CI 中先构建,再单独在本地只“上传 + 部署”
1. 第一步(在 CI 或其他机器完成构建):
```bash
./docker_deplay.sh -amd
# 或手动构建得到 epage_server-latest-amd64.tar
```
2. 以后在你本地,只要本地有这个 tar就可以重复部署
```bash
./docker_deplay.sh -upload -amd
```
---
## 8. 日志 & 排错
脚本使用彩色日志:
* `[INFO]`:普通流程提示
* `[SUCCESS]`:成功信息
* `[WARNING]`:警告信息
* `[ERROR]`:错误信息(一般会退出)
### 8.1 查看容器日志
脚本最后会提示:
```bash
如需查看容器日志,请在服务器上运行: sudo docker logs epage_server-container
```
你只需 SSH 到服务器上执行:
```bash
sudo docker logs -f epage_server-container
```
### 8.2 手动停止容器
```bash
sudo docker stop epage_server-container
```
### 8.3 连接类问题
* 如果报 `Connection refused`、`No route to host`
* 检查 `SERVER_HOST`、`SERVER_PORT` 是否正确
* 检查服务器安全组 / 防火墙设置
* 如果报 `Permission denied`
* 检查 `SERVER_USER` 和 `SERVER_PASSWORD` 是否正确
* 或考虑改为 SSH 密钥认证
---
## 9. 安全建议(可选优化)
目前脚本直接在代码里写了密码并通过 `sshpass` 使用,适合开发、内网或快速测试环境。更安全的做法:
* 禁用密码登录,只保留 SSH Key
* 修改脚本,将 `sshpass` 部分改为纯 `ssh` / `scp`,让系统自动使用私钥
* 或从环境变量中读取密码,而不是写死在脚本里
---
如果你愿意,我也可以帮你基于这个脚本再拆分一版 **“生产安全版”**(用 SSH Key、不明文写密码或者帮你写一版 **英文 README** 方便放到 GitHub。