From e73142c21fe46b4bb92faf441af454251deaf6ce Mon Sep 17 00:00:00 2001 From: Benjamin Dweck Date: Wed, 6 Sep 2023 17:09:19 +0000 Subject: [PATCH] Initial commit --- .gitignore | 2 ++ anki-sync/Dockerfile | 59 +++++++++++++++++++++++++++++++ anki-sync/bin/download-release.sh | 15 ++++++++ anki-sync/bin/entrypoint.sh | 15 ++++++++ anki-sync/docker-compose.yml | 14 ++++++++ docker-compose.yml | 13 +++++++ install.sh | 59 +++++++++++++++++++++++++++++++ sample.env | 1 + service/anki-sync-server.service | 14 ++++++++ 9 files changed, 192 insertions(+) create mode 100644 .gitignore create mode 100644 anki-sync/Dockerfile create mode 100755 anki-sync/bin/download-release.sh create mode 100755 anki-sync/bin/entrypoint.sh create mode 100644 anki-sync/docker-compose.yml create mode 100644 docker-compose.yml create mode 100755 install.sh create mode 100644 sample.env create mode 100644 service/anki-sync-server.service diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0c54f60 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +data/ +.env diff --git a/anki-sync/Dockerfile b/anki-sync/Dockerfile new file mode 100644 index 0000000..62eb5e3 --- /dev/null +++ b/anki-sync/Dockerfile @@ -0,0 +1,59 @@ +ARG ANKISYNCD_ROOT=/opt/ankisyncd +ARG PYTHONUSERBASE=/opt/venv + +# -- BUILDER -- +FROM library/python:3.9-buster as builder + +ARG ANKISYNCD_ROOT +WORKDIR ${ANKISYNCD_ROOT} + +COPY bin/download-release.sh ./bin/download-release.sh + +ARG PYTHONUSERBASE +RUN sh ./bin/download-release.sh && \ + pip3 install --upgrade pip && \ + pip3 install --user -r ./release/requirements.txt + +# -- DEPLOYER -- +FROM python:3.9-slim-buster + +# Copy Python dependencies +ARG PYTHONUSERBASE +ENV PYTHONUSERBASE=${PYTHONUSERBASE} +COPY --from=builder ${PYTHONUSERBASE} ${PYTHONUSERBASE} + +# Copy Anki Sync Server release and scripts +ARG ANKISYNCD_ROOT +COPY --from=builder ${ANKISYNCD_ROOT}/release ${ANKISYNCD_ROOT} +WORKDIR ${ANKISYNCD_ROOT} + +# Move ankisyncctl.py to the working directory and make it executable +RUN mv /opt/ankisyncd/ankisyncd_cli/ankisyncctl.py /opt/ankisyncd/ankisyncctl.py && \ + chmod +x /opt/ankisyncd/ankisyncctl.py + +# Create data volume. +ARG ANKISYNCD_DATA_ROOT=/srv/ankisyncd +VOLUME ${ANKISYNCD_DATA_ROOT} + +# Set default environment variables. +ARG ANKISYNCD_PORT=27701 +ARG ANKISYNCD_BASE_URL=/sync/ +ARG ANKISYNCD_BASE_MEDIA_URL=/msync/ + +ENV ANKISYNCD_HOST=0.0.0.0 \ + ANKISYNCD_PORT=${ANKISYNCD_PORT} \ + ANKISYNCD_DATA_ROOT=${ANKISYNCD_DATA_ROOT} \ + ANKISYNCD_BASE_URL=${ANKISYNCD_BASE_URL} \ + ANKISYNCD_BASE_MEDIA_URL=${ANKISYNCD_BASE_MEDIA_URL} \ + ANKISYNCD_AUTH_DB_PATH=/data/auth.db \ + ANKISYNCD_SESSION_DB_PATH=/data/session.db \ + ANKISYNCD_DATA_ROOT=/data + +COPY bin/entrypoint.sh ./bin/entrypoint.sh + +EXPOSE ${ANKISYNCD_PORT} + +# TODO: Change to ENTRYPOINT. Currently CMD to allow shell access if needed. +CMD ["/bin/sh", "./bin/entrypoint.sh"] + +HEALTHCHECK --interval=60s --timeout=3s CMD python -c "import requests; requests.get('http://127.0.0.1:${ANKISYNCD_PORT}/')" diff --git a/anki-sync/bin/download-release.sh b/anki-sync/bin/download-release.sh new file mode 100755 index 0000000..1ce1fa9 --- /dev/null +++ b/anki-sync/bin/download-release.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# file: download-release.sh + + +mkdir -p release + +cd release + +git clone https://github.com/ankicommunity/anki-sync-server + +mv anki-sync-server/src/* . + +rm -rf anki-sync-server + +cd .. \ No newline at end of file diff --git a/anki-sync/bin/entrypoint.sh b/anki-sync/bin/entrypoint.sh new file mode 100755 index 0000000..f7a96b8 --- /dev/null +++ b/anki-sync/bin/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/sh +# file: entrypoint.sh + +# if [ -f "/app/data/auth.db" ]; then +# echo "auth.db found" +# else +# echo "Creating new authentication database: auth.db." +# sqlite3 /app/data/auth.db 'CREATE TABLE auth (user VARCHAR PRIMARY KEY, hash VARCHAR)' +# fi + +# echo "Updating database schema" +# python3 utils/migrate_user_tables.py + +echo "Starting anki-sync-server" +python3 -m ankisyncd \ No newline at end of file diff --git a/anki-sync/docker-compose.yml b/anki-sync/docker-compose.yml new file mode 100644 index 0000000..dd481fe --- /dev/null +++ b/anki-sync/docker-compose.yml @@ -0,0 +1,14 @@ +version: '3.7' +services: + + anki_sync_server: + image: ${DOCKER_IMAGE:-anki-sync-server}:${DOCKER_VERSION:-latest} + build: + context: . + dockerfile: Dockerfile + args: + - ANKISYNCD_PORT=${ANKISYNCD_PORT:-27701} + - ANKISYNCD_BASE_URL=${ANKISYNCD_BASE_URL:-/sync/} + - ANKISYNCD_BASE_MEDIA_URL=${ANKISYNCD_BASE_MEDIA_URL:-/msync/} + - ANKISYNCD_AUTH_DB_PATH=${ANKISYNCD_AUTH_DB_PATH:-./auth.db} + - ANKISYNCD_SESSION_DB_PATH=${ANKISYNCD_SESSION_DB_PATH:-./session.db} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..12f3b33 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' +services: + anki-sync-server: + build: ./anki-sync + environment: + - ANKISYNCD_DATA_ROOT=/data + - ANKISYNCD_AUTH_DB_PATH=/data/auth.db + - ANKISYNCD_SESSION_DB_PATH=/data/session.db + ports: + - "${ANKI_PORT}:27701" + volumes: + - "${ANKI_VOLUME_PATH}:/data" + diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..571f5a1 --- /dev/null +++ b/install.sh @@ -0,0 +1,59 @@ +#!/bin/bash + +# Set variables +SERVICE_FILE="service/anki-sync-server.service" +SYSTEMD_DIR="/etc/systemd/system" +ENV_SAMPLE="sample.env" +ENV_TARGET=".env" + +# Check if root +if [[ $EUID -ne 0 ]]; then + echo "This script must be run as root." + exit 1 +fi + +# Copy service file to systemd directory +if [ -e "$SERVICE_FILE" ]; then + cp -n "$SERVICE_FILE" "$SYSTEMD_DIR" + if [ $? -eq 0 ]; then + echo "Service file copied successfully." + systemctl daemon-reload + if [ $? -eq 0 ]; then + echo "Daemon reloaded successfully." + else + echo "Failed to reload the daemon." + exit 1 + fi + else + echo "Failed to copy the service file." + exit 1 + fi +else + echo "Service file $SERVICE_FILE does not exist." + exit 1 +fi + +# Copy sample.env to .env if it does not already exist +if [ ! -e "$ENV_TARGET" ]; then + if [ -e "$ENV_SAMPLE" ]; then + cp "$ENV_SAMPLE" "$ENV_TARGET" + if [ $? -eq 0 ]; then + echo ".env file created successfully." + else + echo "Failed to create .env file." + exit 1 + fi + else + echo "Sample env file $ENV_SAMPLE does not exist." + exit 1 + fi +else + echo ".env file already exists, skipping." +fi + +# Remind user to create data directory +echo "Remember to create the data directory on your local machine." + +# Script completed successfully +exit 0 + diff --git a/sample.env b/sample.env new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/sample.env @@ -0,0 +1 @@ +.env diff --git a/service/anki-sync-server.service b/service/anki-sync-server.service new file mode 100644 index 0000000..9dc0a75 --- /dev/null +++ b/service/anki-sync-server.service @@ -0,0 +1,14 @@ +[Unit] +Description=Anki Sync Server +Requires=docker.service +After=docker.service + +[Service] +WorkingDirectory=/var/lib/anki +ExecStart=/usr/local/bin/docker-compose up +ExecStop=/usr/local/bin/docker-compose down +Restart=always +EnvironmentFile=/var/lib/anki/.env + +[Install] +WantedBy=multi-user.target