From f75488d44c8a9a4e07eab7a549a9a1ea02e6e48c Mon Sep 17 00:00:00 2001 From: Daniel Freiling Date: Fri, 26 Apr 2024 20:29:26 +0200 Subject: [PATCH] feat(ci): add default config & htpasswd for local testing --- .dockerignore | 3 +- .github/workflows/ci.yml | 2 +- .gitignore | 3 + ci/README.md | 34 ++++++++++++ ci/build.sh | 5 ++ {docker => ci}/docker-compose.yml | 11 ++-- ci/htpasswd | 1 + ci/lcp/Dockerfile | 49 ++++++++++++++++ docker/build.sh | 4 -- docker/cert/cert-edrlab-test.pem | 33 ----------- docker/cert/privkey-edrlab-test.pem | 52 ----------------- docker/htpasswd | 1 - docker/lcp/Dockerfile | 35 ------------ test/config.localhost.yaml | 86 +++++++++++++++++++++++++++++ 14 files changed, 185 insertions(+), 134 deletions(-) create mode 100644 ci/README.md create mode 100755 ci/build.sh rename {docker => ci}/docker-compose.yml (67%) create mode 100644 ci/htpasswd create mode 100644 ci/lcp/Dockerfile delete mode 100755 docker/build.sh delete mode 100644 docker/cert/cert-edrlab-test.pem delete mode 100644 docker/cert/privkey-edrlab-test.pem delete mode 100644 docker/htpasswd delete mode 100644 docker/lcp/Dockerfile create mode 100644 test/config.localhost.yaml diff --git a/.dockerignore b/.dockerignore index bdb96709..d70b1984 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,2 @@ -docker +ci +!ci/htpasswd diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f3384d53..00c4e2e9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,7 @@ jobs: uses: docker/build-push-action@v5.3.0 with: context: "." - file: "./docker/lcp/Dockerfile" + file: "./ci/lcp/Dockerfile" push: ${{ github.event_name != 'pull_request' }} # Don't push on PR tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index 582c52a0..048cd4c7 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,9 @@ debug *.exe *.yaml !test/config.yaml +!test/config.localhost.yaml +!ci/htpasswd +!ci/*.yaml **/manage/config.js frontend/manage/node_modules/* frontend/manage/dist/* diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 00000000..f82dfe3c --- /dev/null +++ b/ci/README.md @@ -0,0 +1,34 @@ +# CI setup for Readium LCP + +This folder contains the CI setup for Readium LCP. It contains Dockerfiles for each server component and a Helm chart for easy kubernetes deployment. + +## Dockerfiles +Simple Dockerfile which contains all executables and a localhost config for testing. + +The only difference between LCP and LSD images is which executable is run. +They are defined in the same Dockerfile using the following stage targets: +* runtime-lcp +* runtime-lsd + +## Build and run LCP & LSD servers +To test LCP server components locally, simply run this command: +``` +docker compose up -d +``` + +## Placeholders + +### config.localhost.yaml +Simple config for local testing. Assumes you will expose ports 8989-8990 on 127.0.0.1. + +### htpasswd +Placeholder htpasswd is just `admin` as username and `Test1234` as password. + +## Overriding with volumes + +You should not run the default config in production. To change the config, simply use volume mounts to override the following files: +* `/app/config.yaml` +* `/app/htpasswd` +* `/app/certs` + +Basically the config.yaml decides the location of all other files and which ports to use, so modify it wisely. diff --git a/ci/build.sh b/ci/build.sh new file mode 100755 index 00000000..336e1d77 --- /dev/null +++ b/ci/build.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +# Helper script for building all images for multiple architectures +# NOTE: May not be possible on all types of machines +docker buildx bake --set *.platform=linux/amd64,linux/arm64 diff --git a/docker/docker-compose.yml b/ci/docker-compose.yml similarity index 67% rename from docker/docker-compose.yml rename to ci/docker-compose.yml index a181fef0..ae19c9de 100644 --- a/docker/docker-compose.yml +++ b/ci/docker-compose.yml @@ -3,13 +3,12 @@ services: restart: unless-stopped build: context: ../ - dockerfile: docker/lcp/Dockerfile + dockerfile: ci/lcp/Dockerfile + target: runtime-lcp image: ghcr.io/notalib/readium-lcp-server/lcpserver:${TAG:-latest} #environment: volumes: - - ./config.yaml:/app/config.yaml - ./htpasswd:/app/htpasswd - - ./cert:/app/cert # i18n ? ports: - 8989 @@ -17,14 +16,12 @@ services: restart: unless-stopped build: context: ../ - dockerfile: docker/lcp/Dockerfile + dockerfile: ci/lcp/Dockerfile + target: runtime-lsd image: ghcr.io/notalib/readium-lcp-server/lsdserver:${TAG:-latest} - command: ["/app/lsdserver"] #environment: volumes: - - ./config.yaml:/app/config.yaml - ./htpasswd:/app/htpasswd - - ./cert:/app/cert # i18n ? ports: - 8990 diff --git a/ci/htpasswd b/ci/htpasswd new file mode 100644 index 00000000..764a78cc --- /dev/null +++ b/ci/htpasswd @@ -0,0 +1 @@ +admin:$2y$10$6zTy35TyLjpvcYRudYOoWeI7TxaHyIFMDUb3VFQU3Bjz7Z5q5hXzO diff --git a/ci/lcp/Dockerfile b/ci/lcp/Dockerfile new file mode 100644 index 00000000..fdce08c7 --- /dev/null +++ b/ci/lcp/Dockerfile @@ -0,0 +1,49 @@ +############### +# Build image # +############### +FROM --platform=$BUILDPLATFORM golang:1.22-alpine as builder + +WORKDIR /lcp + +COPY . /lcp/. + +ENV GOPATH=/lcp/build + +RUN apk add build-base + +# Needed for sqlite3 lib +ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE" + +RUN CGO_ENABLED=1 go build -o $GOPATH/bin/ ./lcpserver +RUN go build -o $GOPATH/bin/ ./lsdserver +RUN go build -o $GOPATH/bin/ ./lcpencrypt + +####################### +# Runtime image (LCP) # +####################### +FROM alpine:latest as runtime-lcp +LABEL org.opencontainers.image.source https://github.com/notalib/readium-lcp-server +WORKDIR /app + +RUN mkdir -p /data/db && \ + mkdir -p /data/files + +# Copy over all bins, CMD can be changed at runtime. +COPY --from=builder /lcp/build/bin /app + +# Copy in default localhost config and certs (override with volume-mapping at runtime). +COPY test/cert /app/cert +COPY test/config.localhost.yaml /app/config.yaml + +# Mounted config.yaml decides which ports to use. This is just the default from test config. +EXPOSE 8989 + +CMD ["/app/lcpserver"] + +####################### +# Runtime image (LSD) # +####################### +FROM runtime-lcp as runtime-lsd + +EXPOSE 8990 +CMD ["/app/lsdserver"] diff --git a/docker/build.sh b/docker/build.sh deleted file mode 100755 index af308690..00000000 --- a/docker/build.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash - -set -e -docker buildx build --platform linux/amd64,linux/arm64 . diff --git a/docker/cert/cert-edrlab-test.pem b/docker/cert/cert-edrlab-test.pem deleted file mode 100644 index 3e664a6c..00000000 --- a/docker/cert/cert-edrlab-test.pem +++ /dev/null @@ -1,33 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFpTCCA42gAwIBAgIBATANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJGUjEO -MAwGA1UEBxMFUGFyaXMxDzANBgNVBAoTBkVEUkxhYjESMBAGA1UECxMJTENQIFRl -c3RzMSMwIQYDVQQDExpFRFJMYWIgUmVhZGl1bSBMQ1AgdGVzdCBDQTAeFw0xNjAz -MjUwMzM3MDBaFw0yNjAzMjMwNzM3MDBaMIGQMQswCQYDVQQGEwJGUjEOMAwGA1UE -BxMFUGFyaXMxDzANBgNVBAoTBkVEUkxhYjESMBAGA1UECxMJTENQIFRlc3RzMSIw -IAYDVQQDExlUZXN0IHByb3ZpZGVyIGNlcnRpZmljYXRlMSgwJgYJKoZIhvcNAQkB -FhlsYXVyZW50LmxlbWV1ckBlZHJsYWIub3JnMIICIjANBgkqhkiG9w0BAQEFAAOC -Ag8AMIICCgKCAgEAq/gFXdvKb+EOzsEkHcoSOcPQmNzivzf+9NOJcxWi1/BwuxqA -APv+4LKoLz89U1xx5TE1swL11BsEkIdVYrjl1RiYRa8YV4bb4xyMTm8lm39P16H1 -fG7Ep8yyoVuN6LT3WT2xHGp2jYU8I2nW78cyYApAWAuiMc3epeIOxC2mKgf1pGna -X9j5l/Rx8hhxULqoHIHpR8e1eVRC7tgAz4Oy5qeLxGoL4S+GK/11eRlDO37whAWa -MRbPnJDqqi8Z0Beovf6jmdoUTJdcPZZ9kFdtPsWjPNNHDldPuJBtCd7lupc0K4pC -lJSqtJKyxs05Yeb1j7kbs/i3grdlUcxz0zOaPN1YzrzOO7GLEWUnIe+LwVXAeUse -HedOexITyDQXXCqMoQw/BC6ApGzR0FynC6ojq98tStYGJAGbKBN/9p20CvYf4/hm -PU3fFkImWguPIoeJT//0rz+nSynykeEVtORRIcdyOnX2rL03xxBW7qlTlUXOfQk5 -oLIWXBW9Z2Q63MPWi8jQhSI0jC12iEqCT54xKRHNWKr04at9pJL85M0bDCbBH/jJ -+AIbVx02ewtXcWgWTgK9vgSPN5kRCwIGaV9PMS193KHfNpGqV45EKrfP8U2nvNDe -yqLqAN5847ABSW7UmA5Kj/x5uGxIWu9MUKjZlT0FpepswFvMMo1InLHANMcCAwEA -AaMyMDAwDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBaAwEwYDVR0lBAwwCgYIKwYB -BQUHAwEwDQYJKoZIhvcNAQELBQADggIBAEGAqzHsCbrfQwlWas3q66FG/xbiOYQx -pngA4CZWKQzJJDyOFgWEihW+H6NlSIH8076srpIZByjEGXZfOku4NH4DGNOj6jQ9 -mEfEwbrvCoEVHQf5YXladXpKqZgEB2FKeJVjC7yplelBtjBpSo23zhG/o3/Bj7zR -ySL6gUCewn7z/DkxM6AshDE4HKQxjxp7stpESev+0VTL813WXvwzmucr94H1VPra -sFyVzQHj4Ib+Id1OAmgfzst0vSZyX6bjAuiN9yrs7wze5cAYTaswWr7GAnAZ/r1Z -3PiDp50qaGRhHqJ+lRAhihpFP+ZjsYWRqnxZnDzJkJ6RZAHi2a3VN8x5WhOUMTf3 -JZcFVheDmA4SaEjAZAHU8zUxx1Fstjc8GJcjTwWxCsVM2aREBKXAYDhPTVLRKt6P -yQxB0GxjDZZSvGI9uXn6S5wvjuE4T2TUwbJeGHqJr4FNpXVQ2XNww+sV2QSiAwrl -ORm8HNXqavj4rqz1PkUySXJ6b7zbjZoiACq4C7zb70tRYDyCfLTYtaTL3UK2Sa9e -PSl0Fe6QfcqlGjalrqOo4GI6oqbAIkIXocHHksbLx0mIMSEWQOax+DqXhsl8tNGV -wa5EiUSy83Sc0LyYXoWA35q8dugbkeNnY94rNG/hYKeci1VHhyg4rqxEeVwfBx12 -1JqQSs+hHGKt ------END CERTIFICATE----- diff --git a/docker/cert/privkey-edrlab-test.pem b/docker/cert/privkey-edrlab-test.pem deleted file mode 100644 index 1e56ccb9..00000000 --- a/docker/cert/privkey-edrlab-test.pem +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -sXxINdM+KazdbsK/GIJ6hMvuL6MzOg== ------END PRIVATE KEY----- diff --git a/docker/htpasswd b/docker/htpasswd deleted file mode 100644 index 46a8da4d..00000000 --- a/docker/htpasswd +++ /dev/null @@ -1 +0,0 @@ -nota:$2y$10$hNhxG1rf2FvDGhrfuMb4uejuxPnKk8UF0zx4OVnicEBBXTu5cWYLG diff --git a/docker/lcp/Dockerfile b/docker/lcp/Dockerfile deleted file mode 100644 index acc6fb10..00000000 --- a/docker/lcp/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# Build image -FROM --platform=$BUILDPLATFORM golang:1.22-alpine as lcpserver-builder - -WORKDIR /lcp - -COPY . /lcp/. - -ENV GOPATH=/lcp/build - -RUN apk add build-base - -ENV CGO_CFLAGS="-D_LARGEFILE64_SOURCE" - -RUN CGO_ENABLED=1 go build -o $GOPATH/bin/ ./lcpserver -RUN go build -o $GOPATH/bin/ ./lsdserver -RUN go build -o $GOPATH/bin/ ./lcpencrypt - -# Runtime image -FROM alpine:latest -LABEL org.opencontainers.image.source https://github.com/notalib/readium-lcp-server -WORKDIR /app - -ENV GOPATH=/app - -RUN mkdir -p /data/db && \ - mkdir -p /data/files && \ - mkdir -p /app/cert - -# Copy over all bins, CMD can be changed at runtime. -COPY --from=lcpserver-builder /lcp/build/bin /app - -# Mounted config.yaml decides which ports to use. These are just defaults. -EXPOSE 8989-8990 - -CMD ["/app/lcpserver"] diff --git a/test/config.localhost.yaml b/test/config.localhost.yaml new file mode 100644 index 00000000..77ac9bf5 --- /dev/null +++ b/test/config.localhost.yaml @@ -0,0 +1,86 @@ +# Test configuration for lcpserver and lsdserver. +# It is meant to be used as a quick-start setup. +# +# Replace every occurence of : by the License Server host name or IP address + port. +# Replace every occurence of by the Status Server host name. +# Replace every occurence of by the License Gateway host name. +# Replace every occurence of by the absolute path to the folder hosting every file associated with the LCP service. + +# Shared configuration + +# The usernames and passwords must match the ones in the htpasswd files for each server. +lcp_update_auth: + # login and password used by the Status Server to access the License Server + username: "admin" + password: "Test1234" + +lsd_notify_auth: + # login and password used by the License Server to access the Status Server + username: "admin" + password: "Test1234" + +# LCP Server + +profile: "basic" +lcp: + host: "127.0.0.1" + # the public url a client app will use to access the License Server (optional) + public_base_url: "http://127.0.0.1:8989" + # the port on which the License Server will be running + port: 8989 + # replace this dsn if you're not using SQLite + database: "sqlite3://file:/data/db/lcp.sqlite?cache=shared&mode=rwc" + # authentication file of the License Server. Here we use the same file for the License Server and Status Server + auth_file: "/app/htpasswd" +# uncomment if lcpencrypt does not manage the storage of encrypted publications +storage: + filesystem: + directory: "/data/files/storage" +certificate: + # theses test certificates are provided in the test/cert folder of the codebase + cert: "/app/cert/cert-edrlab-test.pem" + private_key: "/app/cert/privkey-edrlab-test.pem" +license: + links: + # leave the url as-is (after has been resolved) + status: "http://localhost:8990/licenses/{license_id}/status" + # the url of a REAL html page, that indicates how the user can get back his passphrase if forgotten + hint: "https://localhost/lcp-hint" + + +# LSD Server + +lsd: + host: "127.0.0.1" + # the public url a client app will use to access the Status Server + public_base_url: "http://127.0.0.1:8990" + # the port on which the Status Server will be running + port: 8990 + # replace this dsn if you're not using SQLite + database: "sqlite3:///data/db/lsd.sqlite?cache=shared&mode=rwc" + # authentication file of the Status Server. Here we use the same file for the License Server and Status Server + auth_file: "/app/htpasswd" + # in this example, the License Gateway is developed so that adding a license id + # to the host name gives access to a fresh license. + # Keep {license_id} as-is; this is a template. + # Read the doc to know more about how to develop a License Gateway. + license_link_url: "http://localhost:8990/{license_id}" +license_status: + register: true + # uncomment the lines below if you're allowing e-lending + renew: true + return: true + renting_days: 30 + renew_days: 7 + +# Testing Frontend (not used yet) + +frontend: + host: "127.0.0.1" + port: 8991 + database: "sqlite3://file:/data/db/frontend.sqlite?cache=shared&mode=rwc" + master_repository: "/data/files/master" + encrypted_repository: "/data/files/encrypted" + provider_uri: "https://localhost/download/" + right_print: 10 + right_copy: 2000