Added Dockerfiles from seb-server-setup; first CI attempt

This commit is contained in:
Bengt Giger 2020-12-12 23:38:24 +01:00
parent 4ac8f15dca
commit 5e146e5af9
62 changed files with 4938 additions and 0 deletions

View file

@ -0,0 +1,33 @@
name: ci
on:
push:
branches: master
jobs:
main:
runs-on: ubuntu-latest
steps:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
file: ./docker/demo/Dockerfile
push: true
tags: bengig/seb-server:latest
-
name: Image digest
run: echo ${{ steps.docker_build.outputs.digest }}

1
docker/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/test/

46
docker/demo/Dockerfile Normal file
View file

@ -0,0 +1,46 @@
FROM alpine/git
ARG SEBSERVER_VERSION
ARG GIT_TAG="v${SEBSERVER_VERSION}"
WORKDIR /sebserver
RUN if [ "x${GIT_TAG}" = "x" ] ; \
then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \
else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi
FROM maven:latest
ARG SEBSERVER_VERSION
WORKDIR /sebserver
COPY --from=0 /sebserver/seb-server /sebserver
RUN mvn clean install -DskipTests -Dbuild-version="${SEBSERVER_VERSION}"
FROM openjdk:11-jre-stretch
ARG SEBSERVER_VERSION
ENV SEBSERVER_JAR=${SEBSERVER_VERSION}
ENV SERVER_PORT="8080"
ENV JMX_PORT="9090"
ENV SERVER_PWD=
WORKDIR /sebserver
COPY --from=1 /sebserver/target/seb-server-"${SEBSERVER_JAR}".jar /sebserver
ENTRYPOINT exec java \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9090 \
-Dcom.sun.management.jmxremote.rmi.port=9090 \
-Djava.rmi.server.hostname=localhost \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-jar seb-server-"${SEBSERVER_JAR}".jar \
--server.port="${SERVER_PORT}" \
--spring.profiles.active=ws,gui,demo \
--spring.config.location=file:/sebserver/config/,classpath:/config/ \
--sebserver.mariadb.password="${SERVER_PWD}" \
--sebserver.password="${SERVER_PWD}"
EXPOSE $SERVER_PORT $JMX_PORT

View file

@ -0,0 +1,77 @@
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
### Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ROOT=WARN
logging.level.ch=DEBUG
# Log file name and location
logging.file=/sebserver/log/sebserver.log
##########################################################
### SEB Server Webservice configuration
sebserver.test.property=This is a SEB Server Demo Configuration
### webservice initialization
sebserver.init.adminaccount.gen-on-init=false
sebserver.init.organisation.name=
sebserver.init.adminaccount.username=
# database
datastore.mariadb.server.address=seb-server-mariadb
datastore.mariadb.server.port=3306
spring.flyway.enabled=true
spring.flyway.locations=classpath:config/sql/base,classpath:config/sql/demo
spring.flyway.cleanDisabled=false
spring.datasource.hikari.initializationFailTimeout=30000
sebserver.webservice.clean-db-on-startup=true
# webservice configuration
sebserver.webservice.distributed=false
sebserver.webservice.http.external.scheme=http
sebserver.webservice.http.external.servername=ralph.ethz.ch
sebserver.webservice.http.external.port=${server.port}
sebserver.webservice.http.redirect.gui=${sebserver.gui.entrypoint}
sebserver.webservice.api.admin.clientId=guiClient
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=-1
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery
sebserver.webservice.api.exam.endpoint.v1=${sebserver.webservice.api.exam.endpoint}/v1
sebserver.webservice.api.exam.accessTokenValiditySeconds=86400
sebserver.webservice.api.pagination.maxPageSize=500
# comma separated list of known possible OpenEdX API access token request endpoints
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
sebserver.webservice.lms.address.alias=lms.mockup.com=ralph.ethz.ch,edx.devstack.lms=ralph.ethz.ch
##########################################################
### SEB Server GUI service configuration
sebserver.gui.external.messages=file:/sebserver/config/messages
sebserver.gui.multilingual=false
sebserver.gui.supported.languages=en
sebserver.gui.date.displayformat=de
sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.protocol=http
sebserver.gui.webservice.address=${server.address}
sebserver.gui.webservice.port=8080
sebserver.gui.webservice.apipath=/admin-api/v1
sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=20
sebserver.gui.date.displayformat=MM / dd / yyyy
sebserver.gui.date.displayformat.time=HH:mm
sebserver.gui.date.displayformat.timezone=|ZZ
sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb
sebserver.gui.seb.exam.config.download.filename=SebExamSettings.seb
#sebserver.gui.defaultLogo=classpath:/static/images/ethz_logo_white.png

View file

@ -0,0 +1,10 @@
[mysqld]
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# network
connect_timeout = 61
wait_timeout = 28800
max_connections = 100000
max_allowed_packet = 64M
max_connect_errors = 1000

View file

