diff --git a/.gitignore b/.gitignore index 00f46e6..e86f283 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ __pycache__/ *$py.class *.cfg lenny.env +configs/lcp/processed/lcpserver.yaml + # C extensions *.so diff --git a/README.md b/README.md index b5fdf82..7e72739 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ cd lenny ./run.sh ``` -This process will run `docker/configure.sh` and generate a gitignored `.env` file with reasonable default values, if not present. +This process will run `docker/configure.sh` & `docker/lcpserverconfig.sh` to generate a gitignored `.env` & `lcpserver.yaml` file with reasonable default values, if not present. Navigate to localhost:8080 or whatever `$LENNY_PORT` is specified in your `.env` diff --git a/compose.yaml b/compose.yaml index 5ac1162..a3ae983 100644 --- a/compose.yaml +++ b/compose.yaml @@ -98,6 +98,31 @@ services: networks: - lenny_network + lcp: + build: + context: . + dockerfile: docker/lcp-server/Dockerfile + container_name: lenny_lcp + env_file: .env + ports: + - "8081:8081" + depends_on: + db: + condition: service_healthy + environment: + - LCPSERVER_CONFIG=/app/config/lcpserver.yaml + - LCP_PORT=${LCP_PORT:-8081} + - LCP_SERVER_URL=${LCP_SERVER_URL} + - LCP_ADMIN_USERNAME=${LCP_SERVER_ADMIN_USER} + - LCP_ADMIN_PASSWORD=${LCP_SERVER_ADMIN_PASSWORD} + volumes: + - ./configs/lcp/processed:/app/config:ro + - lcp_data:/app/data + networks: + - lenny_network + restart: unless-stopped + + networks: lenny_network: driver: bridge @@ -106,3 +131,4 @@ volumes: db_data: s3_data: readium_data: + lcp_data: diff --git a/docker/configure.sh b/docker/configure.sh index 75a0d72..284b58c 100755 --- a/docker/configure.sh +++ b/docker/configure.sh @@ -25,10 +25,14 @@ LENNY_SSL_KEY="${LENNY_SSL_KEY:-}" READER_PORT="${READER_PORT:-3000}" READIUM_PORT="${READIUM_PORT:-15080}" +LCP_PORT="${LCP_PORT:-8081}" +LCP_SERVER_URL="${LCP_SERVER_URL:-http://localhost:$LCP_PORT}" +LCP_SERVER_ADMIN_USER="${LCP_SERVER_ADMIN_USER:-$(genpass 16)}" +LCP_SERVER_ADMIN_PASSWORD="${LCP_SERVER_ADMIN_PASSWORD:-$(genpass 32)}" + DB_USER="${POSTGRES_USER:-librarian}" DB_HOST="${POSTGRES_HOST:-127.0.0.1}" DB_PORT="${POSTGRES_PORT:-5432}" - DB_PASSWORD="${POSTGRES_PASSWORD:-$(genpass 32)}" DB_NAME="${DB_NAME:-lenny}" @@ -52,6 +56,12 @@ LENNY_SSL_KEY=$LENNY_SSL_KEY READER_PORT=$READER_PORT READIUM_PORT=$READIUM_PORT +# LCP Server +LCP_PORT=$LCP_PORT +LCP_SERVER_URL=$LCP_SERVER_URL +LCP_SERVER_ADMIN_USER=$LCP_SERVER_ADMIN_USER +LCP_SERVER_ADMIN_PASSWORD=$LCP_SERVER_ADMIN_PASSWORD + # DB DB_USER=$DB_USER DB_HOST=$DB_HOST diff --git a/docker/lcp-server/Dockerfile b/docker/lcp-server/Dockerfile new file mode 100644 index 0000000..0ec994e --- /dev/null +++ b/docker/lcp-server/Dockerfile @@ -0,0 +1,53 @@ +FROM golang:1.23-alpine AS builder + +WORKDIR /app + +RUN apk add --no-cache git +RUN git clone https://github.com/edrlab/lcp-server.git . +RUN go get gorm.io/driver/postgres +RUN go mod tidy +RUN go mod download && go mod verify + + +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags \ + '-extldflags "-static"' -tags PGSQL -o /app/lcpserver ./cmd/lcpserver + +RUN ls -la /app + +FROM alpine:latest +WORKDIR /app + +COPY --from=builder /app/lcpserver ./lcpserver + +RUN ls -l /app +RUN chmod +x ./lcpserver +RUN apk add --no-cache openssl + +RUN cat <<'EOF' > ./start.sh +#!/bin/sh +set -e + +# Print environment variables +echo "--- Environment variables ---" +env + +echo "--- Checking/generating certificates ---" +mkdir -p /app/cert +if [ ! -f /app/cert/cert-edrlab-test.pem ] || [ ! -f /app/cert/privkey-edrlab-test.pem ]; then + echo "Generating self-signed certificate..." + openssl req -x509 -newkey rsa:2048 -keyout /app/cert/privkey-edrlab-test.pem -out /app/cert/cert-edrlab-test.pem -days 365 -nodes -subj "/CN=lcpserver" +fi + +echo "--- Starting LCP server ---" +ls -la /app/config/ +cat /app/config/lcpserver.yaml +echo "File content displayed above. Now trying to run lcpserver with explicit config..." +./lcpserver -config /app/config/lcpserver.yaml + + +EOF +RUN chmod +x ./start.sh + +ENV LCPSERVER_CONFIG=/app/config/lcpserver.yaml + +ENTRYPOINT ["./start.sh"] diff --git a/docker/lcpserverconfig.sh b/docker/lcpserverconfig.sh new file mode 100755 index 0000000..c02ff24 --- /dev/null +++ b/docker/lcpserverconfig.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +set -o allexport +source .env +set +o allexport + +mkdir -p ./configs/lcp/processed + +envsubst < lcpserver.yaml.template > ./configs/lcp/processed/lcpserver.yaml diff --git a/lcpserver.yaml.template b/lcpserver.yaml.template new file mode 100644 index 0000000..165872b --- /dev/null +++ b/lcpserver.yaml.template @@ -0,0 +1,21 @@ +public_base_url: ${LCP_SERVER_URL} +port: 8081 +dsn: "postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable" + +access: + username: ${LCP_SERVER_ADMIN_USER} + password: ${LCP_SERVER_ADMIN_PASSWORD} + +license: + provider: "http://lennyforlibrarians.org" + profile: "http://readium.org/lcp/basic-profile" + hint_link: "http://lennyforlibrarians.org/help/lcp/{license_id}" + +status: + renew_default_days: 30 + renew_max_days: 365 + renew_link: "http://lennyforlibrarians.org/renew/{license_id}" + +certificate: + cert: "/app/cert/cert-edrlab-test.pem" + private_key: "/app/cert/privkey-edrlab-test.pem" diff --git a/lenny/configs/__init__.py b/lenny/configs/__init__.py index 328ace6..941aef7 100644 --- a/lenny/configs/__init__.py +++ b/lenny/configs/__init__.py @@ -29,6 +29,11 @@ READIUM_PORT = int(os.environ.get('READIUM_PORT', 15080)) READIUM_BASE_URL = f"http://lenny_readium:{READIUM_PORT}" +LCP_PORT = int(os.environ.get('LCP_PORT')) +LCP_SERVER_URL = os.environ.get('LCP_SERVER_URL') +LCP_SEVER_ADMIN = os.environ.get('LCP_SERVER_ADMIN') +LCP_SERVER_PASSWORD = os.environ.get('LCP_SERVER_PASSWORD') + OPTIONS = { 'host': HOST, 'port': PORT, @@ -63,4 +68,10 @@ 'secure': os.environ.get('S3_SECURE', 'false').lower() == 'true', } -__all__ = ['SCHEME', 'HOST', 'PORT', 'DEBUG', 'OPTIONS', 'DB_URI', 'DB_CONFIG','S3_CONFIG', 'TESTING'] +LCP_SERVER = { + 'url': LCP_SERVER_URL, + 'admin_username': LCP_SEVER_ADMIN, + 'admin_password': LCP_SERVER_PASSWORD, +} + +__all__ = ['SCHEME', 'HOST', 'PORT', 'DEBUG', 'OPTIONS', 'DB_URI', 'DB_CONFIG','S3_CONFIG', 'LCP_SERVER', 'TESTING'] diff --git a/run.sh b/run.sh index a137466..bb215b4 100755 --- a/run.sh +++ b/run.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash ./docker/configure.sh +./docker/lcpserverconfig.sh MODE= LOG= @@ -123,6 +124,8 @@ function create_tunnel() { echo "[+] Loading .env file" export $(grep -v '^#' .env | xargs) +echo "[+] Generated lcp-server configuration files" + if [[ "$PUBLIC" == "true" ]]; then create_tunnel fi @@ -156,3 +159,5 @@ if [[ "$LOG" == "true" ]]; then elif [[ "$PUBLIC" == "true" ]]; then read -p "[+] Press Enter to close tunnel..." fi + +# End of script