Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
webees committed Feb 28, 2024
0 parents commit 7f7382b
Show file tree
Hide file tree
Showing 8 changed files with 316 additions and 0 deletions.
32 changes: 32 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Your domain name without protocol
# If you don't have your own domain (highly recommended)
# comment this out for first deployment, add your fly.dev domain here
# then reset your secrets and redeploy your app (untested)
DOMAIN_NAME=domain.name.com

###################
# E-mail settings #
###################

# the e-mail address used to send e-mails from both vaultwarden and restic
SMTP_FROM=[email protected]

# the e-mail address to notify on case of restic backup failure
SMTP_TO=[email protected]

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=[email protected]
SMTP_PASSWORD=88888888

###################
# Restic settings #
###################

# You don't need to initialize this repo beforehand
RESTIC_REPOSITORY=s3://88888888.r2.cloudflarestorage.com/uptime-kuma
RESTIC_PASSWORD=88888888

# If using S3 (or B2, wasabi, Minio) you'll need those
AWS_ACCESS_KEY_ID=88888888
AWS_SECRET_ACCESS_KEY=88888888
54 changes: 54 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Docker

on:
workflow_dispatch: {}
schedule:
- cron: '43 7 * * *'
push:
tags: [ '*' ]

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build:

runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw, value=latest, enable={{is_default_branch}}
type=semver, pattern={{version}}
type=ref, event=branch
type=ref, event=tag
type=ref, event=pr
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
67 changes: 67 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
FROM ghcr.io/gotify/server:2.4.0

WORKDIR /app

ARG SUPERCRONIC_URL=https://github.com/aptible/supercronic/releases/download/v0.2.29/supercronic-linux-amd64 \
OVERMIND_URL=https://github.com/DarthSim/overmind/releases/download/v2.4.0/overmind-v2.4.0-linux-amd64.gz

ENV TZ="Asia/Shanghai" \

GOTIFY_SERVER_PORT=8080 \

OVERMIND_CAN_DIE=crontab \
OVERMIND_PROCFILE=/Procfile \

SMTP_HOST=smtp.gmail.com \
SMTP_PORT=587 \
[email protected] \
SMTP_PASSWORD=88888888 \
[email protected] \
SMTP_TO= \

RESTIC_REPOSITORY=s3://88888888.r2.cloudflarestorage.com/gotify \
RESTIC_PASSWORD= \
AWS_ACCESS_KEY_ID= \
AWS_SECRET_ACCESS_KEY=

COPY config/crontab \
config/Procfile \
config/Caddyfile \
scripts/restic.sh \
/

RUN apt update && apt install -y --no-install-recommends \
debian-keyring \
debian-archive-keyring \
apt-transport-https \
gnupg \
curl \

&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg \
&& curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list \

&& apt update && apt install -y --no-install-recommends \
caddy \
restic \
ca-certificates \
openssl \
tzdata \
iptables \
iputils-ping \
tmux \
sqlite \
msmtp \
bsd-mailx \

