2
.dockerignore
Normal file
2
.dockerignore
Normal file
@@ -0,0 +1,2 @@
|
||||
docker-compose.yml
|
||||
README.md
|
9
.env.example
Normal file
9
.env.example
Normal file
@@ -0,0 +1,9 @@
|
||||
DB_FILE=/data/db.sqlite
|
||||
CRONTAB="00 06 * * *"
|
||||
DELETE_AFTER=10
|
||||
TZ=Asia/Novosibirsk
|
||||
MINIO_PATH=myminio://sqlite/master/
|
||||
MINIO_ACCOUNT_ID=account
|
||||
MINIO_APPLICATION_KEY=key
|
||||
MINIO_ENDPOINT=https://s3.domain.ru
|
||||
MINIO_LOCATION=ru-nsk
|
61
.gitea/workflows/docker-build.yml
Normal file
61
.gitea/workflows/docker-build.yml
Normal file
@@ -0,0 +1,61 @@
|
||||
name: docker-build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: docker
|
||||
env:
|
||||
REGISTRY: hub.realmanual.ru
|
||||
IMAGE_NAME: pub/sqlite-backup/backup
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Ensure tag commit is reachable from main
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
git fetch --no-tags --depth=0 origin main
|
||||
if git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
|
||||
echo "Commit is on main history. Proceeding."
|
||||
else
|
||||
echo "Tag commit is not from main. Skipping build." >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- name: Extract tag
|
||||
id: vars
|
||||
shell: bash
|
||||
run: |
|
||||
TAG_REF="${GITHUB_REF#refs/tags/}"
|
||||
echo "tag=$TAG_REF" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITEA_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
tags: |
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.tag }}
|
||||
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.idea
|
||||
.env
|
29
Dockerfile
Normal file
29
Dockerfile
Normal file
@@ -0,0 +1,29 @@
|
||||
FROM alpine:latest
|
||||
|
||||
ENV TZ=UTC
|
||||
LABEL maintainer="Vassiliy Yegorov <vasyakrg@gmail.com>"
|
||||
|
||||
RUN apk add --no-cache \
|
||||
sqlite \
|
||||
curl \
|
||||
bash \
|
||||
tzdata \
|
||||
openssl
|
||||
|
||||
RUN curl -O https://downloads.rclone.org/rclone-current-linux-amd64.zip && \
|
||||
unzip rclone-current-linux-amd64.zip && \
|
||||
cd rclone-*-linux-amd64 && \
|
||||
cp rclone /usr/bin/ && \
|
||||
chown root:root /usr/bin/rclone && \
|
||||
chmod 755 /usr/bin/rclone
|
||||
|
||||
RUN export TZ=/usr/share/zoneinfo/${TZ}
|
||||
|
||||
RUN mkdir -p scripts
|
||||
COPY scripts/ /scripts
|
||||
|
||||
WORKDIR /scripts
|
||||
|
||||
RUN chmod +x /scripts/*
|
||||
|
||||
ENTRYPOINT ["/scripts/entrypoint.sh"]
|
39
README.md
Normal file
39
README.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# бекапирование sqlite в minio
|
||||
|
||||
```yaml
|
||||
services:
|
||||
sqlite_backup:
|
||||
image: hub.realmanual.ru/pub/sqlite-backup/backup:latest
|
||||
container_name: sqlite_backup
|
||||
restart: always
|
||||
volumes:
|
||||
- ./var/lib/data/:/data
|
||||
environment:
|
||||
- DB_FILE
|
||||
- CRONTAB
|
||||
- DELETE_AFTER
|
||||
- TZ
|
||||
- MINIO_PATH
|
||||
- MINIO_ACCOUNT_ID
|
||||
- MINIO_APPLICATION_KEY
|
||||
- MINIO_ENDPOINT
|
||||
- MINIO_LOCATION
|
||||
```
|
||||
|
||||
пример .env
|
||||
|
||||
```bash
|
||||
DB_FILE=/data/db.sqlite
|
||||
CRONTAB="00 06 * * *"
|
||||
DELETE_AFTER=10
|
||||
TZ=Asia/Novosibirsk
|
||||
MINIO_PATH=myminio://sqlite/master/
|
||||
MINIO_ACCOUNT_ID=account
|
||||
MINIO_APPLICATION_KEY=key
|
||||
MINIO_ENDPOINT=https://s3.domain.ru
|
||||
MINIO_LOCATION=ru-nsk
|
||||
```
|
||||
|
||||
1. myminio - системно! не менять
|
||||
2. проверьте настройки локации, не должно быть пусто
|
||||
3. DELETE_AFTER - в днях
|
6
docker-build.sh
Executable file
6
docker-build.sh
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
DOCKER_BASEIMAGE=alpine:latest
|
||||
|
||||
docker buildx build --platform linux/amd64,linux/arm64 --push -t hub.realmanual.ru/pub/sqlite-backup \
|
||||
--build-arg DOCKER_BASEIMAGE=${DOCKER_BASEIMAGE} .
|
17
docker-compose.yml
Normal file
17
docker-compose.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
services:
|
||||
sqlite_backup:
|
||||
image: hub.realmanual.ru/pub/sqlite-backup/backup:latest
|
||||
container_name: sqlite_backup
|
||||
restart: always
|
||||
volumes:
|
||||
- ./var/lib/sqlite/:/data
|
||||
environment:
|
||||
- DB_FILE
|
||||
- CRONTAB
|
||||
- DELETE_AFTER
|
||||
- TZ
|
||||
- MINIO_PATH
|
||||
- MINIO_ACCOUNT_ID
|
||||
- MINIO_APPLICATION_KEY
|
||||
- MINIO_ENDPOINT
|
||||
- MINIO_LOCATION
|
15
scripts/backup.sh
Normal file
15
scripts/backup.sh
Normal file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
BACKUP_FILE="sqlite_$(date "+%F-%H%M%S")"
|
||||
|
||||
sqlite3 ${DB_FILE} ".backup '/tmp/db.sqlite'"
|
||||
tar -zcvf /tmp/${BACKUP_FILE}.tar.gz /tmp/db.sqlite
|
||||
|
||||
/scripts/minio_uploader.sh copy /tmp/${BACKUP_FILE}.tar.gz ${MINIO_PATH}
|
||||
|
||||
rm /tmp/${BACKUP_FILE}.tar.gz
|
||||
|
||||
if [ ! -z $DELETE_AFTER ] && [ $DELETE_AFTER -gt 0 ]
|
||||
then
|
||||
/scripts/deleteold.sh ${MINIO_PATH}
|
||||
fi
|
24
scripts/deleteold.sh
Normal file
24
scripts/deleteold.sh
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Seconds since epoch for current time
|
||||
DATE_NOW=$(date +%s)
|
||||
|
||||
/scripts/minio_uploader.sh list $MINIO_PATH | grep "sqlite_" | while read LINE
|
||||
do
|
||||
BACKUP_FILENAME=$(echo $LINE | awk '{ print $3 }')
|
||||
|
||||
BACKUP_DATE=$(echo $BACKUP_FILENAME | awk 'BEGIN { FS = "[_-]" } ; { printf "%s-%s-%s",$2,$3,$4 }')
|
||||
|
||||
if [[ $BACKUP_DATE =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]
|
||||
then
|
||||
BACKUP_DATE_SECS=$(date -d $BACKUP_DATE +%s)
|
||||
|
||||
DAYS_DIFF=$(( ($DATE_NOW - $BACKUP_DATE_SECS) / (60*60*24) ))
|
||||
|
||||
if [ "$DAYS_DIFF" -gt "$DELETE_AFTER" ]
|
||||
then
|
||||
echo "File $BACKUP_FILENAME is $DAYS_DIFF days old (greater than $DELETE_AFTER days). Deleting it."
|
||||
/scripts/minio_uploader.sh delete /$BACKUP_FILENAME
|
||||
fi
|
||||
fi
|
||||
done
|
6
scripts/entrypoint.sh
Normal file
6
scripts/entrypoint.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
echo "${CRONTAB} /scripts/backup.sh" > /etc/crontabs/root
|
||||
|
||||
/scripts/backup.sh
|
||||
exec crond -f
|
18
scripts/minio_uploader.sh
Normal file
18
scripts/minio_uploader.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
rclone config create myminio s3 provider Minio access_key_id $MINIO_ACCOUNT_ID secret_access_key $MINIO_APPLICATION_KEY endpoint $MINIO_ENDPOINT region $MINIO_LOCATION acl private
|
||||
|
||||
case $1 in
|
||||
copy)
|
||||
echo "copy from $2 to $3"
|
||||
rclone copy --progress $2 $3
|
||||
;;
|
||||
list)
|
||||
echo "list $2"
|
||||
rclone ls $2
|
||||
;;
|
||||
delete)
|
||||
echo "delete $2"
|
||||
rclone delete $2
|
||||
;;
|
||||
esac
|
Reference in New Issue
Block a user