mirror of
https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
synced 2025-01-13 03:30:35 +00:00
Compare commits
No commits in common. "81c6f32a354a1dee9be5f4933d0f6b69951c8776" and "f79c6d48b2ed1eb3597a687e8d607550dee0ec83" have entirely different histories.
81c6f32a35
...
f79c6d48b2
22
.env.tpl
22
.env.tpl
@ -1,20 +1,32 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# Environment variables used by Docker Compose config files. #
|
# Variables for use in Docker Compose YAML files #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# HINT: Use this bash command `id -u`
|
# HINT: Use this bash command `id -u`
|
||||||
# NOTE: 0 (= root user) is not allowed
|
# NOTE: 0 (= root user) is not allowed
|
||||||
HOST_UID=
|
HOST_UID=
|
||||||
|
|
||||||
# HINT: Use this bash command `id -g`
|
# HINT: Use this bash command `id -g`
|
||||||
# NOTE: 0 (= root group) is not allowed
|
|
||||||
HOST_GID=
|
HOST_GID=
|
||||||
|
|
||||||
# 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: nopaque
|
# DEFAULT: nopaque
|
||||||
NOPAQUE_DOCKER_NETWORK_NAME=nopaque
|
# DOCKER_DEFAULT_NETWORK_NAME=
|
||||||
|
|
||||||
|
# DEFAULT: ./volumes/db/data
|
||||||
|
# NOTE: Use `.` as <project-basedir>
|
||||||
|
# DOCKER_DB_SERVICE_DATA_VOLUME_SOURCE_PATH=
|
||||||
|
|
||||||
|
# DEFAULT: ./volumes/mq/data
|
||||||
|
# NOTE: Use `.` as <project-basedir>
|
||||||
|
# DOCKER_MQ_SERVICE_DATA_VOLUME_SOURCE_PATH=
|
||||||
|
|
||||||
# NOTE: This must be a network share and it must be available on all
|
# NOTE: This must be a network share and it must be available on all
|
||||||
# Docker Swarm nodes, mounted to the same path.
|
# Docker Swarm nodes, mounted to the same path with the same
|
||||||
HOST_NOPAQUE_DATA_PATH=/mnt/nopaque
|
# user and group ownership.
|
||||||
|
DOCKER_NOPAQUE_SERVICE_DATA_VOLUME_SOURCE_PATH=
|
||||||
|
|
||||||
|
# DEFAULT: ./volumes/nopaque/logs
|
||||||
|
# NOTE: Use `.` as <project-basedir>
|
||||||
|
# DOCKER_NOPAQUE_SERVICE_LOGS_VOLUME_SOURCE_PATH=.
|
||||||
|
18
.vscode/settings.json
vendored
18
.vscode/settings.json
vendored
@ -1,7 +1,19 @@
|
|||||||
{
|
{
|
||||||
"editor.rulers": [79],
|
"editor.rulers": [79],
|
||||||
"editor.tabSize": 2,
|
|
||||||
"files.insertFinalNewline": true,
|
"files.insertFinalNewline": true,
|
||||||
"files.trimFinalNewlines": true,
|
"[css]": {
|
||||||
"files.trimTrailingWhitespace": true
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
"[html]": {
|
||||||
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
"[javascript]": {
|
||||||
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
"[jinja-html]": {
|
||||||
|
"editor.tabSize": 2
|
||||||
|
},
|
||||||
|
"[scss]": {
|
||||||
|
"editor.tabSize": 2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,7 @@ from flask import current_app
|
|||||||
from flask_migrate import upgrade
|
from flask_migrate import upgrade
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
from app import db
|
|
||||||
from app.models import (
|
from app.models import (
|
||||||
Corpus,
|
|
||||||
CorpusFollowerRole,
|
CorpusFollowerRole,
|
||||||
Role,
|
Role,
|
||||||
SpaCyNLPPipelineModel,
|
SpaCyNLPPipelineModel,
|
||||||
@ -17,7 +15,7 @@ from . import bp
|
|||||||
@bp.cli.command('deploy')
|
@bp.cli.command('deploy')
|
||||||
def deploy():
|
def deploy():
|
||||||
''' Run deployment tasks. '''
|
''' Run deployment tasks. '''
|
||||||
|
# Make default directories
|
||||||
print('Make default directories')
|
print('Make default directories')
|
||||||
base_dir = current_app.config['NOPAQUE_DATA_DIR']
|
base_dir = current_app.config['NOPAQUE_DATA_DIR']
|
||||||
default_dirs: List[Path] = [
|
default_dirs: List[Path] = [
|
||||||
@ -30,9 +28,11 @@ def deploy():
|
|||||||
if not default_dir.is_dir():
|
if not default_dir.is_dir():
|
||||||
raise NotADirectoryError(f'{default_dir} is not a directory')
|
raise NotADirectoryError(f'{default_dir} is not a directory')
|
||||||
|
|
||||||
|
# migrate database to latest revision
|
||||||
print('Migrate database to latest revision')
|
print('Migrate database to latest revision')
|
||||||
upgrade()
|
upgrade()
|
||||||
|
|
||||||
|
# Insert/Update default database values
|
||||||
print('Insert/Update default Roles')
|
print('Insert/Update default Roles')
|
||||||
Role.insert_defaults()
|
Role.insert_defaults()
|
||||||
print('Insert/Update default Users')
|
print('Insert/Update default Users')
|
||||||
@ -44,9 +44,4 @@ def deploy():
|
|||||||
print('Insert/Update default TesseractOCRPipelineModels')
|
print('Insert/Update default TesseractOCRPipelineModels')
|
||||||
TesseractOCRPipelineModel.insert_defaults()
|
TesseractOCRPipelineModel.insert_defaults()
|
||||||
|
|
||||||
print('Stop running analysis sessions')
|
|
||||||
for corpus in Corpus.query.filter(Corpus.num_analysis_sessions > 0).all():
|
|
||||||
corpus.num_analysis_sessions = 0
|
|
||||||
db.session.commit()
|
|
||||||
|
|
||||||
# TODO: Implement checks for if the nopaque network exists
|
# TODO: Implement checks for if the nopaque network exists
|
||||||
|
63
config.py
63
config.py
@ -20,7 +20,6 @@ class Config:
|
|||||||
APIFAIRY_UI_PATH = '/api'
|
APIFAIRY_UI_PATH = '/api'
|
||||||
|
|
||||||
''' # Flask # '''
|
''' # Flask # '''
|
||||||
APPLICATION_ROOT = os.environ.get('APPLICATION_ROOT', '/')
|
|
||||||
PREFERRED_URL_SCHEME = os.environ.get('PREFERRED_URL_SCHEME', 'http')
|
PREFERRED_URL_SCHEME = os.environ.get('PREFERRED_URL_SCHEME', 'http')
|
||||||
SECRET_KEY = os.environ.get('SECRET_KEY', 'hard to guess string')
|
SECRET_KEY = os.environ.get('SECRET_KEY', 'hard to guess string')
|
||||||
SERVER_NAME = os.environ.get('SERVER_NAME', 'localhost:5000')
|
SERVER_NAME = os.environ.get('SERVER_NAME', 'localhost:5000')
|
||||||
@ -86,15 +85,17 @@ class Config:
|
|||||||
'[%(asctime)s] %(levelname)s in '
|
'[%(asctime)s] %(levelname)s in '
|
||||||
'%(pathname)s (function: %(funcName)s, line: %(lineno)d): %(message)s'
|
'%(pathname)s (function: %(funcName)s, line: %(lineno)d): %(message)s'
|
||||||
)
|
)
|
||||||
|
NOPAQUE_LOG_LEVEL = os.environ.get('NOPAQUE_LOG_LEVEL', 'INFO')
|
||||||
NOPAQUE_LOG_FILE_ENABLED = \
|
NOPAQUE_LOG_FILE_ENABLED = \
|
||||||
os.environ.get('NOPAQUE_LOG_FILE_ENABLED', 'false').lower() == 'true'
|
os.environ.get('NOPAQUE_LOG_FILE_ENABLED', 'true').lower() == 'true'
|
||||||
NOPAQUE_LOG_FILE_DIR = Path(os.environ.get('NOPAQUE_LOG_FILE_DIR', '/var/log/nopaque'))
|
NOPAQUE_LOG_FILE_DIR = \
|
||||||
|
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', None)
|
os.environ.get('NOPAQUE_LOG_FILE_LEVEL', NOPAQUE_LOG_LEVEL)
|
||||||
NOPAQUE_LOG_STDERR_ENABLED = \
|
NOPAQUE_LOG_STDERR_ENABLED = \
|
||||||
os.environ.get('NOPAQUE_LOG_STDERR_ENABLED', 'true').lower() == 'true'
|
os.environ.get('NOPAQUE_LOG_STDERR_ENABLED', 'false').lower() == 'true'
|
||||||
NOPAQUE_LOG_STDERR_LEVEL = \
|
NOPAQUE_LOG_STDERR_LEVEL = \
|
||||||
os.environ.get('NOPAQUE_LOG_STDERR_LEVEL', None)
|
os.environ.get('NOPAQUE_LOG_STDERR_LEVEL', NOPAQUE_LOG_LEVEL)
|
||||||
|
|
||||||
NOPAQUE_PROXY_FIX_ENABLED = \
|
NOPAQUE_PROXY_FIX_ENABLED = \
|
||||||
os.environ.get('NOPAQUE_PROXY_FIX_ENABLED', 'false').lower() == 'true'
|
os.environ.get('NOPAQUE_PROXY_FIX_ENABLED', 'false').lower() == 'true'
|
||||||
@ -118,35 +119,42 @@ class Config:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def init_app(app: Flask):
|
def init_app(app: Flask):
|
||||||
|
# Set up logging according to the corresponding (NOPAQUE_LOG_*)
|
||||||
|
# configurations
|
||||||
|
app.logger.setLevel(app.config['NOPAQUE_LOG_LEVEL'])
|
||||||
|
# Remove existing handlers
|
||||||
for handler in app.logger.handlers:
|
for handler in app.logger.handlers:
|
||||||
app.logger.removeHandler(handler)
|
app.logger.removeHandler(handler)
|
||||||
|
# Setup handlers
|
||||||
log_formatter = logging.Formatter(
|
formatter = logging.Formatter(
|
||||||
fmt=app.config['NOPAQUE_LOG_FORMAT'],
|
fmt=app.config['NOPAQUE_LOG_FORMAT'],
|
||||||
datefmt=app.config['NOPAQUE_LOG_DATE_FORMAT']
|
datefmt=app.config['NOPAQUE_LOG_DATE_FORMAT']
|
||||||
)
|
)
|
||||||
|
if app.config['NOPAQUE_IS_PRIMARY_INSTANCE']:
|
||||||
|
app.config['JOBS'].append(
|
||||||
|
{
|
||||||
|
"id": "daemon",
|
||||||
|
"func": "app.daemon:daemon",
|
||||||
|
"args": (app,),
|
||||||
|
"trigger": "interval",
|
||||||
|
"seconds": 3,
|
||||||
|
}
|
||||||
|
)
|
||||||
if app.config['NOPAQUE_LOG_STDERR_ENABLED']:
|
if app.config['NOPAQUE_LOG_STDERR_ENABLED']:
|
||||||
log_stderr_level: str | None = app.config['NOPAQUE_LOG_STDERR_LEVEL']
|
|
||||||
stream_handler = logging.StreamHandler()
|
stream_handler = logging.StreamHandler()
|
||||||
stream_handler.setFormatter(log_formatter)
|
stream_handler.setFormatter(formatter)
|
||||||
if log_stderr_level is not None:
|
stream_handler.setLevel(app.config['NOPAQUE_LOG_STDERR_LEVEL'])
|
||||||
stream_handler.setLevel(log_stderr_level)
|
|
||||||
app.logger.addHandler(stream_handler)
|
app.logger.addHandler(stream_handler)
|
||||||
|
|
||||||
if app.config['NOPAQUE_LOG_FILE_ENABLED']:
|
if app.config['NOPAQUE_LOG_FILE_ENABLED']:
|
||||||
log_file_dir: Path = app.config['NOPAQUE_LOG_FILE_DIR']
|
if not os.path.exists(app.config['NOPAQUE_LOG_FILE_DIR']):
|
||||||
log_file_level: str | None = app.config['NOPAQUE_LOG_FILE_LEVEL']
|
os.mkdir(app.config['NOPAQUE_LOG_FILE_DIR'])
|
||||||
if not log_file_dir.exists():
|
|
||||||
log_file_dir.mkdir()
|
|
||||||
rotating_file_handler = RotatingFileHandler(
|
rotating_file_handler = RotatingFileHandler(
|
||||||
log_file_dir / 'nopaque.log',
|
os.path.join(app.config['NOPAQUE_LOG_FILE_DIR'], 'nopaque.log'), # noqa
|
||||||
maxBytes=10_240,
|
maxBytes=10_240,
|
||||||
backupCount=10
|
backupCount=10
|
||||||
)
|
)
|
||||||
rotating_file_handler.setFormatter(log_formatter)
|
rotating_file_handler.setFormatter(formatter)
|
||||||
if log_file_level is not None:
|
rotating_file_handler.setLevel(app.config['NOPAQUE_LOG_FILE_LEVEL']) # noqa
|
||||||
rotating_file_handler.setLevel(log_file_level)
|
|
||||||
app.logger.addHandler(rotating_file_handler)
|
app.logger.addHandler(rotating_file_handler)
|
||||||
|
|
||||||
if app.config['NOPAQUE_PROXY_FIX_ENABLED']:
|
if app.config['NOPAQUE_PROXY_FIX_ENABLED']:
|
||||||
@ -160,14 +168,3 @@ class Config:
|
|||||||
x_prefix=app.config['NOPAQUE_PROXY_FIX_X_PREFIX'],
|
x_prefix=app.config['NOPAQUE_PROXY_FIX_X_PREFIX'],
|
||||||
x_proto=app.config['NOPAQUE_PROXY_FIX_X_PROTO']
|
x_proto=app.config['NOPAQUE_PROXY_FIX_X_PROTO']
|
||||||
)
|
)
|
||||||
|
|
||||||
if app.config['NOPAQUE_IS_PRIMARY_INSTANCE']:
|
|
||||||
app.config['JOBS'].append(
|
|
||||||
{
|
|
||||||
"id": "daemon",
|
|
||||||
"func": "app.daemon:daemon",
|
|
||||||
"args": (app,),
|
|
||||||
"trigger": "interval",
|
|
||||||
"seconds": 3,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# Environment variables used by the Docker db service. #
|
# Environment variables to configure the db service in docker-compose.yml. #
|
||||||
# #
|
# #
|
||||||
# More information about the environment variables can be found here: #
|
# More information about the environment variables can be found here: #
|
||||||
# https://hub.docker.com/_/postgres #
|
# https://hub.docker.com/_/postgres #
|
||||||
|
@ -1,55 +1,62 @@
|
|||||||
# This file is not meant to be modified, use the following files instead:
|
# The docker-compose.yml file is not meant to be modified itself.
|
||||||
# - `.env`: Environment variables available within Docker Compose config files.
|
# Instead use the following files for configurations:
|
||||||
# - `db.env`: Environment variables for the database service.
|
# - .env: Environment variables for the docker-compose.yml file.
|
||||||
# - `nopaque.env`: Environment variables for the nopaque service.
|
# - db.env: Environment variables for the database service.
|
||||||
# - `docker-compose.override.yml`: Override the docker-compose.yml file.
|
# - nopaque.env: Environment variables for the nopaque service.
|
||||||
# - The `docker-compose` directory includes examples for this.
|
# - 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:
|
||||||
nopaque:
|
default:
|
||||||
attachable: true
|
name: "${DOCKER_DEFAULT_NETWORK_NAME:-nopaque}"
|
||||||
driver: "overlay"
|
|
||||||
name: "${NOPAQUE_DOCKER_NETWORK_NAME}"
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
db:
|
db:
|
||||||
env_file: "db.env"
|
env_file: db.env
|
||||||
image: "postgres:11"
|
image: postgres:11
|
||||||
networks:
|
restart: unless-stopped
|
||||||
- "nopaque"
|
|
||||||
restart: "unless-stopped"
|
|
||||||
volumes:
|
volumes:
|
||||||
- "./volumes/db/data:/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
|
||||||
networks:
|
restart: unless-stopped
|
||||||
- "nopaque"
|
|
||||||
restart: "unless-stopped"
|
|
||||||
volumes:
|
volumes:
|
||||||
- "./volumes/mq/data:/data"
|
- type: bind
|
||||||
|
source: "${DOCKER_MQ_SERVICE_DATA_VOLUME_SOURCE_PATH:-./volumes/mq/data}"
|
||||||
|
target: "/data"
|
||||||
|
|
||||||
nopaque:
|
nopaque:
|
||||||
build: .
|
build: .
|
||||||
depends_on:
|
depends_on:
|
||||||
- "db"
|
- db
|
||||||
- "mq"
|
- mq
|
||||||
env_file:
|
env_file:
|
||||||
- "nopaque.env"
|
- nopaque.env
|
||||||
environment:
|
environment:
|
||||||
# DANGER: Don't change the following environment variables within a
|
# This section overrides the values set in the nopaque.env file. Do not
|
||||||
# Docker Compose config file, use the `.env` file instead.
|
# override the environment variables in a docker-compose.override.yml
|
||||||
HOST_UID: "${HOST_UID}"
|
# file unless you really know what you are doing.
|
||||||
HOST_GID: "${HOST_GID}"
|
- NOPAQUE_UID=${HOST_UID}
|
||||||
HOST_DOCKER_GID: "${HOST_DOCKER_GID}"
|
- NOPAQUE_GID=${HOST_GID}
|
||||||
NOPAQUE_DATA_PATH: "${HOST_NOPAQUE_DATA_PATH}"
|
- DOCKER_GID=${HOST_DOCKER_GID}
|
||||||
NOPAQUE_DOCKER_NETWORK_NAME: "${NOPAQUE_DOCKER_NETWORK_NAME}"
|
- NOPAQUE_DATA_PATH=${DOCKER_NOPAQUE_SERVICE_DATA_VOLUME_SOURCE_PATH}
|
||||||
image: "nopaque:latest"
|
- NOPAQUE_DOCKER_NETWORK_NAME=${DOCKER_DEFAULT_NETWORK_NAME:-nopaque}
|
||||||
networks:
|
- NOPAQUE_LOGS_PATH=/home/nopaque/logs
|
||||||
- "nopaque"
|
image: nopaque:latest
|
||||||
restart: "unless-stopped"
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
- type: bind
|
||||||
# DANGER: Don't change the following mount within a Docker Compose
|
source: "/var/run/docker.sock"
|
||||||
# config file, use the `.env` file instead.
|
target: "/var/run/docker.sock"
|
||||||
- "${HOST_NOPAQUE_DATA_PATH}:${HOST_NOPAQUE_DATA_PATH}"
|
# 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"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
services:
|
services:
|
||||||
nopaque:
|
nopaque:
|
||||||
environment:
|
environment:
|
||||||
FLASK_DEBUG: "True"
|
- FLASK_DEBUG=True
|
||||||
ports:
|
ports:
|
||||||
- "5000:5000"
|
- "5000:5000"
|
||||||
volumes:
|
volumes:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
services:
|
services:
|
||||||
nopaque:
|
nopaque:
|
||||||
environment:
|
environment:
|
||||||
NOPAQUE_IS_PRIMARY_INSTANCE: "False"
|
- NOPAQUE_IS_PRIMARY_INSTANCE=False
|
||||||
|
@ -6,26 +6,29 @@ networks:
|
|||||||
services:
|
services:
|
||||||
nopaque:
|
nopaque:
|
||||||
environment:
|
environment:
|
||||||
NOPAQUE_PROXY_FIX_ENABLED: "True"
|
- NOPAQUE_PROXY_FIX_ENABLED=True
|
||||||
NOPAQUE_PROXY_FIX_X_FOR: "1"
|
- NOPAQUE_PROXY_FIX_X_FOR=1
|
||||||
NOPAQUE_PROXY_FIX_X_HOST: "1"
|
- NOPAQUE_PROXY_FIX_X_HOST=1
|
||||||
NOPAQUE_PROXY_FIX_X_PORT: "1"
|
- NOPAQUE_PROXY_FIX_X_PORT=1
|
||||||
NOPAQUE_PROXY_FIX_X_PREFIX: "0"
|
- NOPAQUE_PROXY_FIX_X_PREFIX=0
|
||||||
NOPAQUE_PROXY_FIX_X_PROTO: "1"
|
- NOPAQUE_PROXY_FIX_X_PROTO=1
|
||||||
labels:
|
labels:
|
||||||
|
- "traefik.docker.network=traefik"
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
# HTTP
|
### <http> ###
|
||||||
- "traefik.http.routers.http-nopaque.entrypoints=http"
|
- "traefik.http.routers.http-nopaque.entrypoints=http"
|
||||||
- "traefik.http.routers.http-nopaque.middlewares=redirect-to-https@file"
|
- "traefik.http.routers.http-nopaque.middlewares=redirect-to-https@file"
|
||||||
# Replace <nopaque-domain> with your domain
|
# Replace <nopaque-domain> with your domain
|
||||||
- "traefik.http.routers.http-nopaque.rule=Host(`<nopaque-domain>`)"
|
- "traefik.http.routers.http-nopaque.rule=Host(`<nopaque-domain>`)"
|
||||||
# HTTPS
|
### </http> ###
|
||||||
|
### <https> ###
|
||||||
- "traefik.http.routers.https-nopaque.entrypoints=https"
|
- "traefik.http.routers.https-nopaque.entrypoints=https"
|
||||||
- "traefik.http.routers.https-nopaque.middlewares=hsts-header@file"
|
- "traefik.http.routers.https-nopaque.middlewares=hsts-header@file"
|
||||||
# Replace <nopaque-domain> with your domain
|
# Replace <nopaque-domain> with your domain
|
||||||
- "traefik.http.routers.https-nopaque.rule=Host(`<nopaque-domain>`)"
|
- "traefik.http.routers.https-nopaque.rule=Host(`<nopaque-domain>`)"
|
||||||
- "traefik.http.routers.https-nopaque.tls.certresolver=<CERTRESOLVER>"
|
- "traefik.http.routers.https-nopaque.tls.certresolver=<CERTRESOLVER>"
|
||||||
- "traefik.http.routers.https-nopaque.tls.options=intermediate@file"
|
- "traefik.http.routers.https-nopaque.tls.options=intermediate@file"
|
||||||
|
### </https> ###
|
||||||
networks:
|
networks:
|
||||||
- "nopaque"
|
- default
|
||||||
- "traefik"
|
- traefik
|
||||||
|
@ -7,48 +7,25 @@ CHECK_MARK="\xE2\x9C\x93"
|
|||||||
CROSS_MARK="\xE2\x9D\x8C"
|
CROSS_MARK="\xE2\x9D\x8C"
|
||||||
|
|
||||||
|
|
||||||
# Check if necessary environment variables are set
|
if [[ "${NOPAQUE_UID}" == "0" ]]; then
|
||||||
if [[ -z "${HOST_DOCKER_GID}" ]]; then
|
|
||||||
echo "Environment variable \"HOST_DOCKER_GID\" not set."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "${HOST_UID}" ]]; then
|
|
||||||
echo "Environment variable \"HOST_UID\" not set."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z "${HOST_GID}" ]]; then
|
|
||||||
echo "Environment variable \"HOST_GID\" not set."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
# Check if the UID or GID are set to "0" (root). We want an unprivileged user.
|
|
||||||
if [[ "${HOST_UID}" == "0" ]]; then
|
|
||||||
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
|
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
|
||||||
echo "\"0\" is not allowed for HOST_UID"
|
echo "Running as root is not allowed"
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${HOST_GID}" == "0" ]]; then
|
|
||||||
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
|
|
||||||
echo "\"0\" is not allowed for HOST_GID"
|
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
echo "Set container UID and GIDs to match the host system..."
|
echo "Set container UID and GIDs to match the host system..."
|
||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Update docker GID #
|
# docker GID #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
DOCKER_GID=$(getent group docker | cut -d: -f3)
|
if [[ "${DOCKER_GID}" == "$(getent group docker | cut -d: -f3)" ]]; then
|
||||||
if [[ "${DOCKER_GID}" == "${HOST_DOCKER_GID}" ]]; then
|
|
||||||
echo -n "- docker GID is already matching..."
|
echo -n "- docker GID is already matching..."
|
||||||
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
||||||
else
|
else
|
||||||
echo -n "- Updating docker GID (${DOCKER_GID} -> ${HOST_DOCKER_GID})... "
|
echo -n "- Updating docker GID ($(getent group docker | cut -d: -f3) -> ${DOCKER_GID})... "
|
||||||
groupmod --gid "${HOST_DOCKER_GID}" docker > /dev/null
|
groupmod --gid "${DOCKER_GID}" docker > /dev/null
|
||||||
if [[ "${?}" == "0" ]]; then
|
if [[ "${?}" == "0" ]]; then
|
||||||
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
||||||
else
|
else
|
||||||
@ -59,16 +36,16 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Update nopaque GID #
|
# nopaque GID #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
NOPAQUE_GID=$(id -g nopaque)
|
if [[ "${NOPAQUE_GID}" == "$(id -g nopaque)" ]]; then
|
||||||
if [[ "${NOPAQUE_GID}" == "${HOST_GID}" ]]; then
|
|
||||||
echo -n "- nopaque GID is already matching..."
|
echo -n "- nopaque GID is already matching..."
|
||||||
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
||||||
else
|
else
|
||||||
echo -n "- Updating nopaque GID (${NOPAQUE_GID} -> ${HOST_GID})... "
|
echo -n "- Updating nopaque GID ($(id -g nopaque) -> ${NOPAQUE_GID})... "
|
||||||
groupmod --gid "${HOST_GID}" nopaque > /dev/null
|
groupmod --gid "${NOPAQUE_GID}" nopaque > /dev/null
|
||||||
if [[ "${?}" == "0" ]]; then
|
if [[ "${?}" == "0" ]]; then
|
||||||
|
HAS_NOPAQUE_GID_CHANGED=true
|
||||||
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
||||||
else
|
else
|
||||||
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
|
echo -e "${RED_COLOR}${CROSS_MARK}${NO_COLOR}"
|
||||||
@ -87,15 +64,14 @@ fi
|
|||||||
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Update nopaque UID #
|
# nopaque UID #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
NOPAQUE_UID=$(id -u nopaque)
|
if [[ "${NOPAQUE_UID}" == "$(id -u nopaque)" ]]; then
|
||||||
if [[ "${NOPAQUE_UID}" == "${HOST_UID}" ]]; then
|
|
||||||
echo -n "- nopaque UID is already matching..."
|
echo -n "- nopaque UID is already matching..."
|
||||||
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
||||||
else
|
else
|
||||||
echo -n "- Updating nopaque UID (${NOPAQUE_UID} -> ${HOST_UID})... "
|
echo -n "- Updating nopaque UID ($(id -u nopaque) -> ${NOPAQUE_UID})... "
|
||||||
usermod --uid "${HOST_UID}" nopaque > /dev/null
|
usermod --uid "${NOPAQUE_UID}" nopaque > /dev/null
|
||||||
if [[ "${?}" == "0" ]]; then
|
if [[ "${?}" == "0" ]]; then
|
||||||
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
echo -e "${GREEN_COLOR}${CHECK_MARK}${NO_COLOR}"
|
||||||
else
|
else
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
##############################################################################
|
##############################################################################
|
||||||
# Environment variables used by nopaque. #
|
# 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 #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
|
|
||||||
|
|
||||||
@ -7,9 +11,6 @@
|
|||||||
# Flask #
|
# Flask #
|
||||||
# https://flask.palletsprojects.com/en/1.1.x/config/ #
|
# https://flask.palletsprojects.com/en/1.1.x/config/ #
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# DEFAULT: /
|
|
||||||
# APPLICATION_ROOT=
|
|
||||||
|
|
||||||
# CHOOSE ONE: http, https
|
# CHOOSE ONE: http, https
|
||||||
# DEFAULT: http
|
# DEFAULT: http
|
||||||
# PREFERRED_URL_SCHEME=
|
# PREFERRED_URL_SCHEME=
|
||||||
@ -113,10 +114,10 @@ NOPAQUE_ADMIN=
|
|||||||
# DEFAULT: /mnt/nopaque
|
# DEFAULT: /mnt/nopaque
|
||||||
# NOTES:
|
# NOTES:
|
||||||
# - This must be a network share and it must be available on all
|
# - This must be a network share and it must be available on all
|
||||||
# Docker Swarm nodes, mounted to the same path.
|
# 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
|
# - When running with Docker Compose, this gets overwritten in the
|
||||||
# `docker-compose.yml` file with the value of the `HOST_NOPAQUE_DATA_PATH`
|
# `docker-compose.yml` file
|
||||||
# environment variable from the `.env` file.
|
|
||||||
# NOPAQUE_DATA_PATH=
|
# NOPAQUE_DATA_PATH=
|
||||||
|
|
||||||
# CHOOSE ONE: False, True
|
# CHOOSE ONE: False, True
|
||||||
@ -141,22 +142,30 @@ NOPAQUE_DOCKER_REGISTRY_PASSWORD=
|
|||||||
# DEFAULT: [%(asctime)s] %(levelname)s in %(pathname)s (function: %(funcName)s, line: %(lineno)d): %(message)s
|
# DEFAULT: [%(asctime)s] %(levelname)s in %(pathname)s (function: %(funcName)s, line: %(lineno)d): %(message)s
|
||||||
# NOPAQUE_LOG_FORMAT=
|
# NOPAQUE_LOG_FORMAT=
|
||||||
|
|
||||||
|
# DEFAULT: INFO
|
||||||
|
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
|
||||||
|
# NOPAQUE_LOG_LEVEL=
|
||||||
|
|
||||||
# CHOOSE ONE: False, True
|
# CHOOSE ONE: False, True
|
||||||
# DEFAULT: False
|
# DEFAULT: True
|
||||||
# NOPAQUE_LOG_FILE_ENABLED=
|
# NOPAQUE_LOG_FILE_ENABLED=
|
||||||
|
|
||||||
# DEFAULT: /var/log/nopaque
|
# DEFAULT: <nopaque-basedir>/logs
|
||||||
# NOPAQUE_LOG_FILE_DIR=
|
# NOTES:
|
||||||
|
# - Use `.` as <nopaque-basedir>
|
||||||
|
# - When running with Docker Compose, this gets overwritten in the
|
||||||
|
# `docker-compose.yml` file
|
||||||
|
# NOPAQUE_LOGS_PATH=
|
||||||
|
|
||||||
# DEFAULT: DEBUG if FLASK_DEBUG == True else WARNING
|
# DEFAULT: NOPAQUE_LOG_LEVEL
|
||||||
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
|
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
|
||||||
# NOPAQUE_LOG_FILE_LEVEL=
|
# NOPAQUE_LOG_FILE_LEVEL=
|
||||||
|
|
||||||
# CHOOSE ONE: False, True
|
# CHOOSE ONE: False, True
|
||||||
# DEFAULT: True
|
# DEFAULT: False
|
||||||
# NOPAQUE_LOG_STDERR_ENABLED=
|
# NOPAQUE_LOG_STDERR_ENABLED=
|
||||||
|
|
||||||
# DEFAULT: DEBUG if FLASK_DEBUG == True else WARNING
|
# DEFAULT: NOPAQUE_LOG_LEVEL
|
||||||
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
|
# CHOOSE ONE: CRITICAL, ERROR, WARNING, INFO, DEBUG
|
||||||
# NOPAQUE_LOG_STDERR_LEVEL=
|
# NOPAQUE_LOG_STDERR_LEVEL=
|
||||||
|
|
||||||
|
19
wsgi.py
19
wsgi.py
@ -8,6 +8,20 @@ from flask import Flask # noqa
|
|||||||
from typing import Any, Dict # noqa
|
from typing import Any, Dict # noqa
|
||||||
from app import create_app, db, scheduler, socketio # noqa
|
from app import create_app, db, scheduler, socketio # noqa
|
||||||
from app import models # noqa
|
from app import models # noqa
|
||||||
|
# from app.models import (
|
||||||
|
# Avatar,
|
||||||
|
# Corpus,
|
||||||
|
# CorpusFile,
|
||||||
|
# CorpusFollowerAssociation,
|
||||||
|
# CorpusFollowerRole,
|
||||||
|
# Job,
|
||||||
|
# JobInput,
|
||||||
|
# JobResult,
|
||||||
|
# Role,
|
||||||
|
# TesseractOCRPipelineModel,
|
||||||
|
# SpaCyNLPPipelineModel,
|
||||||
|
# User
|
||||||
|
# ) # noqa
|
||||||
|
|
||||||
|
|
||||||
app: Flask = create_app()
|
app: Flask = create_app()
|
||||||
@ -34,8 +48,11 @@ def make_shell_context() -> Dict[str, Any]:
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if app.config['NOPAQUE_IS_PRIMARY_INSTANCE']:
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
|
if app.config['NOPAQUE_IS_PRIMARY_INSTANCE']:
|
||||||
|
for corpus in models.Corpus.query.filter(models.Corpus.num_analysis_sessions > 0).all():
|
||||||
|
corpus.num_analysis_sessions = 0
|
||||||
|
db.session.commit()
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
socketio.run(app, host='0.0.0.0')
|
socketio.run(app, host='0.0.0.0')
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user