Skip to content

Commit

Permalink
🐝
Browse files Browse the repository at this point in the history
  • Loading branch information
webees committed Feb 19, 2024
0 parents commit 9b81e90
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 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=from@mail.com

# the e-mail address to notify on case of restic backup failure
SMTP_TO=to@mail.com

# https://github.com/dani-garcia/vaultwarden/wiki/SMTP-Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=88888888@gmail.com
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
55 changes: 55 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Docker

on:
workflow_dispatch: {}
schedule:
- cron: '43 7 * * *'
push:
branches: [ "main" ]
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 }}
48 changes: 48 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
FROM louislam/uptime-kuma:1.23.11-debian

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 OVERMIND_CAN_DIE=setup-msmtp \
OVERMIND_PROCFILE=/Procfile

COPY config/crontab \
config/Procfile \
config/Caddyfile \
scripts/restic-backup.sh \
scripts/setup-msmtp.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-backup.sh && \
chmod +x /setup-msmtp.sh

CMD ["overmind", "start"]
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
```
fly auth login
fly apps create uptime-kuma
cat .env | fly secrets import
fly volumes create app_data --size 1
fly deploy
fly ssh console
```
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 json
}
}

{$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:5000 {
header_up X-Real-IP {remote_host}
}
}
4 changes: 4 additions & 0 deletions config/Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
uptime-kuma: cd /app && node server/server.js --port=5000
caddy: caddy run --config /Caddyfile
restic-backup: supercronic /crontab
setup-msmtp: /setup-msmtp.sh
2 changes: 2 additions & 0 deletions config/crontab
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@hourly /restic-backup.sh
@hourly /usr/bin/find /var/log/restic/ -name "*.log" -type f -mmin +600 -exec rm -f {} \;
27 changes: 27 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
app = "uptime-kuma"
primary_region = "sjc"
kill_signal = "SIGINT"
kill_timeout = 5
swap_size_mb = 256

[build]
image = "ghcr.io/webees/uptime-kuma"

[mounts]
source = "app_data"
destination = "/app/data"

[http_service]
internal_port = 80
force_https = true
min_machines_running = 1

[checks]
[checks.health]
grace_period = "30s"
interval = "15s"
method = "get"
path = "/socket.io/?EIO=4&transport=polling"
port = 80
timeout = "10s"
type = "http"
97 changes: 97 additions & 0 deletions scripts/restic-backup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/bin/bash

# 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() {
sed -e 's/\x1b\[[0-9;]*m//g' "${LOG}" | mail -s "${EMAIL_SUBJECT_PREFIX} ${1}" ${SMTP_TO}
}

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/db.sqlite3 '.backup /app/data/backup.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
23 changes: 23 additions & 0 deletions scripts/setup-msmtp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash

SMTP_HOST=${SMTP_HOST:-smtp.gmail.com}
SMTP_PORT=${SMTP_PORT:-587}
SMTP_USERNAME=${SMTP_USERNAME:-88888888@gmail.com}
SMTP_PASSWORD=${SMTP_PASSWORD:-88888888}
SMTP_FROM=${SMTP_FROM:-88888888@gmail.com}
SMTP_TO=${SMTP_TO:-88888888@gmail.com}

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

0 comments on commit 9b81e90

Please sign in to comment.