Compare commits

..

9 Commits

Author SHA1 Message Date
Patrick Jentsch
b50147a66a Use IP instead of Hostname again... 2023-09-25 13:43:17 +02:00
Patrick Jentsch
18311c8c9c Use Hostname for cqpserver again... 2023-09-25 13:39:39 +02:00
Patrick Jentsch
2dc54f4258 Merge branch 'query-builder' of gitlab.ub.uni-bielefeld.de:sfb1288inf/nopaque into query-builder 2023-09-25 13:28:51 +02:00
Patrick Jentsch
bcdc3721ef Don't use container name as host for cqiclient 2023-09-25 13:28:48 +02:00
Inga Kirschnick
60bcaa9e01 Corpus Analysis Asset update 2023-09-25 12:42:10 +02:00
Patrick Jentsch
af89a5776f add missing dot 2023-09-25 10:18:19 +02:00
Patrick Jentsch
fcbf9c8cb6 Set default values in docker compose 2023-09-25 10:17:06 +02:00
Patrick Jentsch
cc6ce6e1f3 Merge branch 'query-builder' of gitlab.ub.uni-bielefeld.de:sfb1288inf/nopaque into query-builder 2023-09-25 10:11:51 +02:00
Patrick Jentsch
4581367d04 Restructure startup procedure 2023-09-25 10:11:11 +02:00
17 changed files with 425 additions and 248 deletions

View File

@ -8,5 +8,6 @@
!.flaskenv !.flaskenv
!boot.sh !boot.sh
!config.py !config.py
!docker-entrypoint.sh
!nopaque.py !nopaque.py
!requirements.txt !requirements.txt

210
.env.tpl
View File