@ -0,0 +1,144 @@
################################
# Overall
################################
sebserver.overall.version=SEB Server Version : {0}
sebserver.overall.imprint=
sebserver.overall.imprint.markup=
sebserver.overall.about=
sebserver.overall.about.markup=
sebserver.overall.help=Dokumentation
sebserver.overall.help.link=https://www.safeexambrowser.org/news_de.html
sebserver.overall.message.leave.without.save=You are leaving this page without saved changes!\nThe unsaved changes will be lost.\Are you sure to leave the page?
sebserver.overall.upload=Bitte Ausw\u00E4hlen
sebserver.overall.action.modify.cancel=Abbrechen
sebserver.overall.action.modify.cancel.confirm=Nicht gespeicherte Daten gehen verloren. Wirklich abbrechen?
sebserver.overall.action.filter=Filtern
sebserver.overall.action.filter.clear=Filter Zur\u00FCcksetzen
################################
# Form validation and messages
################################
sebserver.form.validation.error.title=Validierung
sebserver.form.validation.error.message=Einige Daten fehlen oder sind nicht korrekt.
sebserver.form.validation.fieldError.size=Der Text muss mindestens {3} und kann h\u00F6chstens {4} Zeichen beinhalten
sebserver.form.validation.fieldError.name=Name is mandatory and must have a size between {3} and {4} character
sebserver.form.validation.fieldError.urlSuffix=URL Suffix must have a size between {3} and {4} character
sebserver.form.validation.fieldError.notNull=Dies ist ein Pflichtfeld
sebserver.form.validation.fieldError.username.notunique=Dieser Username ist schon in Gebrauch. Bitte w\u00E4hlen Sie einen anderen.
sebserver.form.validation.fieldError.password.wrong=Das (aktuelle) Passwort stimmt nicht
sebserver.form.validation.fieldError.password.mismatch=Passwort, neues Passwort und Best\u00E4tigung stimmen nicht \u00FCberein
sebserver.error.unexpected=Unerwarteter Fehler
sebserver.page.message=Information
sebserver.dialog.confirm.title=Best\u00E4tigung
sebserver.dialog.confirm.deactivation=Es gibt {0} weitere Objekte die zu diesem Objeckt geh\u00F6ren.<br/>Diese werden bei einer Deaktivierung ebenfalls deaktiviert.<br/><br/>Sollen alle deaktiviert weden?
sebserver.dialog.confirm.deactivation.noDependencies=Soll dieses Object wirklich deaktiviert werden?
################################
# Login Page
################################
sebserver.login.username=Benutzer Name
sebserver.login.pwd=Passwort
sebserver.login.login=Anmelden
sebserver.login.failed.title=Anmelden Fehlgeschlagen
sebserver.login.failed.message=Zugang verweigert: Falscher Benutzer Name oder Passwort
sebserver.logout=Abmelden
sebserver.logout.success.message=Sie wurden erfolgreich abgemeldet
sebserver.login.password.change=Information
sebserver.login.password.change.success=Das Passwort wurde erfoglreich ge\u00E4ndert. Bitte melden Sie sich mit dem neuen Passwort an.
################################
# Main Page
################################
sebserver.logout=Abmelden
sebserver.mainpage.maximize.tooltip=Maximieren
sebserver.mainpage.minimize.tooltip=Minimieren
sebserver.activitiespane.title=Aktivit\u00E4ten
sebserver.actionpane.title=Aktionen
################################
# Institution
################################
sebserver.institution.list.title=Institutionen
sebserver.institution.list.column.name=Name
sebserver.institution.list.column.urlSuffix=URL Suffix
sebserver.institution.list.column.active=Aktiv
sebserver.institution.action.list=Institution
sebserver.institution.action.form=Institution
sebserver.institution.action.new=Neue Institution
sebserver.institution.action.list.view=Ausgew\u00E4hlte Ansehen
sebserver.institution.action.modify=Institution Editieren
sebserver.institution.action.list.modify=Ausgew\u00E4hlte Editieren
sebserver.institution.action.save=Institution Speichern
sebserver.institution.action.activate=Aktiv
sebserver.institution.action.deactivate=Aktiv
sebserver.institution.action.delete=Institution L\u00F6schen
sebserver.institution.info.pleaseSelect=Bitte zuerst eine Instiiution aus der List ausw\u00E4hlen.
sebserver.institution.form.title.new=Neue Institution
sebserver.institution.form.title=Institution : {0}
sebserver.institution.form.name=Name
sebserver.institution.form.urlSuffix=URL Suffix
sebserver.institution.form.logoImage=Logo Bild
################################
# User Account
################################
sebserver.useraccount.role.SEB_SERVER_ADMIN=SEB Server Administrator
sebserver.useraccount.role.INSTITUTIONAL_ADMIN=Institution Administrator
sebserver.useraccount.role.EXAM_ADMIN=Examen Administrator
sebserver.useraccount.role.EXAM_SUPPORTER=Examen Supporter
sebserver.useraccount.list.title=Benutzer Konto
sebserver.useraccount.list.column.name=Name
sebserver.useraccount.list.column.username=Benutzer Name
sebserver.useraccount.list.column.email=E-Mail
sebserver.useraccount.list.column.language=Sprache
sebserver.useraccount.list.column.active=Aktiv
sebserver.useraccount.action.list=Benutzer Konto
sebserver.useraccount.action.form=Benutzer Konto
sebserver.useraccount.action.new=Neues Benutzer Konto
sebserver.useraccount.action.view=Ausgew\u00E4hlter Ansehen
sebserver.useraccount.action.list.modify=Ausgew\u00E4hlter Editieren
sebserver.useraccount.action.modify=Editieren
sebserver.useraccount.action.save=Benutzer Konto Speichern
sebserver.useraccount.action.activate=Aktiv
sebserver.useraccount.action.deactivate=Aktiv
sebserver.useraccount.action.delete=Benutzer Konto L\u00F6schen
sebserver.useraccount.action.change.password=Passwort Ändern
sebserver.useraccount.action.change.password.save=Passwort Speichern
sebserver.useraccount.info.pleaseSelect=Bitte zuerst ein Benutzer Konto aus der List ausw\u00E4hlen.
sebserver.useraccount.form.title=Benutzer Konto : {0}
sebserver.useraccount.form.title.new=Neues Benutzer Konto
sebserver.useraccount.form.institution=Institution
sebserver.useraccount.form.name=Name
sebserver.useraccount.form.username=Benutzer Name
sebserver.useraccount.form.mail=E-Mail
sebserver.useraccount.form.language=Sprache
sebserver.useraccount.form.timezone=Zeit Zone
sebserver.useraccount.form.roles=Benutzer Rollen
sebserver.useraccount.form.password=Passwort
sebserver.useraccount.form.password.confirm=Passwort Best\u00E4tigen
sebserver.useraccount.form.pwchange.title=Passwort \u00C4ndern : {0}
sebserver.useraccount.form.password.old=Altes Passwort
sebserver.useraccount.form.password.new=Neues Passwort
sebserver.useraccount.form.password.new.confirm=Neues Password Best\u00E4tigen

View file

@ -0,0 +1,6 @@
sebserver.overall.about=About
sebserver.overall.about.markup=<span style='font-family: Arial, Helvetica,sans-serif;font-size: 25px;font-weight: normal;font-style: normal;color: rgb(31, 64, 122);'>SEB Server About</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 18px;font-weight: bold;font-style: normal;'>1. Installation.</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 14px;font-weight: normal;font-style: normal;'>This is a SEB Server demo setup, ideal for testing or demonstrations.</span>
sebserver.overall.help=Documentation
sebserver.overall.help.link=https://seb-server.readthedocs.io/en/latest/index.html
sebserver.monitoring.exam.connection.action.disable=Mark as Canceled

View file

@ -0,0 +1,44 @@
version: '3'
services:
mariadb:
image: "mariadb/server:10.3"
container_name: seb-server-mariadb
environment:
MYSQL_ROOT_PASSWORD: somePW
volumes:
- seb-server-mariadb-data:/var/lib/mysql
- ./config/mariadb:/etc/mysql/conf.d
ports:
- 3306:3306
networks:
- ralph
restart: unless-stopped
seb-server:
build:
context: .
args:
- SEBSERVER_VERSION=1.0-latest
container_name: seb-server
environment:
- SERVER_PORT=8080
- SERVER_PWD=somePW
volumes:
- ./config:/sebserver/config
- seb-server-logs:/sebserver/log
ports:
- 8080:8080
- 9090:9090
networks:
- ralph
depends_on:
- "mariadb"
restart: unless-stopped
networks:
ralph:
volumes:
seb-server-mariadb-data:
seb-server-logs:

View file

@ -0,0 +1,2 @@
admin readwrite
user readonly

View file

@ -0,0 +1,15 @@
[mysqld]
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# network
connect_timeout = 61
wait_timeout = 28800
max_connections = 100000
max_allowed_packet = 256M
max_connect_errors = 1000000
skip_external_locking
#memory
innodb_buffer_pool_size=2G

View file

