Skip to content

Commit

Permalink
General Improvements & Makeover
Browse files Browse the repository at this point in the history
  • Loading branch information
Leon Hubrich committed Feb 21, 2024
1 parent ab63e38 commit c1412ba
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 80 deletions.
49 changes: 0 additions & 49 deletions .github/workflows/build.yml

This file was deleted.

15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
FROM debian:12


# Install Proxmox Backup Client
RUN apt-get update \
&& apt-get -y install \
wget \
Expand All @@ -10,3 +12,16 @@ RUN apt-get update \
&& echo "deb http://download.proxmox.com/debian/pbs-client bookworm main" >> /etc/apt/sources.list \
&& apt-get update \
&& apt-get -y install proxmox-backup-client

# Install ssh client
RUN apt-get -y install openssh-client

# Cron Dependencies
RUN apt-get -y install python3-croniter

COPY cron.py /cron.py

COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENTRYPOINT ["/entrypoint.sh"]
34 changes: 3 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,7 @@
# Proxmox Backup Client in a Container

This was built to run on an unraid server, so here are some specific setup steps for that.
This is a docker container for the Proxmox Backup Client.

### Setup
SSH into unraid and perform the following:
Just upload the docker-compose.yml file and edit the environment variables to match your setup.

```bash
mkdir -p /mnt/user/appdata/pbclient && chown nobody:nousers /mnt/user/appdata/pbclient
```

### Create the encryption key
```bash
docker run --rm -i -v /mnt/user/appdata/pbclient:/config kwatson/pbclient:latest proxmox-backup-client key create /config/client.key --kdf none
```

### Perform a backup

You can use the userscripts application to setup a recurring schedule for this.

* `docs.pxar:/data` is a friendly name for the unraid share, and `/data` is where it's mounted in the container
* `unraid@pbs\!unraid-agent` is the API username
* `PBS_PASSWORD` is your api token
* `--backup-id unraid-docs` is a friendly name that's displayed under Content in the proxmox backup UI. Without this, it would default to the hostname of the container, which is different after each run.
* `MYPBS` is the ip or url to your proxmox backup server
* `DATASTORE` is the name of your datastore

```bash
docker run --rm \
-v /mnt/user/appdata/pbclient:/config \
-v /mnt/user/Docs:/data \
-e PBS_PASSWORD=CHANGEME \
-e PBS_REPOSITORY=unraid@pbs\!unraid-agent@MYPBS:DATASTORE \
kwatson/pbclient:latest proxmox-backup-client backup docs.pxar:/data --keyfile /config/client.key --backup-id unraid-docs
```
For info on how to use Proxmox Backup Client, see the [Proxmox Backup Client Documentation](https://pbs.proxmox.com/docs/backup-client.html).
51 changes: 51 additions & 0 deletions cron.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import sys
import time
from datetime import datetime, timedelta
from croniter import croniter
import subprocess

def roundDownTime(dt=None, dateDelta=timedelta(minutes=1)):
"""Round time down to the top of the previous minute."""
roundTo = dateDelta.total_seconds()
if dt is None:
dt = datetime.now()
seconds = (dt - dt.min).seconds
rounding = (seconds + roundTo / 2) // roundTo * roundTo
return dt + timedelta(0, rounding - seconds, -dt.microsecond)

def getNextCronRunTime(schedule):
"""Get next run time from now, based on schedule specified by cron string."""
return croniter(schedule, datetime.now()).get_next(datetime)

def sleepTillTopOfNextMinute():
"""Sleep till the top of the next minute."""
t = datetime.utcnow()
sleeptime = 60 - (t.second + t.microsecond / 1000000.0)
time.sleep(sleeptime)

def execute_command(command):
"""Executes a given command in the shell."""
try:
subprocess.run(command, shell=True, check=True)
except subprocess.CalledProcessError as e:
print("Error executing command:", str(e))

if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: python script.py '<cron_schedule>' '<command>'")
sys.exit(1)

schedule = sys.argv[1] # CRON expression
command = sys.argv[2] # Command to execute

nextRunTime = getNextCronRunTime(schedule)
while True:
roundedDownTime = roundDownTime()
if roundedDownTime == nextRunTime:
print("Executing command at:", datetime.now())
execute_command(command)
nextRunTime = getNextCronRunTime(schedule)
elif roundedDownTime > nextRunTime:
print("Missed execution at:", datetime.now())
nextRunTime = getNextCronRunTime(schedule)
sleepTillTopOfNextMinute()
12 changes: 12 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
services:
proxmox-backup-client:
image: ghcr.io/games-crack/pbc-docker:main
container_name: proxmox-backup-client
restart: unless-stopped
volumes:
# - path/to/be/backuped:/backup
- ./config:/config
environment:
CRON_SCHEDULE: "0 0 * * *"
BACKUP_CMD: "proxmox-backup-client ...Arguments Here..."
stop_signal: SIGKILL
53 changes: 53 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/bin/bash
# Fail on any error.
set -e pipefail

# Environment variables:
# - Cron schedule: CRON_SCHEDULE
# - Backup command: BACKUP_CMD


echo "Generating crontab schedule..."

# Get current stdout and stderr paths
#std_out=$(readlink -f /proc/self/fd/1) # 2>&1 | tee -a $std_out
echo "CRON_SCHEDULE: $CRON_SCHEDULE"
echo "BACKUP_CMD: $BACKUP_CMD"

echo "SHELL=/bin/bash" > /etc/crontab
echo "$CRON_SCHEDULE /tmp/backup.sh" >> /etc/crontab



export -p > /.env

echo '#!/bin/bash' > /tmp/backup.sh
echo '' >> /tmp/backup.sh
echo '# Load environment variables' >> /tmp/backup.sh
echo 'source /.env' >> /tmp/backup.sh
echo '' >> /tmp/backup.sh
echo '# Run the pre-backup script if it exists' >> /tmp/backup.sh
echo 'if [ -f /pre_backup.sh ]; then' >> /tmp/backup.sh
echo ' echo "Running pre-backup script..."' >> /tmp/backup.sh
echo ' /pre_backup.sh' >> /tmp/backup.sh
echo 'fi' >> /tmp/backup.sh
echo '' >> /tmp/backup.sh
echo "$BACKUP_CMD" >> /tmp/backup.sh
echo '' >> /tmp/backup.sh
echo '# Run the post-backup script if it exists' >> /tmp/backup.sh
echo 'if [ -f /post_backup.sh ]; then' >> /tmp/backup.sh
echo ' echo "Running post-backup script..."' >> /tmp/backup.sh
echo ' /post_backup.sh' >> /tmp/backup.sh
echo 'fi' >> /tmp/backup.sh

chmod +x /tmp/backup.sh /.env

# Hook Kill signal


# Run the cron daemon
echo "Starting cron daemon..."
python3 /cron.py "$CRON_SCHEDULE" "$BACKUP_CMD"



0 comments on commit c1412ba

Please sign in to comment.