diff --git a/memos/backup.sh b/memos/backup.sh new file mode 100755 index 0000000..c75201b --- /dev/null +++ b/memos/backup.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Note: use rclone for backup, needs manually configuration. + +export XDG_RUNTIME_DIR="/run/user/$(id -u)" +export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus" + +DATA="" +DB="" +LOCAL_BACKUP="$HOME/.local/backup" +REMOTE="" +DB_USERNAME="" +DB_PASSWORD="" +DB_DATABASE="" +CONTAINER_DB="" +SERVICE="" + +STAGING_DIR=$(mktemp -d) +mkdir -p $LOCAL_BACKUP +DATE=$(date +%F-%H-%M-%S) +BACKUP_NAME="backup_$DATE.tar.gz" + +systemctl --user stop $SERVICE +podman exec $CONTAINER_DB pg_dump -U $DB_USERNAME -F c -d $DB_DATABASE > $STAGING_DIR/db.dump + +cp -r "$DATA" "$STAGING_DIR/data" +cp -r "$DB" "$STAGING_DIR/db" +tar -czf "$LOCAL_BACKUP/$BACKUP_NAME" -C "$STAGING_DIR" . + +ls -1t "$LOCAL_BACKUP"/backup_*.tar.gz | tail -n +6 | xargs -r rm -- + + +/usr/bin/rclone sync $LOCAL_BACKUP $REMOTE > /dev/null + +rm -rf $STAGING_DIR + +systemctl --user start $SERVICE \ No newline at end of file diff --git a/memos/deploy.sh b/memos/deploy.sh new file mode 100755 index 0000000..1f50850 --- /dev/null +++ b/memos/deploy.sh @@ -0,0 +1,144 @@ +#!/bin/bash + +. ./env.sh + +set -e + +services=("$CONTAINER_PREFIX-$CONTAINER_SERVICE.service" + "$CONTAINER_PREFIX-$CONTAINER_DB.service" +) + +for service in "${services[@]}"; do + if systemctl --user list-units --full --all | grep -q "$service"; then + echo "Stopping $service..." + systemctl --user stop $service + echo "$service stopped." + fi +done + +containers=( + "$CONTAINER_SERVICE" + "$CONTAINER_DB" +) + +for container in "${containers[@]}"; do + if podman container exists "$container"; then + echo "Stop and delete existing container $container" + if podman inspect -f '{{.State.Running}}' "$container" | grep -q true; then + podman stop "$container" + fi + podman rm "$container" +fi +done + +if ! podman network exists $NETWORK; then + podman network create $NETWORK +fi + +mkdir -p $DATA_FOLDER +mkdir -p $DB_FOLDER +mkdir -p $USER_SYSTEMD + +podman create \ + --name $CONTAINER_DB \ + --network $NETWORK \ + --userns=keep-id \ + --restart=always \ + -p $PORT_DB:5432 \ + -e POSTGRES_USER=$DB_USER \ + -e POSTGRES_PASSWORD=$DB_PASSWORD \ + -e POSTGRES_DB=$DB_NAME \ + -e POSTGRES_HOST_AUTH_METHOD=trust \ + -v "$DB_FOLDER:/var/lib/postgresql/data:Z" \ + docker.io/library/postgres:16 + +podman generate systemd \ + --new \ + --name $CONTAINER_DB \ + --files --restart-policy always --container-prefix=$CONTAINER_PREFIX > /dev/null + +mv $CONTAINER_PREFIX-$CONTAINER_DB.service $USER_SYSTEMD +systemctl --user daemon-reload +systemctl --user enable --now $CONTAINER_PREFIX-$CONTAINER_DB.service +echo "Wait for PostgreSQL..." +until podman exec $CONTAINER_DB pg_isready -U "$DB_USER" -d "$DB_NAME" > /dev/null 2>&1; do + sleep 2 +done +echo "PostgreSQL ready" + +podman create \ + --name $CONTAINER_SERVICE \ + --network $NETWORK \ + --restart=always \ + -p $PORT_WEB:5230 \ + -v "$DATA_FOLDER:/var/opt/memos:Z" \ + -e MEMOS_DRIVER=postgres \ + -e MEMOS_DSN="postgresql://$DB_USER:$DB_USER@$HOST_DB:$PORT_DB/memos?sslmode=disable" \ + docker.io/neosmemo/memos:stable + +podman generate systemd \ + --new \ + --name $CONTAINER_SERVICE \ + --files \ + --container-prefix=$CONTAINER_PREFIX \ + --restart-policy=always + +sed -i "/^\[Unit\]/a After=$CONTAINER_PREFIX-$CONTAINER_DB.service \nRequires=$CONTAINER_PREFIX-$CONTAINER_DB.service" $CONTAINER_PREFIX-$CONTAINER_SERVICE.service + +mv $CONTAINER_PREFIX-$CONTAINER_SERVICE.service $USER_SYSTEMD +systemctl --user daemon-reload +systemctl --user enable --now $CONTAINER_PREFIX-$CONTAINER_SERVICE.service + +sudo loginctl enable-linger $USER + +# generate haproxy blocks +sudo mkdir -p $SERVICE_DIR +echo "crt $SSL_PATH/fullchain.pem" | sudo tee $SERVICE_DIR/cert.block > /dev/null +ACL_CFG=$(cat < /dev/null +BACKEND_CFG=$(cat < /dev/null + +echo "Generate backup script" +BACKUP_FILE="memos_backup.sh" +cp backup.sh $BACKUP_FILE +sed -i "s|^DATA=\"\"|DATA=\"$DATA_FOLDER\"|" "$BACKUP_FILE" +sed -i "s|^DB=\"\"|DB=\"$DB_FOLDER\"|" "$BACKUP_FILE" +sed -i "s|^DB_USERNAME=\"\"|DB_USERNAME=\"$DB_USER\"|" "$BACKUP_FILE" +sed -i "s|^DB_DATABASE=\"\"|DB_DATABASE=\"$DB_NAME\"|" "$BACKUP_FILE" +sed -i "s|^DB_PASSWORD=\"\"|DB_PASSWORD=\"$DB_PASSWORD\"|" "$BACKUP_FILE" +sed -i "s|^LOCAL_BACKUP=\"\$HOME/.local/backup\"|LOCAL_BACKUP=\"\$HOME/.local/backup/$CONTAINER_PREFIX\"|" "$BACKUP_FILE" +sed -i "s|^CONTAINER_DB=\"\"|CONTAINER_DB=\"$CONTAINER_DB\"|" "$BACKUP_FILE" +sed -i "s|^REMOTE=\"\"|REMOTE=\"$BACKUP_REMOTE\"|" "$BACKUP_FILE" +sed -i "s|^SERVICE=\"\"|SERVICE=\"${CONTAINER_PREFIX}-${CONTAINER_SERVICE}.service\"|" "$BACKUP_FILE" + +mv $BACKUP_FILE $APP_DIR +echo "Backup script generated at $APP_FOLDER/$BACKUP_FILE" +echo "Backup script will be run every day at 2:00 AM" +crontab -l | grep -v "$APP_FOLDER/$BACKUP_FILE" | crontab - +(crontab -l 2>/dev/null; echo "0 2 * * * $APP_DIR/$BACKUP_FILE") | crontab - +echo "Backup script added to crontab" + +echo "Deploy completed, manually run haproxy to generate new config." diff --git a/memos/env.sh b/memos/env.sh new file mode 100644 index 0000000..1a20721 --- /dev/null +++ b/memos/env.sh @@ -0,0 +1,21 @@ +CONTAINER_PREFIX="memos" +CONTAINER_SERVICE="memos" +CONTAINER_DB="memos-db" +NETWORK="memos-net" +APP_DIR="$HOME/.local/share/memos" +DATA_FOLDER=$APP_DIR/data +DB_FOLDER=$APP_DIR/db +USER_SYSTEMD="$HOME/.config/systemd/user" +HOST_DB="host.containers.internal" +PORT_DB=5632 +PORT_WEB=5630 +DB_USER="memos" +DB_PASSWORD="memos" +DB_NAME="memos" + +DOMAIN="" +SSL_PATH=$HOME/.config/ssl/$DOMAIN +HAPROXY_CFG_DIR="/etc/haproxy" +HAPROXY_CFG="$HAPROXY_CFG_DIR/haproxy.cfg" +SERVICE_DIR="$HAPROXY_CFG_DIR/services/$DOMAIN" +BACKUP_REMOTE="onedrive-tianyu:Backups/memos" \ No newline at end of file diff --git a/memos/uninstall.sh b/memos/uninstall.sh new file mode 100755 index 0000000..e043339 --- /dev/null +++ b/memos/uninstall.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +. ./env.sh + +services=("$CONTAINER_PREFIX-$CONTAINER_SERVICE.service" + "$CONTAINER_PREFIX-$CONTAINER_DB.service" +) + +for service in "${services[@]}"; do + if systemctl --user list-units --full --all | grep -q "$service"; then + echo "Stopping $service..." + systemctl --user stop $service + echo "$service stopped." + fi +done + +containers=( + "$CONTAINER_SERVICE" + "$CONTAINER_DB" +) + +for container in "${containers[@]}"; do + if podman container exists "$container"; then + echo "Stop and delete existing container $container" + if podman inspect -f '{{.State.Running}}' "$container" | grep -q true; then + podman stop "$container" + fi + podman rm "$container" +fi +done + +for service in "${services[@]}"; do + systemctl --user disable --now $service + rm $USER_SYSTEMD/$service +done + +sudo rm -r $SERVICE_DIR +crontab -l | grep -v "$APP_DIR/$BACKUP_FILE" | crontab - + +echo "Uninstall complete. Manually run haproxy config to rebuild config. Manually remove data directory + - $APP_DIR + - $HOME/.local/backup/$CONTAINER_PREFIX +if needed." \ No newline at end of file