From 65facfa8b177437f124957949dd29c0dfbeda833 Mon Sep 17 00:00:00 2001 From: DrMaxNix Date: Mon, 2 Sep 2024 22:51:10 +0200 Subject: [PATCH] :tada: initial codebase --- Dockerfile | 15 ++++++ entrypoint.sh | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 13 +++++ 3 files changed, 162 insertions(+) create mode 100644 Dockerfile create mode 100755 entrypoint.sh create mode 100644 index.html diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a611a6b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM alpine:latest +RUN apk --update add bash python3 py3-virtualenv py3-pip git && rm -rf /var/cache/apk/* + +RUN git clone https://github.com/etesync/server.git /opt/etebase +WORKDIR /opt/etebase +RUN virtualenv -p python3 .venv +RUN .venv/bin/pip3 install -r requirements.txt + +# NOTE: Workaround, since some packages seem to be missing in requirements.txt (see https://github.com/etesync/server/issues/185) +RUN .venv/bin/pip3 install tzdata + +COPY ./entrypoint.sh /entrypoint.sh +COPY ./index.html /index.html + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..42df2c7 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +set -euo pipefail + + +## CONSTANTS ## +readonly CODEBASE_DIR="/opt/etebase" +readonly DATA_DIR="/opt/etebase-data" + + +## HANDLE EXIT SIGNALS ## +trap trap_exit EXIT SIGINT SIGTERM +trap_exit(){ + if [[ "${pid:+x}" ]]; then + kill -- $pid 2> /dev/null || true + q=0 + while proc_running $pid; do + q=$(( q + 1 )) + snore 1 + if [[ "$q" -ge 15 ]]; then + log_warn "Sending kill to Etebase" + kill -s KILL -- $pid 2> /dev/null || true + break + fi + done + fi + exit 0 +} + + + +# +# LIB: Efficient sleep (does not create a new process). +# +snore(){ + local IFS + [[ -n "${_snore_fd:-}" ]] || exec {_snore_fd}<> <(:) + read ${1:+-t "$1"} -u $_snore_fd || true +} + + + +# +# HELPER: Check whether given pid is running. +# +# @param $1 Process ID. +# +# @exit 0: Process is running +# 1: Process is not running. +# +proc_running(){ + # try reading state + local state_path="/proc/$1/stat" + [[ ! -f "$state_path" ]] && return 1 + local state + state=$(cat "$state_path" 2> /dev/null | cut -d ' ' -f3) || return 1 + + # parse state + case "$state" in + R|S|D|Z|W|W|P|I) return 0;; + *) return 1;; + esac +} + + + +# +# HELPER: Initialize etebase config files. +# +etebase_config_init(){ + ## MAYBE CREATE SYMLINK ## + if [[ ! -h "${CODEBASE_DIR}/etebase-server.ini" ]]; then + ln -s "${DATA_DIR}/server.ini" "${CODEBASE_DIR}/etebase-server.ini" + fi + + + ## MAYBE WRITE DEFAULT FILE ## + if [[ ! -f "${DATA_DIR}/server.ini" ]]; then + echo "[global] +debug = false +secret_file = ${DATA_DIR}/secret.txt +static_root = ${CODEBASE_DIR}/static +media_root = ${DATA_DIR}/media +;language_code = en-us +;time_zone = UTC + +[allowed_hosts] +allowed_host1 = * + +[database] +engine = django.db.backends.sqlite3 +name = db.sqlite3" > "${DATA_DIR}/server.ini" + fi +} + + + +# +# HELPER: Initialize django app. +# +etebase_app_init(){ + ## RUN MIGRATIONS ## + .venv/bin/python3 ./manage.py migrate + + + ## MAYBE COPY STATIC FILES ## + if [[ ! -d "${CODEBASE_DIR}/static" ]]; then + .venv/bin/python3 ./manage.py collectstatic + fi + + + ## OVERWRITE INDEX PAGE ## + cat /index.html > "${CODEBASE_DIR}/etebase_server/templates/success.html" +} + + + + + +## SET UP DATA DIRECTORIES ## +mkdir -p "$DATA_DIR" +mkdir -p "${DATA_DIR}/media" + + +## INITIALIZE CONFIG ## +etebase_config_init + + +## INITIALIZE DJANGO APP ## +etebase_app_init + + +## RUN SERVER ## +.venv/bin/uvicorn etebase_server.asgi:application --host 0.0.0.0 --port 80 & pid=$! +wait $pid diff --git a/index.html b/index.html new file mode 100644 index 0000000..5fba58e --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + EteBase Docker + + +

EteBase Docker

+

Usage Instructions (README.md)

+

EteSync Website

+

Admin Interface

+ +