&& rm -rf /var/lib/apt/lists/* && apt -y autoremove \
&& curl -fsSL "$SUPERCRONIC_URL" -o /usr/local/bin/supercronic \
&& curl -fsSL "$OVERMIND_URL" | gunzip -c - > /usr/local/bin/overmind \

&& ln -sf /usr/bin/msmtp /usr/bin/sendmail \
&& ln -sf /usr/bin/msmtp /usr/sbin/sendmail \

&& chmod +x /usr/local/bin/supercronic \
&& chmod +x /usr/local/bin/overmind \
&& chmod +x /restic.sh

ENTRYPOINT ["overmind", "start"]
Empty file added README.md
Empty file.
38 changes: 38 additions & 0 deletions config/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
# HTTPS/TLS is handled by Fly or on your domain (eg: Cloudflare)
auto_https off
admin off
persist_config off

log {
output stdout
format console
}
}

{$DOMAIN_NAME}:80 {
encode gzip

header / {
# Enable HTTP Strict Transport Security (HSTS)
Strict-Transport-Security "max-age=31536000;"
# Enable cross-site filter (XSS) and tell browser to block detected attacks
X-XSS-Protection "1; mode=block"
# Disallow the site to be rendered within a frame (clickjacking protection)
X-Frame-Options "DENY"
# Prevent search engines from indexing
X-Robots-Tag "noindex, nofollow"
# Disallow sniffing of X-Content-Type-Options
X-Content-Type-Options "nosniff"
# Server name removing
-Server
# Remove X-Powered-By though this shouldn't be an issue, better opsec to remove
-X-Powered-By
# Remove Last-Modified because etag is the same and is as effective
-Last-Modified
}

reverse_proxy localhost:8080 {
header_up X-Real-IP {remote_host}
}
}
3 changes: 3 additions & 0 deletions config/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
gotify: /app/gotify-app
caddy: caddy run --config /Caddyfile
crontab: supercronic /crontab
2 changes: 2 additions & 0 deletions config/crontab
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@hourly /restic.sh
@hourly /usr/bin/find /var/log/restic/ -name "*.log" -type f -mmin +600 -exec rm -f {} \;
120 changes: 120 additions & 0 deletions scripts/restic.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/bin/bash

if [ -z "$RESTIC_PASSWORD" ]; then
exit 1
fi

if [ -n "$SMTP_TO" ]; then
cat << EOF > /etc/msmtprc
defaults
auth on
tls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
logfile /var/log/msmtp.log
account default
host $SMTP_HOST
port $SMTP_PORT
from $SMTP_FROM
user $SMTP_USERNAME
password $SMTP_PASSWORD
EOF
fi

# catch the error in case first pipe command fails (but second succeeds)
set -o pipefail
# turn on traces, useful while debugging but commented out by default
# set -o xtrace

EMAIL_SUBJECT_PREFIX="[Restic]"
LOG="/var/log/restic/$(date +\%Y\%m\%d_\%H\%M\%S).log"

# create log dir
mkdir -p /var/log/restic/

# e-mail notification
function notify() {
if [ -n "$SMTP_TO" ]; then
sed -e 's/\x1b\[[0-9;]*m//g' "${LOG}" | mail -s "${EMAIL_SUBJECT_PREFIX} ${1}" ${SMTP_TO}
fi
}

function log() {
"$@" 2>&1 | tee -a "$LOG"
}

function run_silently() {
"$@" >/dev/null 2>&1
}

# ###############################################################################
# colorized echo helpers #
# taken from: https://github.com/atomantic/dotfiles/blob/master/lib_sh/echos.sh #
# ###############################################################################

ESC_SEQ="\x1b["
COL_RED=$ESC_SEQ"31;01m"
COL_BLUE=$ESC_SEQ"34;01m"
COL_GREEN=$ESC_SEQ"32;01m"
COL_YELLOW=$ESC_SEQ"33;01m"
COL_RESET=$ESC_SEQ"39;49;00m"

function ok() {
log echo -e "$COL_GREEN[ok]$COL_RESET $1"
}

function running() {
log echo -en "$COL_BLUE$COL_RESET $1..."
}

function warn() {
log echo -e "$COL_YELLOW[warning]$COL_RESET $1"
}

function error() {
log echo -e "$COL_RED[error]$COL_RESET $1"
log echo -e "$2"
}

function notify_and_exit_on_error() {
output=$(eval $1 2>&1)

if [ $? -ne 0 ]; then
error "$2" "$output"
notify "$2"
exit 2
fi
}

# ##############
# backup steps #
# ##############
restic unlock

running "checking restic config"

run_silently restic cat config

if [ $? -ne 0 ]; then
warn "restic repo either not initialized or erroring out"
running "trying to initialize it"
notify_and_exit_on_error "restic init" "Repo init failed"
fi

ok

running "backing up sqlite database"
notify_and_exit_on_error "sqlite3 /app/data/gotify.db '.backup /app/data/gotify.db.bak'" "SQLite backup failed"
ok

running "restic backup"
notify_and_exit_on_error "restic backup --verbose --exclude='*.db' /app/data" "Restic backup failed"
ok

running "checking consistency of restic repository"
notify_and_exit_on_error "restic check" "Restic check failed"
ok

running "removing outdated snapshots"
notify_and_exit_on_error "restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 3 --keep-yearly 3 --prune" "Restic forget failed"
ok

0 comments on commit 7f7382b

Please sign in to comment.