@ -1,204 +1,32 @@
################################################################################ ##############################################################################
# Docker # # Variables for use in Docker Compose YAML files #
################################################################################ ##############################################################################
# DEFAULT: ./data
# NOTE: Use `.` as <project-basedir>
# HOST_DATA_DIR=
# Example: 1000
# HINT: Use this bash command `id -u` # HINT: Use this bash command `id -u`
# NOTE: 0 (= root user) is not allowed
HOST_UID= HOST_UID=
# Example: 1000
# HINT: Use this bash command `id -g` # HINT: Use this bash command `id -g`
HOST_GID= HOST_GID=
# Example: 999
# HINT: Use this bash command `getent group docker | cut -d: -f3` # HINT: Use this bash command `getent group docker | cut -d: -f3`
HOST_DOCKER_GID= HOST_DOCKER_GID=
# DEFAULT: ./logs # DEFAULT: nopaque
# NOTES: Use `.` as <project-basedir> # DOCKER_DEFAULT_NETWORK_NAME=
# HOST_LOG_DIR=
# DEFAULT: nopaque_default # DEFAULT: ./volumes/db/data
# DOCKER_NETWORK_NAME= # NOTE: Use `.` as <project-basedir>
# DOCKER_DB_SERVICE_DATA_VOLUME_SOURCE_PATH=
################################################################################ # DEFAULT: ./volumes/mq/data
# Flask # # NOTE: Use `.` as <project-basedir>
# https://flask.palletsprojects.com/en/1.1.x/config/ # # DOCKER_MQ_SERVICE_DATA_VOLUME_SOURCE_PATH=
################################################################################
# CHOOSE ONE: http, https
# DEFAULT: http
# PREFERRED_URL_SCHEME=
# DEFAULT: hard to guess string # NOTE: This must be a network share and it must be available on all
# HINT: Use this bash command `python -c "import uuid; print(uuid.uuid4().hex)"` # Docker Swarm nodes, mounted to the same path with the same
# SECRET_KEY= # user and group ownership.
DOCKER_NOPAQUE_SERVICE_DATA_VOLUME_SOURCE_PATH=
# DEFAULT: localhost:5000 # DEFAULT: ./volumes/nopaque/logs
# Example: nopaque.example.com/nopaque.example.com:5000 # NOTE: Use `.` as <project-basedir>
# HINT: If your instance is publicly available on a different Port then 80/443, # DOCKER_NOPAQUE_SERVICE_LOGS_VOLUME_SOURCE_PATH=.
# you will have to add this to the server name
# SERVER_NAME=
# CHOOSE ONE: False, True
# DEFAULT: False
# HINT: Set to true if you redirect http to https
# SESSION_COOKIE_SECURE=
################################################################################
# Flask-Assets #
# https://webassets.readthedocs.io/en/latest/ #
################################################################################
# CHOOSE ONE: False, True
# DEFAULT: False
# ASSETS_DEBUG=
################################################################################
# Flask-Hashids #
# https://github.com/Pevtrick/Flask-Hashids #
################################################################################
# DEFAULT: 16
# HASHIDS_MIN_LENGTH=
# NOTE: Use this bash command `python -c "import uuid; print(uuid.uuid4().hex)"`
# It is strongly recommended that this is NEVER the same as the SECRET_KEY
HASHIDS_SALT=
################################################################################
# Flask-Login #
# https://flask-login.readthedocs.io/en/latest/ #
################################################################################
# CHOOSE ONE: False, True
# DEFAULT: False
# HINT: Set to true if you redirect http to https
# REMEMBER_COOKIE_SECURE=
################################################################################
# Flask-Mail #
# https://pythonhosted.org/Flask-Mail/ #
################################################################################
# EXAMPLE: nopaque Admin <nopaque@example.com>
MAIL_DEFAULT_SENDER=
MAIL_PASSWORD=
# EXAMPLE: smtp.example.com
MAIL_SERVER=
# EXAMPLE: 587
MAIL_PORT=
# CHOOSE ONE: False, True
# DEFAULT: False
# MAIL_USE_SSL=
# CHOOSE ONE: False, True
# DEFAULT: False
# MAIL_USE_TLS=
# EXAMPLE: nopaque@example.com
MAIL_USERNAME=
################################################################################
# Flask-SQLAlchemy #
# https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/ #
################################################################################
# DEFAULT: 'sqlite:///<nopaque-basedir>/data.sqlite'
# NOTE: Use `.` as <nopaque-basedir>,
# Don't use a SQLite database when using Docker
# SQLALCHEMY_DATABASE_URI=
################################################################################
# nopaque #
################################################################################
# An account is registered with this email adress gets automatically assigned
# the administrator role.
# EXAMPLE: admin.nopaque@example.com
NOPAQUE_ADMIN=
# DEFAULT: /mnt/nopaque
# NOTE: This must be a network share and it must be available on all Docker
# Swarm nodes
# NOPAQUE_DATA_DIR=
# CHOOSE ONE: False, True
# DEFAULT: True
# NOPAQUE_IS_PRIMARY_INSTANCE=
# transport://[userid:password]@hostname[:port]/[virtual_host]
NOPAQUE_SOCKETIO_MESSAGE_QUEUE_URI=
# NOTE: Get these from the nopaque development team
NOPAQUE_DOCKER_REGISTRY_USERNAME=
NOPAQUE_DOCKER_REGISTRY_PASSWORD=
# DEFAULT: %Y-%m-%d %H:%M:%S
# NOPAQUE_LOG_DATE_FORMAT=
# DEFAULT: [%(asctime)s] %(levelname)s in %(pathname)s (function: %(funcName)s, line: %(lineno)d): %(message)s
# NOPAQUE_LOG_FORMAT=
# DEFAULT: INFO
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
# NOPAQUE_LOG_LEVEL=
# CHOOSE ONE: False, True
# DEFAULT: True
# NOPAQUE_LOG_FILE_ENABLED=
# DEFAULT: <nopaque-basedir>/logs
# NOTE: Use `.` as <nopaque-basedir>
# NOPAQUE_LOG_FILE_DIR=
# DEFAULT: NOPAQUE_LOG_LEVEL
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
# NOPAQUE_LOG_FILE_LEVEL=
# CHOOSE ONE: False, True
# DEFAULT: False
# NOPAQUE_LOG_STDERR_ENABLED=
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
# DEFAULT: NOPAQUE_LOG_LEVEL
# NOPAQUE_LOG_STDERR_LEVEL=
# CHOOSE ONE: False, True
# DEFAULT: False
# HINT: Set this to True only if you are using a proxy in front of nopaque
# NOPAQUE_PROXY_FIX_ENABLED=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-For
# NOPAQUE_PROXY_FIX_X_FOR=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Host
# NOPAQUE_PROXY_FIX_X_HOST=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Port
# NOPAQUE_PROXY_FIX_X_PORT=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Prefix
# NOPAQUE_PROXY_FIX_X_PREFIX=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Proto
# NOPAQUE_PROXY_FIX_X_PROTO=
# CHOOSE ONE: False, True
# DEFAULT: False
# NOPAQUE_TRANSKRIBUS_ENABLED=
# READ-COOP account data: https://readcoop.eu/
# NOPAQUE_READCOOP_USERNAME=
# NOPAQUE_READCOOP_PASSWORD=

2
.gitignore vendored
View File

