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