From c59dd698ed7f7562da367afc4523642cca3cd217 Mon Sep 17 00:00:00 2001 From: Box In A Box Date: Mon, 29 Nov 2021 23:04:18 +0530 Subject: [PATCH] vububtu: Implement Self-Backup Feature With The Help Of Rclone! - Add The New Changes While Building The `Dockerfile.heroku` Instead Of Using A fork of `vital987/vubuntu`. I'm Lazy To rebuild and upload to docker lol. People Not Deploying On Heroku Will Have To Rebuild The Image As Per `Dockerfile.heroku`. Heroku Is Simply More Fun lol. 1- Add Some Additional Packages 2- A Backup Of The Current State Of The VPS, Would Be Taken, And Saved To The CLoud(Which Could Be G-Drive, Onedrive, or any service that supports rclone). 3- This Backup Would Essentially Run Every 30min and Keep The App-Data(and Some Additional Folders) in Sync Always. This Is done by taking a backup of `.cache`, `.vscode`, `documents`, `downloads`, `.bashrc`, `.ssh`, `.config` etc; And Uploading Them to the cloud every 30min. 4- Users Are Free To Choose Which Folders Would be backed-up, However, a default config would be provided, that would backup all possible data. --- Dockerfile | 6 ++++ Dockerfile.heroku | 23 ++++++++++++++ README.md | 12 ++++++-- app.json | 30 ++++++++++++++----- assets/configs/5-selfping.conf | 0 assets/configs/6-selfbackup.conf | 6 ++++ assets/scripts/self-backup.py | 51 ++++++++++++++++++++++++++++++++ 7 files changed, 118 insertions(+), 10 deletions(-) mode change 100755 => 100644 assets/configs/5-selfping.conf create mode 100755 assets/configs/6-selfbackup.conf create mode 100644 assets/scripts/self-backup.py diff --git a/Dockerfile b/Dockerfile index 7fbf65a..abaaeb0 100755 --- a/Dockerfile +++ b/Dockerfile @@ -20,6 +20,12 @@ ENV VNC_PASS="samplepass" \ NGROK_AUTH_TOKEN="placeholder" \ #Brave Shared Memory Usage (Set it to 0 to disable the use of /dev/shm for Brave Browser, helpful for Heroku) BRAVE_USE_SHM=1 \ +#Self Backup: Enable Backup Of App Data And App Cache Using Rclone, disabled by default + SELF_BACKUP=0 \ +#Rclone Config Link: rclone.conf : pasted to gist.github.com [Raw Links Only][Secret Gist Only] + RCLONE_CONFIG_LINK="placeholder" \ +#Backup Script Link: Backup Script Which Specifies Which Folders Are To Be Synced By Rclone. + BACKUP_SCRIPT_LINK="https://gist.githubusercontent.com/Box-boi/dda8fe9a1be8c21b5666fd317a9d40cc/raw/rclone-backup-script.sh" \ #Locale LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ diff --git a/Dockerfile.heroku b/Dockerfile.heroku index 32ac1cd..1ec0baf 100755 --- a/Dockerfile.heroku +++ b/Dockerfile.heroku @@ -1,5 +1,18 @@ FROM vital987/vubuntu:latest +RUN curl -O https://downloads.rclone.org/rclone-current-linux-amd64.zip && \ + unzip rclone-current-linux-amd64.zip -d /tmp && \ + cp /tmp/rclone-*-linux-amd64/rclone /usr/bin/ && \ + chown root:root /usr/bin/rclone && \ + chmod 755 /usr/bin/rclone && \ + rm -rf rclone* /tmp/* + +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update && \ + apt-get --no-install-recommends install -y \ + aria2 neofetch rar unrar rename openssh-client tmate sshpass rsync restic && \ + ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa <</dev/null 2>&1 + ENV DEBIAN_FRONTEND=noninteractive \ #VNC Server Password VNC_PASS="samplepass" \ @@ -13,8 +26,18 @@ ENV DEBIAN_FRONTEND=noninteractive \ PORT=80 \ #Disable Shared Memory for Brave BRAVE_USE_SHM=0 \ +#Self Backup: Enable Backup Of App Data And App Cache Using Rclone, disabled by default + SELF_BACKUP=0 \ +#Rclone Config Link: rclone.conf : pasted to gist.github.com [Raw Links Only][Secret Gist Only] + RCLONE_CONFIG_LINK="placeholder" \ +#Backup Script Link: Backup Script Which Specifies Which Folders Are To Be Synced By Rclone. + BACKUP_SCRIPT_LINK="https://gist.githubusercontent.com/Box-boi/dda8fe9a1be8c21b5666fd317a9d40cc/raw/rclone-backup-script.sh" \ #Locale LANG=en_US.UTF-8 \ LANGUAGE=en_US.UTF-8 \ LC_ALL=C.UTF-8 \ TZ="Asia/Kolkata" + +#Include The New Changes: self-backup.py and 6-selfbackup.conf +COPY . /app/.vubuntu + diff --git a/README.md b/README.md index 4e44f63..00ac672 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # VNC + Ubuntu = Vubuntu ¯\\_\(ツ\)\_\/¯ -[![Ubuntu Version](https://img.shields.io/static/v1?label=Ubuntu&message=20.04&color=E95420&logo=ubuntu)](https://ubuntu.com) [![Maintainer](https://img.shields.io/static/v1?label=Maintainer&message=Vital987&color=1e90ff)](https://github.com/vital987) [![Maintainance](https://img.shields.io/badge/Maintenance%20Level-Active-success.svg)](https://github.com/vital987) [![Docker Pulls](https://img.shields.io/docker/pulls/vital987/vubuntu.svg)](https://hub.docker.com/r/vital987/vubuntu) [![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)]()
[![Latest](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-latest.png)](https://heroku.com/deploy?template=https://github.com/vital987/vubuntu/) [![Minimal](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-minimal.png)](https://heroku.com/deploy?template=https://github.com/vital987/vubuntu/tree/minimal) [![PureVNC](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-purevnc.png)](https://heroku.com/deploy?template=https://github.com/vital987/vubuntu/tree/purevnc) [![PureVNC-Minimal](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-purevnc-minimal.png)](https://heroku.com/deploy?template=https://github.com/vital987/vubuntu/tree/purevnc-minimal) +[[![Ubuntu Version](https://img.shields.io/static/v1?label=Ubuntu&message=20.04&color=E95420&logo=ubuntu)](https://ubuntu.com) [![Maintainer](https://img.shields.io/static/v1?label=Maintainer&message=Vital987&color=1e90ff)](https://github.com/vital987) [![Maintainance](https://img.shields.io/badge/Maintenance%20Level-Active-success.svg)](https://github.com/vital987) [![Docker Pulls](https://img.shields.io/docker/pulls/vital987/vubuntu.svg)](https://hub.docker.com/r/vital987/vubuntu) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)]()
[![Latest](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-latest.png)](https://heroku.com/deploy?template=https://github.com/Box-boi/vubuntu/) [![Minimal](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-minimal.png)](https://heroku.com/deploy?template=https://github.com/Box-boi/vubuntu/tree/minimal) [![PureVNC](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-purevnc.png)](https://heroku.com/deploy?template=https://github.com/Box-boi/vubuntu/tree/purevnc) [![PureVNC-Minimal](https://raw.githubusercontent.com/vital987/vubuntu/master/assets/repo_files/button-purevnc-minimal.png)](https://heroku.com/deploy?template=https://github.com/Box-boi/vubuntu/tree/purevnc-minimal) ## **Table of Contents :** @@ -61,8 +61,11 @@ | PORT | NoVNC HTTP Port | | NGROK_AUTH_TOKEN | Ngrok Token | | NGROK_REGION | Ngrok Server Region (Only PureVNC) | -| NO_SLEEP | Prevent Heroku app from sleeping, disabled by default | +| SELF_BACKUP | Enable Backup Of App Data And App Cache Using Rclone, disabled by default | +| RCLONE_CONFIG_LINK | Your `rclone.conf` Pasted To gist.github.com[Raw Link Only]. To Generate rclone.conf, visit rclone.org/drive. [Required If SELF_BACKUP=1]. | +| BACKUP_SCRIPT_LINK | Backup Script Which Specifies Which Folders Are To Be Synced By Rclone. Default Value Is Provided, And Performs A Complete Backup | | APP_NAME | Name of Heroku app | +| NO_SLEEP | Prevent Heroku app from sleeping, disabled by default | | BRAVE_USE_SHM | Usage of /dev/shm for Brave | ## **Installation :** @@ -83,6 +86,11 @@ vital987/vubuntu:latest * noVNC Web-UI will be accessible on port **8080** +## **Some More Info About Self Backup Feature And Rclone Feature :** + * 1- A Backup Of The Current State Of The VPS, Would Be Taken, And Saved To The CLoud(Which Could Be G-Drive, Onedrive, or any service that supports rclone). + * 2- This Backup Would Essentially Run Every 30min and Keep The App-Data(and Some Additional Folders) in Sync Always. This Is done by taking a backup of `.cache`, `.vscode`, `documents`, `downloads`, `.bashrc`, `.ssh`, `.config` etc; And Uploading Them to the cloud every 30min. + * 3- Users Are Free To Choose Which Folders Would be backed-up, However, a default config would be provided, that would backup all possible data. + ## **Warnings :** * [ ! ] **VNC_TITLE & VNC_PASS values should be without spaces.** * [ ! ] **The whole project runs as a root user and non-sandboxed chromium in a docker container.** diff --git a/app.json b/app.json index f68111b..7a74cf0 100644 --- a/app.json +++ b/app.json @@ -1,9 +1,9 @@ { "name": "Vubuntu", "description": "Fully fledged Ubuntu NoVNC, refer readme for more info.", - "repository": "https://github.com/vital987/vubuntu.git", + "repository": "https://github.com/Box-boi/vubuntu.git", "logo": "https://raw.githubusercontent.com/vital987/vubuntu/master/assets/icons/64x64.png", - "keywords": ["docker","ubuntu", "vscode", "novnc", "firefox", "brave", "fluxbox", "linux", "remote", "ssh", "vnc", "vubuntu"], + "keywords": ["docker","ubuntu", "vscode", "novnc", "firefox", "brave", "fluxbox", "linux", "remote", "ssh", "vnc", "vubuntu", "rclone", "auto-backup"], "stack": "container", "env": { "VNC_TITLE" : { @@ -17,18 +17,32 @@ }, "VNC_RESOLUTION" : { "description": "VNC Server Resolution in WxH, 720p is preferrable.", - "value" : "1280x720", + "value" : "1280x720", "required" : true - }, + }, + "SELF_BACKUP" : { + "description": "Enable Backup Of App Data And App Cache Using Rclone, 1=on, 0=off", + "value" : "0", + "required" : true + }, + "RCLONE_CONFIG_LINK" : { + "description": "Your `rclone.conf` Pasted To gist.github.com[Raw Link Only][Secret Gist Only]. To Generate rclone.conf, visit rclone.org/drive. [Required If SELF_BACKUP=1].", + "required" : false + }, + "BACKUP_SCRIPT_LINK" : { + "description": "Backup Script Which Specifies Which Folders Are To Be Synced By Rclone.", + "value" : "https://gist.githubusercontent.com/Box-boi/dda8fe9a1be8c21b5666fd317a9d40cc/raw/rclone-backup-script.sh", + "required" : true + }, "NO_SLEEP" : { "description": "Prevent app from sleeping, 1=on, 0=off", - "value" : "0", + "value" : "1", "required" : true - }, + }, "APP_NAME" : { "description": "Name of the app, same as mentioned above.", - "value" : "", + "value" : "", "required" : true - } + } } } diff --git a/assets/configs/5-selfping.conf b/assets/configs/5-selfping.conf old mode 100755 new mode 100644 diff --git a/assets/configs/6-selfbackup.conf b/assets/configs/6-selfbackup.conf new file mode 100755 index 0000000..21582de --- /dev/null +++ b/assets/configs/6-selfbackup.conf @@ -0,0 +1,6 @@ +[program:self-backup] +command=python3 /app/.vubuntu/assets/scripts/self-backup.py +exitcodes=0 +startsecs=0 +stderr_logfile=/app/.vubuntu/assets/logs/selfbackup.err.log +priority=6 diff --git a/assets/scripts/self-backup.py b/assets/scripts/self-backup.py new file mode 100644 index 0000000..1ec2997 --- /dev/null +++ b/assets/scripts/self-backup.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python3 +# Script to sync App-Data To Cloud every 30 minutes Using rclone, it also prevents app from sleeping. + +import os +import logging +from time import sleep +if __name__ == "__main__": + + logging.basicConfig(filename="/app/.vubuntu/assets/logs/self-backup.py.log", format='%(asctime)s %(message)s', filemode='w') + logger = logging.getLogger() + logger.setLevel(logging.INFO) + + if os.getenv("SELF_BACKUP") == "1": + if "RCLONE_CONFIG_LINK" not in os.environ: + print("[!]RCLONE_CONFIG_LINK unset, terminating...") + logger.error("[!]RCLONE_CONFIG_LINK unset, terminating...") + exit() + + backup_script_link = os.getenv("BACKUP_SCRIPT_LINK") + rclone_config_link = os.getenv("RCLONE_CONFIG_LINK") + + #Create ~/.config/rclone if not present already + createdir = 'mkdir -p ~/.config/rclone' + True if os.path.isdir("/.config/rclone") else os.system(createdir) + + #Download rclone.conf if not downloaded already + download_rclone_conf = 'aria2c --max-tries=0 --retry-wait=5 -o rclone.conf ' + rclone_config_link + ' -d ~/.config/rclone' + True if os.path.isfile("/.config/rclone/rclone.conf") else os.system(download_rclone_conf) + + #Clean Duplicate Downloads: If Self Deploying on your personal computer/server, The Above two commands would result in multiple copies of rclone.conf, as depending on server, home(~), might not be the same as root(/) + #In Case Of heroku home(~) and root(/) is same. Thus The Statemenet Above checks for /.conf instead of ~/.conf as python doesnt allow "~" in os.path.isfile() + #Thus, Clean Up The Residual Copies Of rclone.conf. (files with prefix .1, .2, .3 etc) + os.system("rm -rf ~/.config/rclone/rclone.conf.*") + + while True: + try: + logger.info(f"Starting Sync Using Rclone") + argument = 'curl -s ' + backup_script_link + ' | bash' + os.system(argument) + except: + logger.warning("Sync failed, retrying...") + try: + logger.info(f"Retrying Sync Using Rclone") + argument = 'curl -s ' + backup_script_link + ' | bash' + os.system(argument) + except: + logger.error("Cannot Sync App-Date, Make Sure rclone.conf is filled properly! Terminating...") + sleep(25*60) + else: + print("SELF_BACKUP mode disabled, terminating...") + logger.info("SELF_BACKUP mode disabled, terminating...") \ No newline at end of file