目录

  1. 目标
  2. 安装 AWS CLI v2
  3. 创建专用 IAM 用户
  4. 创建最小权限 S3 策略
  5. 创建 Access Key 并配置 AWS CLI
  6. 验证 IAM 身份和 S3 权限
  7. 备份脚本
  8. 配置 crontab
  9. 确认服务器时区
  10. 自动删除旧备份
  11. END

数据是最重要的。我们的驾驶数据也是如此。好不容易用 teslamate 来记录我们的驾驶数据,那就要认真地保存和备份这些数据,尤其是特斯拉官方也没有提供查看驾驶记录的入口的情况下。

备份 teslamate 数据其实就是备份 pg 数据。总体上就是创建一个备份脚本,定时 pg dump 然后上传到 aws s3 或其他云存储。

在此之前,我们需要:

  1. 部署好的 teslamate
  2. aws 账号
  3. 新建一个用于存放数据的 bucket

目标

假设我们每天北京时间 00:00 和 12:00 自动备份 TeslaMate 的 PostgreSQL 数据库,并上传到 AWS S3:s3://data-box2/teslamate-backup/。本地临时备份上传成功后应删除,避免持续占用服务器磁盘。

安装 AWS CLI v2

登录上部署 teslamate 的机器,参考官方文档安装 aws cli:

1
2
3
4
5
cd /tmp
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install -y unzip
unzip awscliv2.zip
sudo ./aws/install

验证:

1
aws --version

实际安装版本:aws-cli/2.36.42。

接下来我们来创建专门用户备份数据的 aws 用户,并赋予适当的权限。

创建专用 IAM 用户

在 AWS IAM 中创建用户 teslamate-backup 。该用户不提供 AWS Management Console 登录权限,只用于服务器上的 AWS CLI。

选择“IAM 用户”而不是”角色“选择“IAM 用户”而不是”角色“
选择“直接附加策略”,然后创建策略选择“直接附加策略”,然后创建策略

创建最小权限 S3 策略

创建一个新策略:TeslaMateBackupS3Policy 。Bucket 为 data-box2,数据备份到 teslamate-backup/ 目录下。

策略限制用户只能列出并读写该备份目录,不授予对 Bucket 其他目录的访问权限,也不授予 DeleteObject:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListTeslaMateBackups",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::data-box2",
"Condition": {
"StringLike": {
"s3:prefix": [
"teslamate-backup",
"teslamate-backup/*"
]
}
}
},
{
"Sid": "ManageTeslaMateBackups",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::data-box2/teslamate-backup/*"
}
]
}
创建策略创建策略

创建 Access Key 并配置 AWS CLI

在 teslamate-backup 用户的「安全凭证」中创建用于 Command Line Interface (CLI) 的 Access Key,创建完成后就会看到 access key id 和 secret access key,你也可以下载包含这两个 key 的 csv,然后保存在别处。

接着服务器执行 aws configure ,然后根据提示填写:

1
2
3
4
AWS Access Key ID:     <REDACTED>
AWS Secret Access Key: <REDACTED>
Default region name: us-east-1
Default output format: json

验证 IAM 身份和 S3 权限

配置完成后验证是否能访问 s3,先验证当前身份:

1
aws sts get-caller-identity
确认身份应为 user/teslamate-backup确认身份应为 user/teslamate-backup

然后验证能否列出文件:

1
aws s3 ls s3://data-box2/teslamate-backup/

首次没有任何对象时,命令成功但无输出属于正常情况。

实际上传测试:

1
2
3
echo "test" > /tmp/teslamate-s3-test.txt
aws s3 cp /tmp/teslamate-s3-test.txt \
s3://data-box2/teslamate-backup/teslamate-s3-test.txt

最后再次执行以下命令确认测试文件已经上传成功:

1
aws s3 ls s3://data-box2/teslamate-backup/

备份脚本

aws s3 那边准备好了,接下来就是编写备份脚本了,我们可以将这个脚本放在 teslamate 目录下:/home/ubuntu/projects/teslamate/backup.sh 。脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env bash

set -euo pipefail

cd /home/ubuntu/projects/teslamate

TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
BACKUP_FILE="/tmp/teslamate_${TIMESTAMP}.bck"
S3_PATH="s3://data-box2/teslamate-backup"

docker compose exec -T database \
pg_dump -U teslamate -Fc teslamate \
> "$BACKUP_FILE"

if [ ! -s "$BACKUP_FILE" ]; then
echo "Backup failed: backup file is empty" >&2
exit 1
fi

aws s3 cp "$BACKUP_FILE" "${S3_PATH}/$(basename "$BACKUP_FILE")"
rm -f "$BACKUP_FILE"

注意上面的 pg_dump 使用 -Fc ,表示 PostgreSQL custom format,该格式会进行压缩,因此文件显著小于默认的 plain SQL dump,大概是原来的 12%。可以使用以下命令检查文件是否正常:

1
2
3
4
5
6
7
8
9
10
11
12
$ pg_restore -l teslamate_YYYYMMDD-HHMMSS.bck | head
;
; Archive created at 2026-09-10 06:51:07 UTC
; dbname: teslamate
; TOC Entries: 228
; Compression: gzip
; Dump Version: 1.16-0
; Format: CUSTOM
; Integer: 4 bytes
; Offset: 8 bytes
; Dumped from database version: 18.4 (Debian 18.4-1.pgdg13+1)

如果本地没有 pg_restore,可以直接使用 pg 镜像中的命令:cat teslamate_20260910-145107.bck | docker compose exec -T database pg_restore -l | head ,该命令并不会真的导入数据,只是列出数据(-l)。

恢复 custom-format 备份时使用 pg_restore -U teslamate -d teslamate backup.bck ,而不是 psql < backup.bck 。

赋予脚本执行权限:

1
chmod +x /home/ubuntu/projects/teslamate/backup.sh

手动测试:

1
/home/ubuntu/projects/teslamate/backup.sh

正常应成功上传类似 teslamate_20260910-135911.bck 的备份文件。

接下来我们来配置让其定时运行。

配置 crontab

编辑当前用户的 crontab:crontab -e ,在其中加入:

1
0 0,12 * * * /home/ubuntu/projects/teslamate/backup.sh >> /home/ubuntu/projects/teslamate/backup.log 2>&1

即每天 00:00 和 12:00 各执行一次,日志写入 /home/ubuntu/projects/teslamate/backup.log。

执行 crontab -l 验证是否配置正确。

确认服务器时区

执行 timedatectl 确认时区是否为 Time zone: Asia/Shanghai (CST, +0800) 。不是的话可以更改下时区。

自动删除旧备份

因为我们生成的备份文件是带日期时间的,所以不会自动覆盖,如果长期不清理,就会堆积很多文件。我们可以利用 s3 的生命周期,自动删除 n 天前的备份。

在 bucket 的 管理 → 生命周期规则 右侧创建生命周期规则:

然后按照下图填写字段:

完成后就会只保留最近 7 天的备份文件了。

END