@ -0,0 +1,14 @@
server {
listen 80;
charset utf-8;
access_log off;
location / {
proxy_pass http://seb-server:8080;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View file

@ -0,0 +1,83 @@
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
# Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ROOT=WARN
logging.level.ch=INFO
logging.file=/sebserver/log/sebserver.log
logging.config=/sebserver/config/spring/logback-prod.xml
##########################################################
### SEB Server Webservice configuration
sebserver.test.property=This is a basic bundled productive setup
# webservice database server connection
datastore.mariadb.server.address=seb-server-mariadb
datastore.mariadb.server.port=3306
# data source configuration
spring.datasource.hikari.initializationFailTimeout=30000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
### webservice networking
sebserver.webservice.distributed=false
sebserver.webservice.http.external.scheme=https
sebserver.webservice.http.external.servername=
sebserver.webservice.http.external.port=
sebserver.webservice.http.redirect.gui=/gui
sebserver.http.client.connect-timeout=150000
sebserver.http.client.connection-request-timeout=100000
sebserver.http.client.read-timeout=200000
# webservice API
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=25200
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery
sebserver.webservice.api.exam.endpoint.v1=${sebserver.webservice.api.exam.endpoint}/v1
sebserver.webservice.api.exam.accessTokenValiditySeconds=3600
sebserver.webservice.api.exam.event-handling-strategy=ASYNC_BATCH_STORE_STRATEGY
sebserver.webservice.api.exam.enable-indicator-cache=true
sebserver.webservice.api.pagination.maxPageSize=500
# comma separated list of known possible OpenEdX API access token request endpoints
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
management.server.port=${server.port}
management.endpoints.web.base-path=/management
management.endpoints.web.exposure.include=logfile,loggers
##########################################################
### SEB Server GUI configuration
sebserver.gui.external.messages=file:/sebserver/config/spring/messages
sebserver.gui.multilingual=false
sebserver.gui.supported.languages=en
sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=20
sebserver.gui.date.displayformat=de
sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.protocol=http
sebserver.gui.webservice.address=localhost
sebserver.gui.webservice.port=8080
# defines the polling interval that is used to poll the webservice for client connection data on a monitored exam page
sebserver.gui.webservice.poll-interval=1000
sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.webservice.edx-lms-enabled=true
sebserver.gui.webservice.moodle-lms-enabled=false
sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb
sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>log/sebserver.log</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<springProfile name="prod">
<root level="WARN" additivity="true">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</springProfile>
</configuration>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,84 @@
version: '3.5'
services:
seb-server-setup:
build:
context: .
dockerfile: setup.Dockerfile
container_name: seb-server-setup
volumes:
- seb-server-config:/config
- ./config:/host/config
mariadb:
image: "mariadb/server:10.3"
container_name: seb-server-mariadb
environment:
- MYSQL_ROOT_PASSWORD_FILE=/etc/mysql/conf.d/secret
ports:
- 3306:3306
volumes:
- seb-server-config:/etc/mysql/conf.d
- seb-server-mariadb:/var/lib/mysql
- ./config/mariadb/config.cnf:/etc/mysql/conf.d/config.cnf
networks:
- seb-server-network
depends_on:
- "seb-server-setup"
restart: unless-stopped
seb-server:
build:
context: .
dockerfile: sebserver.Dockerfile
args:
- SEBSERVER_VERSION=1.0-latest
container_name: seb-server
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
- seb-server-logs:/sebserver/log
environment:
- MONITORING_MODE=false
# - JMX_PORT=9090
# Connect this port to host if you want to use JMX (MONITORING_MODE=true)
#ports:
# - 9090:9090
logging:
driver: "json-file"
options:
mode: "non-blocking"
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server-setup"
restart: unless-stopped
reverse-proxy:
image: "nginx:latest"
container_name: seb-server-proxy
volumes:
- ./config/nginx:/etc/nginx/conf.d
ports:
- 80:80
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server"
- "seb-server-setup"
restart: unless-stopped
networks:
seb-server-network:
name: seb-server-network
volumes:
seb-server-config:
name: seb-server-config
seb-server-mariadb:
name: seb-server-mariadb
seb-server-logs:
name: seb-server-logs

View file

@ -0,0 +1,59 @@
FROM alpine/git
ARG SEBSERVER_VERSION
ARG GIT_TAG="v${SEBSERVER_VERSION}"
WORKDIR /sebserver
RUN if [ "x${GIT_TAG}" = "x" ] ; \
then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \
else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi
FROM maven:latest
ARG SEBSERVER_VERSION
WORKDIR /sebserver
COPY --from=0 /sebserver/seb-server /sebserver
RUN mvn clean install -DskipTests -Dbuild-version="${SEBSERVER_VERSION}"
FROM openjdk:11-jre-stretch
ARG SEBSERVER_VERSION
ENV SEBSERVER_JAR="seb-server-${SEBSERVER_VERSION}.jar"
ENV SERVER_PORT="8080"
ENV JMX_PORT=
WORKDIR /sebserver
COPY --from=1 /sebserver/target/"${SEBSERVER_JAR}" /sebserver
CMD if [ "x${JMX_PORT}" = "x" ] ; \
then secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=ws,gui,prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
else secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=${JMX_PORT} \
-Dcom.sun.management.jmxremote.rmi.port=${JMX_PORT} \
-Djava.rmi.server.hostname=localhost \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=/sebserver/config/jmx/jmxremote.password \
-Dcom.sun.management.jmxremote.access.file=/sebserver/config/jmx/jmxremote.access \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=ws,gui,prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
fi
EXPOSE $SERVER_PORT $JMX_PORT

View file

@ -0,0 +1,6 @@
FROM alpine:latest
CMD cp -a /host/config/. /config/ \
&& secret=$(cat /config/secret) \
&& rm /host/config/secret \
&& sudo chmod 777 /host/config/secret

View file

@ -0,0 +1,2 @@
admin readwrite
user readonly

View file

@ -0,0 +1,16 @@
[mysqld]
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# network
connect_timeout = 61
wait_timeout = 28800
max_connections = 100000
max_allowed_packet = 256M
max_connect_errors = 1000000
skip_external_locking
skip_name_resolve
#memory
innodb_buffer_pool_size=2G

View file

@ -0,0 +1,30 @@
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443 ssl;
charset utf-8;
access_log off;
keepalive_timeout 70;
server_name localhost;
ssl_certificate /sebserver/config/certs/localhost.crt;
ssl_certificate_key /sebserver/config/certs/localhost.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://seb-server:8080;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}

View file

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDXDCCAkSgAwIBAgIJAJYb2nNBXHKCMA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV
BAYTAkNIMQ8wDQYDVQQIDAZadXJpY2gxDzANBgNVBAcMBlp1cmljaDESMBAGA1UE
AwwJbG9jYWxob3N0MB4XDTIwMDQzMDEzMDI0OVoXDTIxMDQzMDEzMDI0OVowQzEL
MAkGA1UEBhMCQ0gxDzANBgNVBAgMBlp1cmljaDEPMA0GA1UEBwwGWnVyaWNoMRIw
EAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDLwuUqViIl8RtzQoYiZ6vHM49UlhgrD51sziO1PuDIfZo7R3M3NFuCmwsOlXoH
vHagcFFpplG3br/akbMCiIbZaWCJiNluZy+b1eFNHmPo8KvCFhRZfAUtKbzku2zL
53O7/oMBUbhJILXC5is832K0qswh/QEmndySTO8sb4IZ3EZV4krQ7UlDgbvRruvL
PrqEn25jiuhe5SnrkmI4rlaClvgOJ18qq+L4op90fd0W2V11WV9AJLk7boqVtCwT
ee++SpVxS1W5EsCiZwKVrmrxUXPpC+Q67MNO+GJzW1xivcnz6fpOjoCRisudRtEb
/GRO2jLVr3KvmyftJMk02d5xAgMBAAGjUzBRMB0GA1UdDgQWBBQQmfmkV++5QA0r
uP7xbegL02qLkTAfBgNVHSMEGDAWgBQQmfmkV++5QA0ruP7xbegL02qLkTAPBgNV
HRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC5nt2yexZjt0yaociBiveF
Y1ePyT3QVdDEzaAzMHNJxPA0DcsaJdViv/K8Ri9a7aZgjI7tGR93rTUSs8EgxoYQ
ZUn6Av4xwTHIAoGbIS24pd6wljkehB6G4xGK4D8R51AHqHPwlV9pe/9FhqnIwagr
RMXJurEiKf1EiX/4ryrs5hFzSauUGEhnq7HTGRygK1boN0LNqLx5G4vLtYzOCDuN
GnshMJJvXkQe6Fre1rFnVoBtcbhoEqkp3LLr3eHSiAf7gy4iXjzhGCw/LX0pbEqr
B0Zt+ouuTfga0Pvj3MNEWyI+3CWqXldB/RvonZxWXUhh6ONU2qzRYenewI8gDfIZ
-----END CERTIFICATE-----

View file

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDLwuUqViIl8Rtz
QoYiZ6vHM49UlhgrD51sziO1PuDIfZo7R3M3NFuCmwsOlXoHvHagcFFpplG3br/a
kbMCiIbZaWCJiNluZy+b1eFNHmPo8KvCFhRZfAUtKbzku2zL53O7/oMBUbhJILXC
5is832K0qswh/QEmndySTO8sb4IZ3EZV4krQ7UlDgbvRruvLPrqEn25jiuhe5Snr
kmI4rlaClvgOJ18qq+L4op90fd0W2V11WV9AJLk7boqVtCwTee++SpVxS1W5EsCi
ZwKVrmrxUXPpC+Q67MNO+GJzW1xivcnz6fpOjoCRisudRtEb/GRO2jLVr3Kvmyft
JMk02d5xAgMBAAECggEALXh7rXv1OORaTNlel5TtB5Ig/S5VjF56sgo6e7rhbLxi
y7HBK2OavEWfLQz8Y3eSPXFzKZF9EOM9GyiCeyE+fov+iBKq+vE59ZvAIHaUsynq
GnDU77c2bIKw7ZZJzCMFd8FvOL8k0eTjyu+UXIw5OboXvcn5FMYLr/ZNNWxY6y4P
33fR63HUAQOglxkvzqfCYcWqiBr3fowQcKfeVjSveeTMEHMDq/EWcq1+xmGRs037
cWfLw8A2Vo6lN4CSJvXMJXzNgd3uKG4EI+nTzrO7WaH6KpxIkGkD/u50J868tR+C
TmQnQIvMkjGSiulGHHZhQ3v8zEXzSU3ramxnBM9O8QKBgQDszx7Z5Cioc1RK4dKt
qLhvbQYXQC3XF0WWOjuG6NTxA/cKejQ9fpLzu0UnRYsUfsyiahtB+umGsWxO1yAp
aVf25CYp2lTTvP3EDo9wzOfp9NBqiKSkTTmYvp7i9idGU4Tg8gYUQcG9F63L1M3X
6Xb8ZWylJoypegz2CeDWIh+RXQKBgQDcRikZYaGKsMgCxRVyxeHOFbml4Fk0wH+C
YsrOHMV29Ck/8t/Ajy8+42TmnrmCFsTK4OVG9L87CF9TNxBU8WBAG2YqmiQbH49i
UEaxBSfcmOqgPFGy62EQadUTn4f+HbZJKPyaeMhnKJseIIWy2i+a0Q6+0GX+Gke6
Qe6FWkeMJQKBgQDJ8ZcNmVRS0ob/lLRlA4zE+ORIz6JH2sCs69v3oHZ3UjpJ5QzH
pDkNQJYod1WzlK5Nks7L5X1gL819Lldu+TbahJVG+7l7F6AQoZoRR6w+B1f0gbJl
qrWDXIuCYQf9IRwf+ETW4XymFJtRR5iCl8WwV43fCJDLthl3d9UUxuTEwQKBgQDb
dRNRdFHLqeE70TtTRA96kW6K8wAtbHQdZWwE+elKYGwQiFugr4c0sr0+f3j3QNQE
BRipHwK/P9IpSDz/RBTPCf06CKRcWY8zNiOYDjjusXNg/XewOI5WGfruOAz3goaw
USOKizeuf2g8Fc7eqD6xkgOM3HghN/GqgjGvroiF+QKBgQDQZRljdl/dTi5GijFb
FJwDGEhTpDYEBKb9AwWa5xP0u7JoqCv+0eP8/9eLmjzgawKTjtPHVMaeBmzMeW4O
E+x4114yQthVTs1e8TnoprkapEQNlvDGxJsYycJ4ADrrgOzA+HeddUj9GrWEfd8f
t7TrY/khzS4yDWvTFYG5wag+5Q==
-----END PRIVATE KEY-----

View file

@ -0,0 +1,79 @@
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
# Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ROOT=WARN
logging.level.ch=INFO
logging.file=/sebserver/log/sebserver.log
logging.config=/sebserver/config/spring/logback-prod.xml
##########################################################
### SEB Server Webservice configuration
sebserver.test.property=This is a basic bundled productive setup
# webservice database server connection
datastore.mariadb.server.address=seb-server-mariadb
datastore.mariadb.server.port=3306
# data source configuration
spring.datasource.hikari.initializationFailTimeout=30000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
### webservice networking
sebserver.webservice.distributed=false
sebserver.webservice.http.external.scheme=https
sebserver.webservice.http.external.servername=
sebserver.webservice.http.external.port=
sebserver.webservice.http.redirect.gui=/gui
sebserver.http.client.connect-timeout=150000
sebserver.http.client.connection-request-timeout=100000
sebserver.http.client.read-timeout=200000
# webservice API
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=25200
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery
sebserver.webservice.api.exam.endpoint.v1=${sebserver.webservice.api.exam.endpoint}/v1
sebserver.webservice.api.exam.accessTokenValiditySeconds=3600
sebserver.webservice.api.exam.event-handling-strategy=ASYNC_BATCH_STORE_STRATEGY
sebserver.webservice.api.exam.enable-indicator-cache=true
sebserver.webservice.api.pagination.maxPageSize=500
# comma separated list of known possible OpenEdX API access token request endpoints
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
##########################################################
### SEB Server GUI configuration
sebserver.gui.external.messages=file:/sebserver/config/spring/messages
sebserver.gui.multilingual=false
sebserver.gui.supported.languages=en
sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=20
sebserver.gui.date.displayformat=de
sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.protocol=http
sebserver.gui.webservice.address=localhost
sebserver.gui.webservice.port=8080
# defines the polling interval that is used to poll the webservice for client connection data on a monitored exam page
sebserver.gui.webservice.poll-interval=1000
sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.webservice.edx-lms-enabled=true
sebserver.gui.webservice.moodle-lms-enabled=false
sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb
sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>log/sebserver.log</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<springProfile name="prod">
<root level="WARN" additivity="true">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</springProfile>
</configuration>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,83 @@
version: '3.5'
services:
seb-server-setup:
build:
context: .
dockerfile: setup.Dockerfile
container_name: seb-server-setup
volumes:
- seb-server-config:/config
- ./config:/host/config
mariadb:
image: "mariadb/server:10.3"
container_name: seb-server-mariadb
environment:
- MYSQL_ROOT_PASSWORD_FILE=/etc/mysql/conf.d/secret
ports:
- 3306:3306
volumes:
- seb-server-config:/etc/mysql/conf.d
- seb-server-mariadb:/var/lib/mysql
- ./config/mariadb/config.cnf:/etc/mysql/conf.d/config.cnf
networks:
- seb-server-network
restart: unless-stopped
seb-server:
build:
context: .
dockerfile: sebserver.Dockerfile
args:
- SEBSERVER_VERSION=1.0.0
container_name: seb-server
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
- seb-server-logs:/sebserver/log
environment:
- MONITORING_MODE=false
# - JMX_PORT=9090
# Connect this port to host if you want to use JMX (MONITORING_MODE=true)
#ports:
# - 9090:9090
logging:
driver: "json-file"
options:
mode: "non-blocking"
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server-setup"
restart: unless-stopped
reverse-proxy:
image: "nginx:latest"
container_name: seb-server-proxy
volumes:
- ./config/nginx:/etc/nginx/conf.d
- ./config/nginx/certs:/sebserver/config/certs
ports:
- 443:443
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server"
- "seb-server-setup"
restart: unless-stopped
networks:
seb-server-network:
name: seb-server-network
volumes:
seb-server-config:
name: seb-server-config
seb-server-mariadb:
name: seb-server-mariadb
seb-server-logs:
name: seb-server-logs

View file

@ -0,0 +1,59 @@
FROM alpine/git
ARG SEBSERVER_VERSION
ARG GIT_TAG="v${SEBSERVER_VERSION}"
WORKDIR /sebserver
RUN if [ "x${GIT_TAG}" = "x" ] ; \
then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \
else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi
FROM maven:latest
ARG SEBSERVER_VERSION
WORKDIR /sebserver
COPY --from=0 /sebserver/seb-server /sebserver
RUN mvn clean install -DskipTests -Dbuild-version="${SEBSERVER_VERSION}"
FROM openjdk:11-jre-stretch
ARG SEBSERVER_VERSION
ENV SEBSERVER_JAR="seb-server-${SEBSERVER_VERSION}.jar"
ENV SERVER_PORT="8080"
ENV JMX_PORT=
WORKDIR /sebserver
COPY --from=1 /sebserver/target/"${SEBSERVER_JAR}" /sebserver
CMD if [ "x${JMX_PORT}" = "x" ] ; \
then secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=ws,gui,prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
else secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=${JMX_PORT} \
-Dcom.sun.management.jmxremote.rmi.port=${JMX_PORT} \
-Djava.rmi.server.hostname=localhost \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=/sebserver/config/jmx/jmxremote.password \
-Dcom.sun.management.jmxremote.access.file=/sebserver/config/jmx/jmxremote.access \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=ws,gui,prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
fi
EXPOSE $SERVER_PORT $JMX_PORT

View file

@ -0,0 +1,6 @@
FROM alpine:latest
CMD cp -a /host/config/. /config/ \
&& secret=$(cat /config/secret) \
&& rm /host/config/secret \
&& sudo chmod 777 /host/config/secret

View file

@ -0,0 +1,2 @@
admin readwrite
user readonly

View file

@ -0,0 +1,15 @@
[mysqld]
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# network
connect_timeout = 61
wait_timeout = 28800
max_connections = 100000
max_allowed_packet = 256M
max_connect_errors = 1000000
skip_external_locking
#memory
innodb_buffer_pool_size=1G

View file

@ -0,0 +1,14 @@
server {
listen 80;
charset utf-8;
access_log off;
location / {
proxy_pass http://seb-server:8080;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View file

@ -0,0 +1,72 @@
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
# Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ch=DEBUG
logging.file=/sebserver/log/sebserver.log
##########################################################
### SEB Server Webservice configuration
sebserver.test.property=This is a staging/testing setup with no encryption
# webservice database server connection
datastore.mariadb.server.address=seb-server-mariadb
datastore.mariadb.server.port=3306
# data source configuration
spring.datasource.hikari.initializationFailTimeout=30000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
### webservice networking
sebserver.webservice.distributed=false
sebserver.webservice.http.external.scheme=http
sebserver.webservice.http.external.servername=
sebserver.webservice.http.external.port=
sebserver.webservice.http.redirect.gui=/gui
# webservice API
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=25200
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery
sebserver.webservice.api.exam.endpoint.v1=${sebserver.webservice.api.exam.endpoint}/v1
sebserver.webservice.api.exam.accessTokenValiditySeconds=3600
sebserver.webservice.api.exam.event-handling-strategy=ASYNC_BATCH_STORE_STRATEGY
sebserver.webservice.api.exam.enable-indicator-cache=true
sebserver.webservice.api.pagination.maxPageSize=500
# comma separated list of known possible OpenEdX API access token request endpoints
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
##########################################################
### SEB Server GUI configuration
sebserver.gui.external.messages=file:/sebserver/config/spring/messages
sebserver.gui.multilingual=false
sebserver.gui.supported.languages=en
sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=20
sebserver.gui.date.displayformat=de
sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.protocol=http
sebserver.gui.webservice.address=localhost
sebserver.gui.webservice.port=8080
# defines the polling interval that is used to poll the webservice for client connection data on a monitored exam page
sebserver.gui.webservice.poll-interval=1000
sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb
sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb

View file

@ -0,0 +1,8 @@
sebserver.overall.imprint=
sebserver.overall.imprint.markup=
sebserver.overall.about=About
sebserver.overall.about.markup=<span style='font-family: Arial, Helvetica,sans-serif;font-size: 25px;font-weight: normal;font-style: normal;color: rgb(31, 64, 122);'>SEB Server About Example</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 18px;font-weight: bold;font-style: normal;'>1. This is an example of how an About-Page can look like.</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 14px;font-weight: normal;font-style: normal;'>By simply define the markup HTML content within the messages.propertie configuration of specified language</span>
sebserver.overall.help=Documentation
sebserver.overall.help.link=https://seb-server.readthedocs.io/en/latest/index.html
sebserver.monitoring.exam.connection.action.disable=Mark as Canceled

View file

@ -0,0 +1,76 @@
version: '3'
services:
seb-server-setup:
build:
context: .
dockerfile: setup.Dockerfile
container_name: seb-server-setup
volumes:
- seb-server-config:/config
- ./config:/host/config
mariadb:
image: "mariadb/server:10.3"
container_name: seb-server-mariadb
environment:
- MYSQL_ROOT_PASSWORD_FILE=/etc/mysql/conf.d/secret
# workaround: https://github.com/docker-library/mariadb/issues/262
# TODO this seems to be fixed now... try to remove and test
- MYSQL_INITDB_SKIP_TZINFO=1
ports:
- 3306:3306
volumes:
- seb-server-config:/etc/mysql/conf.d
- seb-server-mariadb:/var/lib/mysql
- ./config/mariadb/config.cnf:/etc/mysql/conf.d/config.cnf
networks:
- seb-server-network
restart: unless-stopped
seb-server:
build:
context: .
dockerfile: sebserver.Dockerfile
args:
- SEBSERVER_VERSION=1.0-latest
container_name: seb-server
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
environment:
- JMX_PORT=9090
ports:
- 9090:9090
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server-setup"
restart: unless-stopped
reverse-proxy:
image: "nginx:latest"
container_name: seb-server-proxy
volumes:
- ./config/nginx:/etc/nginx/conf.d
ports:
- 80:80
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server"
- "seb-server-setup"
restart: unless-stopped
networks:
seb-server-network:
volumes:
seb-server-config:
seb-server-mariadb:

View file

@ -0,0 +1,59 @@
FROM alpine/git
ARG SEBSERVER_VERSION
ARG GIT_TAG="v${SEBSERVER_VERSION}"
WORKDIR /sebserver
RUN if [ "x${GIT_TAG}" = "x" ] ; \
then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \
else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi
FROM maven:latest
ARG SEBSERVER_VERSION
WORKDIR /sebserver
COPY --from=0 /sebserver/seb-server /sebserver
RUN mvn clean install -DskipTests -Dbuild-version="${SEBSERVER_VERSION}"
FROM openjdk:11-jre-stretch
ARG SEBSERVER_VERSION
ENV SEBSERVER_JAR="seb-server-${SEBSERVER_VERSION}.jar"
ENV SERVER_PORT="8080"
ENV JMX_PORT=
WORKDIR /sebserver
COPY --from=1 /sebserver/target/"${SEBSERVER_JAR}" /sebserver
CMD if [ "x${JMX_PORT}" = "x" ] ; \
then secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=ws,gui,prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
else secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=${JMX_PORT} \
-Dcom.sun.management.jmxremote.rmi.port=${JMX_PORT} \
-Djava.rmi.server.hostname=localhost \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=/sebserver/config/jmx/jmxremote.password \
-Dcom.sun.management.jmxremote.access.file=/sebserver/config/jmx/jmxremote.access \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=ws,gui,prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
fi
EXPOSE $SERVER_PORT $JMX_PORT

View file

@ -0,0 +1,6 @@
FROM alpine:latest
CMD cp -a /host/config/. /config/ \
&& secret=$(cat /config/secret) \
&& rm /host/config/secret \
&& sudo chmod 777 /host/config/secret

View file

@ -0,0 +1,26 @@
version: '3.5'
services:
mariadb:
image: "mariadb/server:10.3"
container_name: seb-server-mariadb
environment:
- MYSQL_ROOT_PASSWORD=somePW
# workaround: https://github.com/docker-library/mariadb/issues/262
# TODO this seems to be fixed now... try to remove and test
- MYSQL_INITDB_SKIP_TZINFO=1
volumes:
- mariadb-data:/var/lib/mysql
- ./mariadb:/etc/mysql/conf.d
ports:
- 3306:3306
networks:
- seb-server-network
restart: unless-stopped
volumes:
mariadb-data:
name: seb-server-data
networks:
seb-server-network:
name: seb-server-network

View file

@ -0,0 +1,10 @@
[mysqld]
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# network
connect_timeout = 61
wait_timeout = 28800
max_connections = 100000
max_allowed_packet = 64M
max_connect_errors = 1000

View file

@ -0,0 +1,44 @@
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
# Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ROOT=WARN
logging.level.ch=DEBUG
logging.file=/sebserver/log/sebserver.log
logging.config=/sebserver/config/spring/logback-prod.xml
##########################################################
### SEB Server GUI configuration
sebserver.gui.http.external.scheme=TO-SET
sebserver.gui.http.external.servername=TO-SET
sebserver.gui.http.external.port=TO-SET
sebserver.gui.external.messages=file:/sebserver/config/spring/messages
sebserver.gui.multilingual=false
sebserver.gui.supported.languages=en
sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=20
sebserver.gui.date.displayformat=de
sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.protocol=http
sebserver.gui.webservice.address=seb-server-proxy
sebserver.gui.webservice.port=80
# defines the polling interval that is used to poll the webservice for client connection data on a monitored exam page
sebserver.gui.webservice.poll-interval=1000
sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb
sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>log/sebserver.log</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<springProfile name="prod">
<root level="DEBUG" additivity="true">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</springProfile>
</configuration>

View file

@ -0,0 +1,8 @@
sebserver.overall.imprint=
sebserver.overall.imprint.markup=
sebserver.overall.about=About
sebserver.overall.about.markup=<span style='font-family: Arial, Helvetica,sans-serif;font-size: 25px;font-weight: normal;font-style: normal;color: rgb(31, 64, 122);'>SEB Server About Example</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 18px;font-weight: bold;font-style: normal;'>1. This is an example of how an About-Page can look like.</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 14px;font-weight: normal;font-style: normal;'>By simply define the markup HTML content within the messages.propertie configuration of specified language</span>
sebserver.overall.help=Documentation
sebserver.overall.help.link=https://seb-server.readthedocs.io/en/latest/index.html
sebserver.monitoring.exam.connection.action.disable=Mark as Canceled

View file

@ -0,0 +1,36 @@
version: '3.5'
services:
seb-guiservice:
build:
context: .
dockerfile: sebguiservice.Dockerfile
args:
- GIT_TAG=development
- SEBSERVER_VERSION=1.0.1
container_name: seb-guiservice
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
- seb-server-logs:/sebserver/log
environment:
- SECRET=somePW
ports:
- 80:8080
logging:
driver: "json-file"
options:
mode: "non-blocking"
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
restart: unless-stopped
volumes:
seb-server-config:
seb-server-logs:
name: seb-guiservice-logs
networks:
seb-server-network:
name: seb-server-network

View file

@ -0,0 +1,37 @@
FROM alpine/git
ARG SEBSERVER_VERSION
ARG GIT_TAG="v${SEBSERVER_VERSION}"
WORKDIR /sebserver
RUN if [ "x${GIT_TAG}" = "x" ] ; \
then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \
else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi
FROM maven:latest
ARG SEBSERVER_VERSION
WORKDIR /sebserver
COPY --from=0 /sebserver/seb-server /sebserver
RUN mvn clean install -DskipTests -Dbuild-version="${SEBSERVER_VERSION}"
FROM openjdk:11-jre-stretch
ARG SEBSERVER_VERSION
ENV SEBSERVER_JAR="seb-server-${SEBSERVER_VERSION}.jar"
ENV SERVER_PORT="8080"
ENV SECRET=somePW
WORKDIR /sebserver
COPY --from=1 /sebserver/target/"${SEBSERVER_JAR}" /sebserver
CMD exec java \
-Xms64M \
-Xmx1G \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=gui,prod,prod-gui \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.password="${SECRET}" ;
EXPOSE 8080

View file

@ -0,0 +1,21 @@
upstream backend {
ip_hash;
server seb-webservice1:8080;
server seb-webservice2:8080;
server seb-webservice3:8080;
}
server {
listen 80;
charset utf-8;
access_log off;
location / {
proxy_pass http://backend;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View file

@ -0,0 +1,54 @@
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
# Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ROOT=WARN
logging.level.ch=DEBUG
logging.file=/sebserver/log/sebserver.log
logging.config=/sebserver/config/spring/logback-prod.xml
##########################################################
### SEB Server Webservice configuration
sebserver.test.property=This is a basic single-webservice productive setup
# webservice database server connection
datastore.mariadb.server.address=seb-server-mariadb
datastore.mariadb.server.port=3306
# data source configuration
spring.datasource.hikari.initializationFailTimeout=30000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
### webservice networking
sebserver.webservice.distributed=true
sebserver.webservice.http.external.scheme=http
sebserver.webservice.http.external.servername=localhost
sebserver.webservice.http.external.port=8080
sebserver.webservice.http.redirect.gui=/gui
# webservice API
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=25200
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery
sebserver.webservice.api.exam.endpoint.v1=${sebserver.webservice.api.exam.endpoint}/v1
sebserver.webservice.api.exam.accessTokenValiditySeconds=3600
sebserver.webservice.api.exam.event-handling-strategy=ASYNC_BATCH_STORE_STRATEGY
sebserver.webservice.api.exam.enable-indicator-cache=true
sebserver.webservice.api.pagination.maxPageSize=500
# comma separated list of known possible OpenEdX API access token request endpoints
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>log/sebserver.log</file>
<append>true</append>
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread]:[%logger] %msg%n</pattern>
</encoder>
</appender>
<springProfile name="prod">
<root level="DEBUG" additivity="true">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</springProfile>
</configuration>

View file

@ -0,0 +1,93 @@
version: '3.5'
services:
seb-webservice1:
build:
context: .
dockerfile: sebwebservice.Dockerfile
args:
- GIT_TAG=development
- SEBSERVER_VERSION=1.0.1
container_name: seb-webservice1
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
- seb-server-logs:/sebserver/log
environment:
- SECRET=somePW
logging:
driver: "json-file"
options:
mode: "non-blocking"
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
restart: unless-stopped
seb-webservice2:
build:
context: .
dockerfile: sebwebservice.Dockerfile
args:
- GIT_TAG=development
- SEBSERVER_VERSION=1.0.1
container_name: seb-webservice2
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
- seb-server-logs:/sebserver/log
environment:
- SECRET=somePW
logging:
driver: "json-file"
options:
mode: "non-blocking"
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
restart: unless-stopped
seb-webservice3:
build:
context: .
dockerfile: sebwebservice.Dockerfile
args:
- GIT_TAG=development
- SEBSERVER_VERSION=1.0.1
container_name: seb-webservice3
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
- seb-server-logs:/sebserver/log
environment:
- SECRET=somePW
logging:
driver: "json-file"
options:
mode: "non-blocking"
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
restart: unless-stopped
reverse-proxy:
image: "nginx:latest"
container_name: seb-server-proxy
volumes:
- ./config/nginx:/etc/nginx/conf.d
ports:
- 8081:80
networks:
- seb-server-network
restart: unless-stopped
volumes:
seb-server-config:
seb-server-logs:
name: seb-webservice-logs
networks:
seb-server-network:
name: seb-server-network

View file

@ -0,0 +1,38 @@
FROM alpine/git
ARG SEBSERVER_VERSION
ARG GIT_TAG="v${SEBSERVER_VERSION}"
WORKDIR /sebserver
RUN if [ "x${GIT_TAG}" = "x" ] ; \
then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \
else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi
FROM maven:latest
ARG SEBSERVER_VERSION
WORKDIR /sebserver
COPY --from=0 /sebserver/seb-server /sebserver
RUN mvn clean install -DskipTests -Dbuild-version="${SEBSERVER_VERSION}"
FROM openjdk:11-jre-stretch
ARG SEBSERVER_VERSION
ENV SEBSERVER_JAR="seb-server-${SEBSERVER_VERSION}.jar"
ENV SERVER_PORT="8080"
ENV SECRET=somePW
WORKDIR /sebserver
COPY --from=1 /sebserver/target/"${SEBSERVER_JAR}" /sebserver
CMD exec java \
-Xms64M \
-Xmx1G \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=ws,prod,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.mariadb.password="${SECRET}" \
--sebserver.password="${SECRET}" ;
EXPOSE $SERVER_PORT

View file

@ -0,0 +1,2 @@
admin readwrite
user readonly

View file

@ -0,0 +1,16 @@
[mysqld]
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# network
connect_timeout = 61
wait_timeout = 28800
max_connections = 100000
max_allowed_packet = 256M
max_connect_errors = 1000000
skip_external_locking
skip_name_resolve
#memory
innodb_buffer_pool_size=2G

View file

@ -0,0 +1,25 @@
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server {
listen 443 ssl;
charset utf-8;
access_log off;
keepalive_timeout 70;
server_name localhost;
ssl_certificate /sebserver/config/certs/localhost.crt;
ssl_certificate_key /sebserver/config/certs/localhost.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://seb-server:8080;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}

View file

@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDXDCCAkSgAwIBAgIJAJYb2nNBXHKCMA0GCSqGSIb3DQEBCwUAMEMxCzAJBgNV
BAYTAkNIMQ8wDQYDVQQIDAZadXJpY2gxDzANBgNVBAcMBlp1cmljaDESMBAGA1UE
AwwJbG9jYWxob3N0MB4XDTIwMDQzMDEzMDI0OVoXDTIxMDQzMDEzMDI0OVowQzEL
MAkGA1UEBhMCQ0gxDzANBgNVBAgMBlp1cmljaDEPMA0GA1UEBwwGWnVyaWNoMRIw
EAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQDLwuUqViIl8RtzQoYiZ6vHM49UlhgrD51sziO1PuDIfZo7R3M3NFuCmwsOlXoH
vHagcFFpplG3br/akbMCiIbZaWCJiNluZy+b1eFNHmPo8KvCFhRZfAUtKbzku2zL
53O7/oMBUbhJILXC5is832K0qswh/QEmndySTO8sb4IZ3EZV4krQ7UlDgbvRruvL
PrqEn25jiuhe5SnrkmI4rlaClvgOJ18qq+L4op90fd0W2V11WV9AJLk7boqVtCwT
ee++SpVxS1W5EsCiZwKVrmrxUXPpC+Q67MNO+GJzW1xivcnz6fpOjoCRisudRtEb
/GRO2jLVr3KvmyftJMk02d5xAgMBAAGjUzBRMB0GA1UdDgQWBBQQmfmkV++5QA0r
uP7xbegL02qLkTAfBgNVHSMEGDAWgBQQmfmkV++5QA0ruP7xbegL02qLkTAPBgNV
HRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQC5nt2yexZjt0yaociBiveF
Y1ePyT3QVdDEzaAzMHNJxPA0DcsaJdViv/K8Ri9a7aZgjI7tGR93rTUSs8EgxoYQ
ZUn6Av4xwTHIAoGbIS24pd6wljkehB6G4xGK4D8R51AHqHPwlV9pe/9FhqnIwagr
RMXJurEiKf1EiX/4ryrs5hFzSauUGEhnq7HTGRygK1boN0LNqLx5G4vLtYzOCDuN
GnshMJJvXkQe6Fre1rFnVoBtcbhoEqkp3LLr3eHSiAf7gy4iXjzhGCw/LX0pbEqr
B0Zt+ouuTfga0Pvj3MNEWyI+3CWqXldB/RvonZxWXUhh6ONU2qzRYenewI8gDfIZ
-----END CERTIFICATE-----

View file

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDLwuUqViIl8Rtz
QoYiZ6vHM49UlhgrD51sziO1PuDIfZo7R3M3NFuCmwsOlXoHvHagcFFpplG3br/a
kbMCiIbZaWCJiNluZy+b1eFNHmPo8KvCFhRZfAUtKbzku2zL53O7/oMBUbhJILXC
5is832K0qswh/QEmndySTO8sb4IZ3EZV4krQ7UlDgbvRruvLPrqEn25jiuhe5Snr
kmI4rlaClvgOJ18qq+L4op90fd0W2V11WV9AJLk7boqVtCwTee++SpVxS1W5EsCi
ZwKVrmrxUXPpC+Q67MNO+GJzW1xivcnz6fpOjoCRisudRtEb/GRO2jLVr3Kvmyft
JMk02d5xAgMBAAECggEALXh7rXv1OORaTNlel5TtB5Ig/S5VjF56sgo6e7rhbLxi
y7HBK2OavEWfLQz8Y3eSPXFzKZF9EOM9GyiCeyE+fov+iBKq+vE59ZvAIHaUsynq
GnDU77c2bIKw7ZZJzCMFd8FvOL8k0eTjyu+UXIw5OboXvcn5FMYLr/ZNNWxY6y4P
33fR63HUAQOglxkvzqfCYcWqiBr3fowQcKfeVjSveeTMEHMDq/EWcq1+xmGRs037
cWfLw8A2Vo6lN4CSJvXMJXzNgd3uKG4EI+nTzrO7WaH6KpxIkGkD/u50J868tR+C
TmQnQIvMkjGSiulGHHZhQ3v8zEXzSU3ramxnBM9O8QKBgQDszx7Z5Cioc1RK4dKt
qLhvbQYXQC3XF0WWOjuG6NTxA/cKejQ9fpLzu0UnRYsUfsyiahtB+umGsWxO1yAp
aVf25CYp2lTTvP3EDo9wzOfp9NBqiKSkTTmYvp7i9idGU4Tg8gYUQcG9F63L1M3X
6Xb8ZWylJoypegz2CeDWIh+RXQKBgQDcRikZYaGKsMgCxRVyxeHOFbml4Fk0wH+C
YsrOHMV29Ck/8t/Ajy8+42TmnrmCFsTK4OVG9L87CF9TNxBU8WBAG2YqmiQbH49i
UEaxBSfcmOqgPFGy62EQadUTn4f+HbZJKPyaeMhnKJseIIWy2i+a0Q6+0GX+Gke6
Qe6FWkeMJQKBgQDJ8ZcNmVRS0ob/lLRlA4zE+ORIz6JH2sCs69v3oHZ3UjpJ5QzH
pDkNQJYod1WzlK5Nks7L5X1gL819Lldu+TbahJVG+7l7F6AQoZoRR6w+B1f0gbJl
qrWDXIuCYQf9IRwf+ETW4XymFJtRR5iCl8WwV43fCJDLthl3d9UUxuTEwQKBgQDb
dRNRdFHLqeE70TtTRA96kW6K8wAtbHQdZWwE+elKYGwQiFugr4c0sr0+f3j3QNQE
BRipHwK/P9IpSDz/RBTPCf06CKRcWY8zNiOYDjjusXNg/XewOI5WGfruOAz3goaw
USOKizeuf2g8Fc7eqD6xkgOM3HghN/GqgjGvroiF+QKBgQDQZRljdl/dTi5GijFb
FJwDGEhTpDYEBKb9AwWa5xP0u7JoqCv+0eP8/9eLmjzgawKTjtPHVMaeBmzMeW4O
E+x4114yQthVTs1e8TnoprkapEQNlvDGxJsYycJ4ADrrgOzA+HeddUj9GrWEfd8f
t7TrY/khzS4yDWvTFYG5wag+5Q==
-----END PRIVATE KEY-----

View file

@ -0,0 +1,73 @@
##########################################################
### Global Server Settings
# Server address (set for docker internal)
server.address=0.0.0.0
# Server http port
server.port=8080
# The servlet context path
server.servlet.context-path=/
# Logging
# Default logging level in the form "logging.level" + namespace=LEVEL
logging.level.ROOT=WARN
logging.level.ch=INFO
logging.file=/sebserver/log/sebserver.log
##########################################################
### SEB Server Webservice configuration
sebserver.test.property=This is a basic bundled productive setup
# webservice database server connection
datastore.mariadb.server.address=seb-server-mariadb
datastore.mariadb.server.port=3306
# data source configuration
spring.datasource.hikari.initializationFailTimeout=30000
spring.datasource.hikari.connectionTimeout=30000
spring.datasource.hikari.idleTimeout=600000
spring.datasource.hikari.maxLifetime=1800000
### webservice networking
sebserver.webservice.distributed=false
sebserver.webservice.http.external.scheme=http
sebserver.webservice.http.external.servername=
sebserver.webservice.http.external.port=
sebserver.webservice.http.redirect.gui=/gui
# webservice API
sebserver.webservice.api.admin.endpoint=/admin-api/v1
sebserver.webservice.api.admin.accessTokenValiditySeconds=3600
sebserver.webservice.api.admin.refreshTokenValiditySeconds=25200
sebserver.webservice.api.exam.config.init.permittedProcesses=config/initialPermittedProcesses.xml
sebserver.webservice.api.exam.config.init.prohibitedProcesses=config/initialProhibitedProcesses.xml
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.endpoint.discovery=${sebserver.webservice.api.exam.endpoint}/discovery
sebserver.webservice.api.exam.endpoint.v1=${sebserver.webservice.api.exam.endpoint}/v1
sebserver.webservice.api.exam.accessTokenValiditySeconds=3600
sebserver.webservice.api.exam.event-handling-strategy=ASYNC_BATCH_STORE_STRATEGY
sebserver.webservice.api.exam.enable-indicator-cache=true
sebserver.webservice.api.pagination.maxPageSize=500
# comma separated list of known possible OpenEdX API access token request endpoints
sebserver.webservice.lms.openedx.api.token.request.paths=/oauth2/access_token
##########################################################
### SEB Server GUI configuration
sebserver.gui.external.messages=file:/sebserver/config/spring/messages
sebserver.gui.multilingual=false
sebserver.gui.supported.languages=en
sebserver.gui.theme=css/sebserver.css
sebserver.gui.list.page.size=20
sebserver.gui.date.displayformat=de
sebserver.gui.entrypoint=/gui
sebserver.gui.webservice.protocol=http
sebserver.gui.webservice.address=localhost
sebserver.gui.webservice.port=8080
# defines the polling interval that is used to poll the webservice for client connection data on a monitored exam page
sebserver.gui.webservice.poll-interval=1000
sebserver.gui.webservice.mock-lms-enabled=true
sebserver.gui.seb.client.config.download.filename=SEBServerSettings.seb
sebserver.gui.seb.exam.config.download.filename=SEBExamSettings.seb

View file

@ -0,0 +1,6 @@
sebserver.overall.imprint=
sebserver.overall.imprint.markup=
sebserver.overall.about=About
sebserver.overall.about.markup=<span style='font-family: Arial, Helvetica,sans-serif;font-size: 25px;font-weight: normal;font-style: normal;color: rgb(31, 64, 122);'>SEB Server About Example</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 18px;font-weight: bold;font-style: normal;'>1. This is an example of how an About-Page can look like.</span><br/><br/><span style='font-family: Arial, Helvetica,sans-serif;font-size: 14px;font-weight: normal;font-style: normal;'>By simply define the markup HTML content within the messages.propertie configuration of specified language</span>
sebserver.overall.help=Documentation
sebserver.overall.help.link=https://seb-server.readthedocs.io/en/latest/index.html

View file

@ -0,0 +1,74 @@
version: '3'
services:
seb-server-setup:
build:
context: .
dockerfile: setup.Dockerfile
container_name: seb-server-setup
volumes:
- seb-server-config:/config
- ./config:/host/config
mariadb:
image: "mariadb/server:10.3"
container_name: seb-server-mariadb
environment:
- MYSQL_ROOT_PASSWORD_FILE=/etc/mysql/conf.d/secret
ports:
- 3306:3306
volumes:
- seb-server-config:/etc/mysql/conf.d
- seb-server-mariadb:/var/lib/mysql
- ./config/mariadb/config.cnf:/etc/mysql/conf.d/config.cnf
networks:
- seb-server-network
restart: unless-stopped
seb-server:
build:
context: .
dockerfile: sebserver.Dockerfile
args:
- SEBSERVER_VERSION=1.0-latest
container_name: seb-server
volumes:
- seb-server-config:/sebserver/config
- ./config/spring:/sebserver/config/spring
- seb-server-logs:/sebserver/log
environment:
- JMX_PORT=9090
ports:
- 9090:9090
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server-setup"
reverse-proxy:
image: "nginx:latest"
container_name: seb-server-proxy
volumes:
- ./config/nginx:/etc/nginx/conf.d
- ./config/nginx/certs:/sebserver/config/certs
ports:
- 443:443
networks:
- seb-server-network
depends_on:
- "mariadb"
- "seb-server"
- "seb-server-setup"
networks:
seb-server-network:
volumes:
seb-server-config:
seb-server-mariadb:
seb-server-logs:

View file

@ -0,0 +1,61 @@
# Clone git repository form specified tag
FROM alpine/git
ARG SEBSERVER_VERSION
ARG GIT_TAG="v${SEBSERVER_VERSION}"
WORKDIR /sebserver
RUN if [ "x${GIT_TAG}" = "x" ] ; \
then git clone --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; \
else git clone -b "$GIT_TAG" --depth 1 https://github.com/SafeExamBrowser/seb-server.git ; fi
# Build with maven (skip tests)
FROM maven:latest
ARG SEBSERVER_VERSION
WORKDIR /sebserver
COPY --from=0 /sebserver/seb-server /sebserver
RUN mvn clean install -DskipTests
FROM openjdk:11-jre-stretch
ARG SEBSERVER_VERSION
ENV SEBSERVER_JAR="seb-server-${SEBSERVER_VERSION}.jar"
ENV SERVER_PORT="8080"
ENV JMX_PORT=
WORKDIR /sebserver
COPY --from=1 /sebserver/target/"$SEBSERVER_JAR" /sebserver
CMD if [ "x${JMX_PORT}" = "x" ] ; \
then secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
else secret=$(cat /sebserver/config/secret) && exec java \
-Xms64M \
-Xmx1G \
-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=${JMX_PORT} \
-Dcom.sun.management.jmxremote.rmi.port=${JMX_PORT} \
-Djava.rmi.server.hostname=localhost \
-Dcom.sun.management.jmxremote.local.only=false \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.password.file=/sebserver/config/jmx/jmxremote.password \
-Dcom.sun.management.jmxremote.access.file=/sebserver/config/jmx/jmxremote.access \
-jar "${SEBSERVER_JAR}" \
--spring.profiles.active=prod,prod-gui,prod-ws \
--spring.config.location=file:/sebserver/config/spring/,classpath:/config/ \
--sebserver.certs.password="${secret}" \
--sebserver.mariadb.password="${secret}" \
--sebserver.password="${secret}" ; \
fi
EXPOSE $SERVER_PORT $JMX_PORT

View file

@ -0,0 +1,7 @@
FROM alpine:latest
CMD cp -a /host/config/. /config/ \
&& secret=$(cat /config/secret) \
&& rm /host/config/secret \
&& printf "monitorRoleUser ${secret}\ncontrolRoleUser ${secret}" > /config/jmxremote.password \
&& chmod 700 /config/jmxremote.password