@ -1,6 +1,6 @@
# nopaque specifics # nopaque specifics
app/static/gen/ app/static/gen/
data/ volumes/
docker-compose.override.yml docker-compose.override.yml
logs/ logs/
!logs/dummy !logs/dummy

42
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,42 @@
default:
image: docker:24.0.6
services:
- docker:24.0.6-dind
tags:
- docker
variables:
DOCKER_TLS_CERTDIR: /certs
build_image:
stage: build
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: on_success
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:latest
- if: $CI_COMMIT_TAG
when: "on_success"
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
- when: never
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
script:
- docker build -t $IMAGE_TAG .
- docker push $IMAGE_TAG
include:
- template: Security/Container-Scanning.gitlab-ci.yml
container_scanning:
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: on_success
variables:
CS_IMAGE: $CI_REGISTRY_IMAGE:latest
- if: $CI_COMMIT_TAG
when: on_success
variables:
CS_IMAGE: ${CI_REGISTRY_IMAGE}:${CI_COMMIT_REF_NAME}
- when: never

View File

@ -4,11 +4,6 @@ FROM python:3.11.5-slim-bookworm
LABEL authors="Patrick Jentsch <p.jentsch@uni-bielefeld.de>" LABEL authors="Patrick Jentsch <p.jentsch@uni-bielefeld.de>"
ARG DOCKER_GID
ARG UID
ARG GID
ENV LANG="C.UTF-8" ENV LANG="C.UTF-8"
ENV PYTHONDONTWRITEBYTECODE="1" ENV PYTHONDONTWRITEBYTECODE="1"
ENV PYTHONUNBUFFERED="1" ENV PYTHONUNBUFFERED="1"
@ -17,34 +12,42 @@ ENV PYTHONUNBUFFERED="1"
RUN apt-get update \ RUN apt-get update \
&& apt-get install --no-install-recommends --yes \ && apt-get install --no-install-recommends --yes \
build-essential \ build-essential \
gosu \
libpq-dev \ libpq-dev \
&& rm --recursive /var/lib/apt/lists/* && rm --recursive /var/lib/apt/lists/*
RUN groupadd --gid "${DOCKER_GID}" docker \ COPY docker-entrypoint.sh /usr/local/bin/
&& groupadd --gid "${GID}" nopaque \
&& useradd --create-home --gid nopaque --groups "${DOCKER_GID}" --no-log-init --uid "${UID}" nopaque
RUN useradd --create-home --no-log-init nopaque \
&& groupadd docker \
&& usermod --append --groups docker nopaque
USER nopaque USER nopaque
WORKDIR /home/nopaque WORKDIR /home/nopaque
ENV PYTHON3_VENV_PATH="/home/nopaque/venv" ENV NOPAQUE_PYTHON3_VENV_PATH="/home/nopaque/.venv"
RUN python3 -m venv "${PYTHON3_VENV_PATH}" RUN python3 -m venv "${NOPAQUE_PYTHON3_VENV_PATH}"
ENV PATH="${PYTHON3_VENV_PATH}/bin:${PATH}" ENV PATH="${NOPAQUE_PYTHON3_VENV_PATH}/bin:${PATH}"
COPY --chown=nopaque:nopaque requirements.txt .
RUN python3 -m pip install --requirement requirements.txt \
&& rm requirements.txt
COPY --chown=nopaque:nopaque app app COPY --chown=nopaque:nopaque app app
COPY --chown=nopaque:nopaque migrations migrations COPY --chown=nopaque:nopaque migrations migrations
COPY --chown=nopaque:nopaque tests tests COPY --chown=nopaque:nopaque tests tests
COPY --chown=nopaque:nopaque .flaskenv boot.sh config.py nopaque.py ./ COPY --chown=nopaque:nopaque .flaskenv boot.sh config.py nopaque.py requirements.txt ./
RUN python3 -m pip install --requirement requirements.txt \
&& mkdir logs
USER root
EXPOSE 5000 EXPOSE 5000
ENTRYPOINT ["./boot.sh"] ENTRYPOINT ["docker-entrypoint.sh"]

View File

@ -13,7 +13,6 @@ from flask_paranoid import Paranoid
from flask_socketio import SocketIO from flask_socketio import SocketIO
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask_hashids import Hashids from flask_hashids import Hashids
from werkzeug.exceptions import HTTPException
apifairy = APIFairy() apifairy = APIFairy()

View File

@ -1,13 +1,14 @@
from cqi import CQiClient from cqi import CQiClient
from cqi.errors import CQiException from cqi.errors import CQiException
from cqi.status import CQiStatus from cqi.status import CQiStatus
from flask import session from docker.models.containers import Container
from flask import current_app, session
from flask_login import current_user from flask_login import current_user
from flask_socketio import Namespace from flask_socketio import Namespace
from inspect import signature from inspect import signature
from threading import Lock from threading import Lock
from typing import Callable, Dict, List, Optional from typing import Callable, Dict, List, Optional
from app import db, hashids, socketio from app import db, docker_client, hashids, socketio
from app.decorators import socketio_login_required from app.decorators import socketio_login_required
from app.models import Corpus, CorpusStatus from app.models import Corpus, CorpusStatus
from . import extensions from . import extensions
@ -121,7 +122,11 @@ class CQiNamespace(Namespace):
socketio.sleep(3) socketio.sleep(3)
retry_counter -= 1 retry_counter -= 1
db.session.refresh(db_corpus) db.session.refresh(db_corpus)
cqi_client: CQiClient = CQiClient(f'cqpserver_{db_corpus_id}') # cqi_client: CQiClient = CQiClient(f'cqpserver_{db_corpus_id}')
cqpserver_container_name: str = f'cqpserver_{db_corpus_id}'
cqpserver_container: Container = docker_client.containers.get(cqpserver_container_name)
cqpserver_host: str = cqpserver_container.attrs['NetworkSettings']['Networks'][current_app.config['NOPAQUE_DOCKER_NETWORK_NAME']]['IPAddress']
cqi_client: CQiClient = CQiClient(cqpserver_host)
session['cqi_over_sio'] = { session['cqi_over_sio'] = {
'cqi_client': cqi_client, 'cqi_client': cqi_client,
'cqi_client_lock': Lock(), 'cqi_client_lock': Lock(),

View File

@ -143,7 +143,7 @@ def _create_cqpserver_container(corpus):
''' ## Name ## ''' ''' ## Name ## '''
name = f'cqpserver_{corpus.id}' name = f'cqpserver_{corpus.id}'
''' ## Network ## ''' ''' ## Network ## '''
network = f'{current_app.config["DOCKER_NETWORK_NAME"]}' network = f'{current_app.config["NOPAQUE_DOCKER_NETWORK_NAME"]}'
''' ## Volumes ## ''' ''' ## Volumes ## '''
volumes = [] volumes = []
''' ### Corpus data volume ### ''' ''' ### Corpus data volume ### '''

View File

@ -43,3 +43,5 @@ def deploy():
SpaCyNLPPipelineModel.insert_defaults() SpaCyNLPPipelineModel.insert_defaults()
print('Insert/Update default TesseractOCRPipelineModels') print('Insert/Update default TesseractOCRPipelineModels')
TesseractOCRPipelineModel.insert_defaults() TesseractOCRPipelineModel.insert_defaults()
# TODO: Implement checks for if the nopaque network exists

View File

@ -26,15 +26,6 @@
output='gen/app.%(version)s.js', output='gen/app.%(version)s.js',
'js/App.js', 'js/App.js',
'js/Utils.js', 'js/Utils.js',
'js/CorpusAnalysis/CorpusAnalysisApp.js',
'js/CorpusAnalysis/CorpusAnalysisConcordance.js',
'js/CorpusAnalysis/CorpusAnalysisReader.js',
'js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js',
'js/CorpusAnalysis/QueryBuilder.js',
'js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js',
'js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js',
'js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js',
'js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js',
'js/XMLtoObject.js' 'js/XMLtoObject.js'
%} %}
<script src="{{ ASSET_URL }}"></script> <script src="{{ ASSET_URL }}"></script>
@ -96,6 +87,21 @@
%} %}
<script src="{{ ASSET_URL }}"></script> <script src="{{ ASSET_URL }}"></script>
{%- endassets %} {%- endassets %}
{%- assets
filters='rjsmin',
output='gen/CorpusAnalysis.%(version)s.js',
'js/CorpusAnalysis/QueryBuilder/ElementReferencesQueryBuilder.js',
'js/CorpusAnalysis/QueryBuilder/GeneralFunctionsQueryBuilder.js',
'js/CorpusAnalysis/QueryBuilder/StructuralAttributeBuilderFunctionsQueryBuilder.js',
'js/CorpusAnalysis/QueryBuilder/TokenAttributeBuilderFunctionsQueryBuilder.js',
'js/CorpusAnalysis/CorpusAnalysisApp.js',
'js/CorpusAnalysis/CorpusAnalysisConcordance.js',
'js/CorpusAnalysis/QueryBuilder.js',
'js/CorpusAnalysis/CorpusAnalysisReader.js',
'js/CorpusAnalysis/CorpusAnalysisStaticVisualization.js'
%}
<script src="{{ ASSET_URL }}"></script>
{%- endassets %}
<script> <script>
const app = new App(); const app = new App();
{%- if current_user.is_authenticated %} {%- if current_user.is_authenticated %}

View File

@ -13,7 +13,7 @@ display_help() {
echo "Run '${script_name} COMMAND --help' for more information on a command." echo "Run '${script_name} COMMAND --help' for more information on a command."
} }
if [[ "${#}" -eq 0 ]]; then if [[ "${#}" == "0" ]]; then
if [[ "${NOPAQUE_IS_PRIMARY_INSTANCE:-True}" == "True" ]]; then if [[ "${NOPAQUE_IS_PRIMARY_INSTANCE:-True}" == "True" ]]; then
while true; do while true; do
flask deploy flask deploy
@ -26,7 +26,7 @@ if [[ "${#}" -eq 0 ]]; then
fi fi
python3 nopaque.py python3 nopaque.py
elif [[ "${1}" == "flask" ]]; then elif [[ "${1}" == "flask" ]]; then
flask "${@:2}" flask ${@:2}
elif [[ "${1}" == "--help" || "${1}" == "-h" ]]; then elif [[ "${1}" == "--help" || "${1}" == "-h" ]]; then
display_help display_help
else else

View File

@ -7,13 +7,10 @@ import os
basedir = os.path.abspath(os.path.dirname(__file__)) basedir = os.path.abspath(os.path.dirname(__file__))
load_dotenv(os.path.join(basedir, '.env')) load_dotenv(os.path.join(basedir, 'nopaque.env'))
class Config: class Config:
''' Docker '''
DOCKER_NETWORK_NAME = os.environ.get('DOCKER_NETWORK_NAME', 'nopaque_default')
''' APIFairy ''' ''' APIFairy '''
APIFAIRY_TITLE = 'nopaque' APIFAIRY_TITLE = 'nopaque'
APIFAIRY_VERSION = '0.0.1' APIFAIRY_VERSION = '0.0.1'
@ -35,8 +32,8 @@ class Config:
ASSETS_DEBUG = os.environ.get('ASSETS_DEBUG', 'false').lower() == 'true' ASSETS_DEBUG = os.environ.get('ASSETS_DEBUG', 'false').lower() == 'true'
''' # Flask-Hashids ''' ''' # Flask-Hashids '''
HASHIDS_MIN_LENGTH = 16 HASHIDS_MIN_LENGTH = int(os.environ.get('HASHIDS_MIN_LENGTH', '16'))
HASHIDS_SALT=os.environ.get('HASHIDS_SALT') HASHIDS_SALT=os.environ.get('HASHIDS_SALT', 'hard to guess string')
''' # Flask-Login # ''' ''' # Flask-Login # '''
REMEMBER_COOKIE_SECURE = \ REMEMBER_COOKIE_SECURE = \
@ -61,7 +58,7 @@ class Config:
''' # nopaque # ''' ''' # nopaque # '''
NOPAQUE_ADMIN = os.environ.get('NOPAQUE_ADMIN') NOPAQUE_ADMIN = os.environ.get('NOPAQUE_ADMIN')
NOPAQUE_DATA_DIR = \ NOPAQUE_DATA_DIR = \
os.path.abspath(os.environ.get('NOPAQUE_DATA_DIR', '/mnt/nopaque')) os.path.abspath(os.environ.get('NOPAQUE_DATA_PATH', '/mnt/nopaque'))
NOPAQUE_IS_PRIMARY_INSTANCE = \ NOPAQUE_IS_PRIMARY_INSTANCE = \
os.environ.get('NOPAQUE_IS_PRIMARY_INSTANCE', 'true').lower() == 'true' os.environ.get('NOPAQUE_IS_PRIMARY_INSTANCE', 'true').lower() == 'true'
NOPAQUE_MAIL_SUBJECT_PREFIX = '[nopaque]' NOPAQUE_MAIL_SUBJECT_PREFIX = '[nopaque]'
@ -74,6 +71,8 @@ class Config:
NOPAQUE_DOCKER_REGISTRY = 'gitlab.ub.uni-bielefeld.de:4567' NOPAQUE_DOCKER_REGISTRY = 'gitlab.ub.uni-bielefeld.de:4567'
NOPAQUE_DOCKER_IMAGE_PREFIX = f'{NOPAQUE_DOCKER_REGISTRY}/sfb1288inf/' NOPAQUE_DOCKER_IMAGE_PREFIX = f'{NOPAQUE_DOCKER_REGISTRY}/sfb1288inf/'
NOPAQUE_DOCKER_NETWORK_NAME = \
os.environ.get('DOCKER_NETWORK_NAME', 'nopaque')
NOPAQUE_DOCKER_REGISTRY_USERNAME = \ NOPAQUE_DOCKER_REGISTRY_USERNAME = \
os.environ.get('NOPAQUE_DOCKER_REGISTRY_USERNAME') os.environ.get('NOPAQUE_DOCKER_REGISTRY_USERNAME')
NOPAQUE_DOCKER_REGISTRY_PASSWORD = \ NOPAQUE_DOCKER_REGISTRY_PASSWORD = \
@ -90,7 +89,7 @@ class Config:
NOPAQUE_LOG_FILE_ENABLED = \ NOPAQUE_LOG_FILE_ENABLED = \
os.environ.get('NOPAQUE_LOG_FILE_ENABLED', 'true').lower() == 'true' os.environ.get('NOPAQUE_LOG_FILE_ENABLED', 'true').lower() == 'true'
NOPAQUE_LOG_FILE_DIR = \ NOPAQUE_LOG_FILE_DIR = \
os.environ.get('NOPAQUE_LOG_FILE_DIR', os.path.join(basedir, 'logs')) os.environ.get('NOPAQUE_LOGS_PATH', os.path.join(basedir, 'logs'))
NOPAQUE_LOG_FILE_LEVEL = \ NOPAQUE_LOG_FILE_LEVEL = \
os.environ.get('NOPAQUE_LOG_FILE_LEVEL', NOPAQUE_LOG_LEVEL) os.environ.get('NOPAQUE_LOG_FILE_LEVEL', NOPAQUE_LOG_LEVEL)
NOPAQUE_LOG_STDERR_ENABLED = \ NOPAQUE_LOG_STDERR_ENABLED = \

View File

@ -1,4 +1,11 @@
POSTGRES_DB_NAME= ##############################################################################
# Environment variables to configure the db service in docker-compose.yml. #
# #
# More information about the environment variables can be found here: #
# https://hub.docker.com/_/postgres #
##############################################################################
POSTGRES_DB=
POSTGRES_USER= POSTGRES_USER=

View File

@ -1,8 +1,17 @@
version: "3.5" version: "3.5"
# The docker-compose.yml file is not meant to be modified itself.
# Instead use the following files for configurations:
# - .env: Environment variables for the docker-compose.yml file.
# - db.env: Environment variables for the database service.
# - nopaque.env: Environment variables for the nopaque service.
# - docker-compose.override.yml: Override the docker-compose.yml file.
# - Don't change too much here, it's meant for configurations like exposing
# ports for development or adding labels for e.g. traefik.
networks: networks:
default: default:
name: "${DOCKER_NETWORK_NAME:-nopaque_default}" name: "${DOCKER_DEFAULT_NETWORK_NAME:-nopaque}"
services: services:
db: db:
@ -10,28 +19,46 @@ services:
image: postgres:11 image: postgres:11
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- "${HOST_DATA_DIR:-./data}/db:/var/lib/postgresql/data" - type: bind
source: "${DOCKER_DB_SERVICE_DATA_VOLUME_SOURCE_PATH:-./volumes/db/data}"
target: "/var/lib/postgresql/data"
mq: mq:
image: redis:6 image: redis:6
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- "${HOST_DATA_DIR:-./data}/mq:/data" - type: bind
source: "${DOCKER_MQ_SERVICE_DATA_VOLUME_SOURCE_PATH:-./volumes/mq/data}"
target: "/data"
nopaque: nopaque:
build: build: .
args:
DOCKER_GID: ${HOST_DOCKER_GID}
GID: ${HOST_GID}
UID: ${HOST_UID}
context: .
depends_on: depends_on:
- db - db
- mq - mq
env_file: .env env_file:
- nopaque.env
environment:
# This section overrides the values set in the nopaque.env file. Do not
# override the environment variables in a docker-compose.override.yml
# file unless you really know what you are doing.
- NOPAQUE_UID=${HOST_UID}
- NOPAQUE_GID=${HOST_GID}
- DOCKER_GID=${HOST_DOCKER_GID}
- NOPAQUE_DATA_PATH=${DOCKER_NOPAQUE_SERVICE_DATA_VOLUME_SOURCE_PATH}
- NOPAQUE_DOCKER_NETWORK_NAME=${DOCKER_DEFAULT_NETWORK_NAME:-nopaque}
- NOPAQUE_LOGS_PATH=/home/nopaque/logs
image: nopaque:latest image: nopaque:latest
restart: unless-stopped restart: unless-stopped
volumes: volumes:
- "/var/run/docker.sock:/var/run/docker.sock" - type: bind
- "${NOPAQUE_DATA_DIR:-/mnt/nopaque}:${NOPAQUE_DATA_DIR:-/mnt/nopaque}" source: "/var/run/docker.sock"
- "${HOST_LOG_DIR-./logs}:${NOPAQUE_LOG_DIR:-/home/nopaque/logs}" target: "/var/run/docker.sock"
# TODO: Make this less quirky. The target path should be variable.
# In order to achieve this, a cifs volume needs to be configured.
- type: bind
source: "${DOCKER_NOPAQUE_SERVICE_DATA_VOLUME_SOURCE_PATH}"
target: "${DOCKER_NOPAQUE_SERVICE_DATA_VOLUME_SOURCE_PATH}"
- type: bind
source: "${DOCKER_NOPAQUE_SERVICE_LOGS_VOLUME_SOURCE_PATH:-./volumes/nopaque/logs}"
target: "/home/nopaque/logs"

55
docker-entrypoint.sh Executable file
View File

@ -0,0 +1,55 @@
#!/bin/bash
GREEN_COLOR="\033[0;32m"
RED_COLOR="\033[0;31m"
NO_COLOR="\033[0m"
CHECK_MARK="\xE2\x9C\x93"
CROSS_MARK="\xE2\x9D\x8C"
echo -n "Set container UID and GIDs to match the host system..."
if [[ "${NOPAQUE_UID}" == 0 ]]; then
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
echo "Running as root is not allowed"
exit 1
else
echo ""
fi
echo -n "- Updating docker GID ($(getent group docker | cut -d: -f3) -> ${DOCKER_GID})... "
groupmod --gid "${DOCKER_GID}" docker > /dev/null
if [[ "${?}" == "0" ]]; then
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
else
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
exit 1
fi
echo -n "- Updating nopaque GID ($(id -g nopaque) -> ${NOPAQUE_GID})... "
groupmod --gid "${NOPAQUE_GID}" nopaque > /dev/null
if [[ "${?}" == "0" ]]; then
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
else
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
exit 1
fi
echo -n "- Updating nopaque UID ($(id -u nopaque) -> ${NOPAQUE_UID})... "
usermod --uid "${NOPAQUE_UID}" nopaque > /dev/null
if [[ "${?}" == "0" ]]; then
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
else
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
exit 1
fi
echo -n "- Updating nopaque directory owner and group... "
chown -R nopaque:nopaque /home/nopaque
if [[ "${?}" == "0" ]]; then
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
else
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
exit 1
fi
exec gosu nopaque ./boot.sh ${@}

View File

203
nopaque.env.tpl Normal file
View File

@ -0,0 +1,203 @@
##############################################################################
# Environment variables to configure the nopaque. #
# - When running nopaque with Docker Compose, these variables are set in the #
# `docker-compose.yml` file. #
# - When running nopaque without Docker, these variables are loaded by #
# nopaque in the config.py file #
##############################################################################
##############################################################################
# Flask #
# https://flask.palletsprojects.com/en/1.1.x/config/ #
##############################################################################
# CHOOSE ONE: http, https
# DEFAULT: http
# PREFERRED_URL_SCHEME=
# DEFAULT: hard to guess string
# HINT: Use this bash command `python -c "import uuid; print(uuid.uuid4().hex)"`
# SECRET_KEY=
# DEFAULT: localhost:5000
# EXAMPLES:
# - nopaque.example.com
# - nopaque.example.com:5000
# HINT: If your instance is publicly available on a different Port then 80/443,
# you will have to add this to the server name
# SERVER_NAME=
# CHOOSE ONE: False, True
# DEFAULT: False
# HINT: Set to true if you redirect http to https
# SESSION_COOKIE_SECURE=
##############################################################################
# Flask-Assets #
# https://webassets.readthedocs.io/en/latest/ #
##############################################################################
# CHOOSE ONE: False, True
# DEFAULT: False
# ASSETS_DEBUG=
##############################################################################
# Flask-Hashids #
# https://github.com/Pevtrick/Flask-Hashids #
##############################################################################
# DEFAULT: 16
# HASHIDS_MIN_LENGTH=
# DEFAULT: hard to guess string
# HINT: Use this bash command `python -c "import uuid; print(uuid.uuid4().hex)"`
# NOTE: In production it is strongly recommended that this is NEVER the same as
# the `SECRET_KEY`
# HASHIDS_SALT=
##############################################################################
# Flask-Login #
# https://flask-login.readthedocs.io/en/latest/ #
##############################################################################
# CHOOSE ONE: False, True
# DEFAULT: False
# HINT: Set to true if you redirect http to https
# REMEMBER_COOKIE_SECURE=
##############################################################################
# Flask-Mail #
# https://pythonhosted.org/Flask-Mail/ #
##############################################################################
# EXAMPLE: nopaque Admin <nopaque@example.com>
MAIL_DEFAULT_SENDER=
MAIL_PASSWORD=
# EXAMPLE: smtp.example.com
MAIL_SERVER=
# EXAMPLE: 587
MAIL_PORT=
# CHOOSE ONE: False, True
# DEFAULT: False
# MAIL_USE_SSL=
# CHOOSE ONE: False, True
# DEFAULT: False
# MAIL_USE_TLS=
# EXAMPLE: nopaque@example.com
MAIL_USERNAME=
##############################################################################
# Flask-SQLAlchemy #
# https://flask-sqlalchemy.palletsprojects.com/en/2.x/config/ #
##############################################################################
# NOTES:
# - Use `.` as <nopaque-basedir>
# - Don't use a SQLite database when using Docker Compose
SQLALCHEMY_DATABASE_URI=
##############################################################################
# nopaque #
##############################################################################
# An account is registered with this email adress gets automatically assigned
# the administrator role
# EXAMPLE: admin.nopaque@example.com
NOPAQUE_ADMIN=
# DEFAULT: /mnt/nopaque
# NOTES:
# - This must be a network share and it must be available on all
# Docker Swarm nodes, mounted to the same path with the same
# user and group ownership
# - When running with Docker Compose, this gets overwritten in the
# `docker-compose.yml` file
# NOPAQUE_DATA_PATH=
# CHOOSE ONE: False, True
# DEFAULT: True
# NOPAQUE_IS_PRIMARY_INSTANCE=
# transport://[userid:password]@hostname[:port]/[virtual_host]
NOPAQUE_SOCKETIO_MESSAGE_QUEUE_URI=
# DEFAULT: nopaque
# NOTE: When running with Docker Compose, this gets overwritten in the
# `docker-compose.yml` file
# NOPAQUE_DOCKER_NETWORK_NAME=
# NOTE: Get these from the nopaque development team
NOPAQUE_DOCKER_REGISTRY_USERNAME=
NOPAQUE_DOCKER_REGISTRY_PASSWORD=
# DEFAULT: %Y-%m-%d %H:%M:%S
# NOPAQUE_LOG_DATE_FORMAT=
# DEFAULT: [%(asctime)s] %(levelname)s in %(pathname)s (function: %(funcName)s, line: %(lineno)d): %(message)s
# NOPAQUE_LOG_FORMAT=
# DEFAULT: INFO
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
# NOPAQUE_LOG_LEVEL=
# CHOOSE ONE: False, True
# DEFAULT: True
# NOPAQUE_LOG_FILE_ENABLED=
# DEFAULT: <nopaque-basedir>/logs
# NOTES:
# - Use `.` as <nopaque-basedir>
# - When running with Docker Compose, this gets overwritten in the
# `docker-compose.yml` file
# NOPAQUE_LOGS_PATH=
# DEFAULT: NOPAQUE_LOG_LEVEL
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
# NOPAQUE_LOG_FILE_LEVEL=
# CHOOSE ONE: False, True
# DEFAULT: False
# NOPAQUE_LOG_STDERR_ENABLED=
# DEFAULT: NOPAQUE_LOG_LEVEL
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
# NOPAQUE_LOG_STDERR_LEVEL=
# CHOOSE ONE: False, True
# DEFAULT: False
# HINT: Set this to True only if you are using a proxy in front of nopaque
# NOPAQUE_PROXY_FIX_ENABLED=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-For
# NOPAQUE_PROXY_FIX_X_FOR=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Host
# NOPAQUE_PROXY_FIX_X_HOST=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Port
# NOPAQUE_PROXY_FIX_X_PORT=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Prefix
# NOPAQUE_PROXY_FIX_X_PREFIX=
# DEFAULT: 0
# Number of values to trust for X-Forwarded-Proto
# NOPAQUE_PROXY_FIX_X_PROTO=
# CHOOSE ONE: False, True
# DEFAULT: False
# NOPAQUE_TRANSKRIBUS_ENABLED=
# READ-COOP account data: https://readcoop.eu/
# NOPAQUE_READCOOP_USERNAME=
# NOPAQUE_READCOOP_PASSWORD=