Initial commit

This commit is contained in:
Scott Idem
2023-02-22 16:40:16 -05:00
parent d18de5507b
commit cc767aac25
52 changed files with 2588 additions and 0 deletions

45
.gitignore vendored
View File

@@ -11,6 +11,7 @@ dist/
*.class
# Compiled Python bytecode
__pycache__/
*.py[cod]
# Log files
@@ -48,3 +49,47 @@ Thumbs.db
*.mov
*.wmv
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
environment/
*.bak
.directory
backups/
bak/
downloads/
hold/
log/
# logs/
logs/ae_api/
logs/ae_app/
logs/apache2/
logs/mailman2/
logs/php7/
logs/web/
tmp/
temp/
srv/aether_api/
srv/aether_app/
srv/hosted_files/
srv/hosted_tmp/
srv/html_php/
srv/mailman2/
srv/mariadb/
srv/nextcloud/
srv/oneskyit_site/
srv/static_files/
srv/aether_api_link/
srv/aether_app_link/
srv/hosted_files_dev_link/
srv/hosted_files_link/
srv/hosted_tmp_dev_link/
srv/hosted_tmp_link/

57
README.md Normal file
View File

@@ -0,0 +1,57 @@
This can be used to create a Docker server cluster for the Aether App using Flask, Aether API using FastAPI.
## Common:
* conf/ = All config files
* logs/ = All log files
* srv/ = All files and data directories that are being served up in some way.
* srv/hosted_files = All hashed hosted files (/mnt/data_drive/srv/data/osit_app/hosted_files_dev/)
* srv/static_files = All static files
* ---
* srv/aether_api = Aether API
* srv/aether_app = Aether App
* ---
* srv/html_php = The default HTML and PHP directory
* srv/oneskyit_site = One Sky IT, LLC main site
* ---
* srv/mailman2 = All Mailman2 files
* srv/mariadb = All MariaDB database files
* srv/nextcloud = All Nextcloud app files
## Servics:
nginx
php
gunicorn
mariadb
phpmyadmin
redis
postfix?
mailman?
Nextcloud???
Syncthing???
restic???
memcached???
## Setup
## Check for in use services and ports
Note that the Aether FastAPI will hang if redis is not found.
sudo systemctl status mariadb.services
sudo systemctl status nginx.service
sudo systemctl status php-fpm.service
sudo systemctl status postfix.service
sudo systemctl status redis.service
### Create links to Aether API and app directories
Make sure the docker-compose.yml file is updated with the correct paths.
ln -s /home/scott/OSIT_dev/aether_api_fastapi /home/scott/OSIT_dev/aether_container_env/srv/aether_api_link
ln -s /home/scott/OSIT_dev/aether_app /home/scott/OSIT_dev/aether_container_env/srv/aether_app_link
ln -s /mnt/data_drive/srv/data/osit_app/hosted_files /home/scott/OSIT_dev/aether_container_env/srv/hosted_files_link
ln -s /mnt/data_drive/srv/data/osit_app/hosted_files_dev /home/scott/OSIT_dev/aether_container_env/srv/hosted_files_dev_link
ln -s /mnt/data_drive/srv/data/osit_app/hosted_tmp /home/scott/OSIT_dev/aether_container_env/srv/hosted_tmp_link
ln -s /mnt/data_drive/srv/data/osit_app/hosted_tmp_dev /home/scott/OSIT_dev/aether_container_env/srv/hosted_tmp_dev_link

View File

@@ -0,0 +1,11 @@
FROM tiangolo/uvicorn-gunicorn-fastapi:latest
# FROM tiangolo/uvicorn-gunicorn-fastapi:python3.10
LABEL maintainer="Scott Idem <scott.idem@oneskyit.com>"
WORKDIR /srv/aether_api
COPY conf/aether_fastapi_test_requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt
CMD ["gunicorn", "--conf", "/conf/gunicorn_fastapi_conf.py"]

View File

@@ -0,0 +1,10 @@
FROM python:3
LABEL maintainer="Scott Idem <scott.idem@oneskyit.com>"
WORKDIR /srv/aether_app
COPY conf/aether_flask_requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt
CMD ["gunicorn", "--conf", "/conf/gunicorn_flask_conf.py"]

3
aether_nginx.Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
FROM nginx:latest
LABEL maintainer="Scott Idem <scott.idem@oneskyit.com>"

95
conf/aether_api_config.py Normal file
View File

@@ -0,0 +1,95 @@
# Configuration file for this FastAPI app.
import os
from pydantic import AnyHttpUrl, BaseSettings, EmailStr, HttpUrl, PostgresDsn, validator
from typing import Any, Dict, List, Optional, Union
# ### ### #
class Settings(BaseSettings):
AETHER_CFG = {}
AETHER_CFG['id'] = os.getenv('AE_CFG_ID', None)
AETHER_CFG['api_id'] = os.getenv('AE_API_CFG_ID', None)
APP_NAME: str = "Aether API (FastAPI)"
SUPER_EMAIL: EmailStr = 'Aether.Super@oneskyit.com'
# Database Connection
DB = {}
DB['server'] = os.getenv('AE_DB_SERVER', None) # 'linode.oneskyit.com' # linode.oneskyit.com, vpn-linode linode.oneskyit.local
DB['port'] = os.getenv('AE_DB_PORT', None) # '3306' # default = 3306
DB['name'] = os.getenv('AE_DB_NAME', None) # 'aether_dev' #onesky_ams_dev
DB['username'] = os.getenv('AE_DB_USERNAME', None) # 'osit_aether' # 'onesky_aether'
DB['password'] = os.getenv('AE_DB_PASSWORD', None) #
print(DB)
SQLALCHEMY_DB_URI = 'mysql://'+DB['username']+':'+DB['password']+'@'+DB['server']+'/'+DB['name']
# Aether API log files paths
LOG_PATH = {}
LOG_PATH['app'] = '/logs/aether_api.log' # 'admin/log/app.log', '../../logs/aether_api.log'
LOG_PATH['app_warning'] = '/logs/aether_api_warning.log' # 'admin/log/app_warning.log' '../../logs/aether_api_warning.log'
# Redis
REDIS = {}
REDIS['server'] = os.getenv('AE_REDIS_SERVER', None) # 'redis' # 'localhost' 'redis'
REDIS['port'] = os.getenv('AE_REDIS_PORT', None) # '6379'
# Send SMTP Email
SMTP = {}
# Server Hosted File Paths
FILES_PATH = {}
# CORS Origins
ORIGINS_REGEX = '(https://.*\.oneskyit\.com)|(http://.*\.oneskyit\.com)|(http://.*\.oneskyit\.com:8181)|(https://.*\.oneskyit\.com:8443)|(http://.*\.oneskyit\.local)|(http://.*\.oneskyit\.local:5000)|(http://.*.localhost)|(http://.*.localhost:5000)|(http://.*.localhost:8181)'
ORIGINS = [
'https://oneskyit.com',
'http://app-local.oneskyit.com',
'http://192.168.32.20:3000',
'http://192.168.32.20:8080',
'http://localhost',
'http://localhost:3000',
'http://localhost:5000',
'http://localhost:8080',
'http://localhost:7800',
'http://fastapi.localhost',
'http://svelte.oneskyit.local:5555',
'http://connect.localhost:5000', # Using localhost
'http://dev-svelte.oneskyit.local:5555',
'http://lci.internal:5000', # Using internal; just in case guess before LCI
'http://lci.oneskyit.internal:5000', # Using internal; just in case guess before LCI
'http://lci.oneskyit.internal', # Using internal; just in case guess before LCI
]
# HTTP Status Dict List
HTTP_STATUS_LI = {}
HTTP_STATUS_LI[200] = { 'name': 'OK', 'message': 'The request has succeeded.' }
HTTP_STATUS_LI[400] = { 'name': 'Bad Request', 'message': 'The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications.' }
HTTP_STATUS_LI[401] = { 'name': 'Unauthorized', 'message': 'The server could not verify that you are authorized to access the URL requested. You either supplied the wrong credentials (e.g. a bad password), or your browser does not understand how to supply the credentials required.' }
HTTP_STATUS_LI[402] = { 'name': '?Request Failed?', 'message': '??The parameters were valid but the request failed.??' }
HTTP_STATUS_LI[403] = { 'name': 'Forbidden', 'message': 'The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. If the request method was not HEAD and the server wishes to make public why the request has not been fulfilled, it SHOULD describe the reason for the refusal in the entity. If the server does not wish to make this information available to the client, the status code 404 (Not Found) can be used instead.' }
HTTP_STATUS_LI[404] = { 'name': 'Not Found', 'message': 'The requested resource does not exist.' }
HTTP_STATUS_LI[409] = { 'name': 'Conflict', 'message': 'The request conflicts with another request (perhaps due to using the same idempotent key).' }
HTTP_STATUS_LI[429] = { 'name': 'Too Many Requests', 'message': 'Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.' }
HTTP_STATUS_LI[500] = { 'name': 'Internal Server Error', 'message': 'The server encountered an unexpected condition which prevented it from fulfilling the request.' }
HTTP_STATUS_LI[501] = { 'name': 'Not Implemented', 'message': 'The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource.' }
HTTP_STATUS_LI[502] = { 'name': 'Bad Gateway', 'message': 'The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in attempting to fulfill the request.' }
HTTP_STATUS_LI[503] = { 'name': 'Service Unavailable', 'message': 'The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.' }
HTTP_STATUS_LI[504] = { 'name': 'Gateway Timeout', 'message': 'The server, while acting as a gateway or proxy, did not receive a timely response from the upstream server specified by the URI (e.g. HTTP, FTP, LDAP) or some other auxiliary server (e.g. DNS) it needed to access in attempting to complete the request.' }
settings = Settings()

187
conf/aether_app_config.py Normal file
View File

@@ -0,0 +1,187 @@
# Configuration file for this Flask app.
import os
# ### ### #
## Builtin Python Flask configuration options
# General Flask options
FLASK_ENV = 'development' # None, 'backup', 'default', 'development', 'production', 'testing'
ENV = 'development' # None, 'backup', 'default', 'development', 'production', 'testing'
DEBUG = True
TESTING = True
SECRET_KEY = '\x08}\xe1q?\xb2\x16o9\xf1\x1d\xc7\xa8\xfb!\xff' # Generate a new key with: # python -c 'import os; print(os.urandom(16))'
# SESSION_COOKIE_NAME = 'session'
# SESSION_COOKIE_DOMAIN = '.onesky.com'
# SESSION_COOKIE_PATH = None
# SESSION_COOKIE_HTTPONLY = True
# SESSION_COOKIE_SECURE = False
# SESSION_COOKIE_SAMESITE = None
# SESSION_REFRESH_EACH_REQUEST = True
# Client browser session options
# 3600 is 1 hour, 28800 is 8 hours
# 86400 is 24 hours, 172800 is 48 hours
# 1209600 is 14 days, 2678400 is 31 days
# 7862400 is 91 days or 13 weeks (.25 year)
# 31536000 is 365 days
# 33868800 is 9408 hours or 392 days
PERMANENT_SESSION_LIFETIME = 3600
SESSION_REFRESH_EACH_REQUEST = True
# Files and caching
# SERVER_NAME = ''
# UPLOAD_FOLDER = ''
MAX_CONTENT_LENGTH = 5120 * 1024 * 1024 # 5 GB
SEND_FILE_MAX_AGE_DEFAULT = 3 # default 43200 (in seconds), 1800 = 30 minutes
CACHE_TYPE = 'SimpleCache'
CACHE_DEFAULT_TIMEOUT = 1
JSONIFY_PRETTYPRINT_REGULAR = True
## MySQL and SQL Alchemy
# pool_size is set to 100. The default is 5 connections
# pool_recyle after 10 minutes (600 seconds). MySQL is set to timeout after 15 minutes (900 seconds)
# SQLALCHEMY_ENGINE_OPTIONS = {'pool_size' : 100, 'pool_recycle' : 120, 'pool_pre_ping': True}
POOL_SIZE = 25
POOL_RECYCLE = 60
POOL_PRE_PING = True
ECHO = False
ECHO_POOL = False
ISOLATION_LEVEL = 'READ COMMITTED'
# ### ### #
### Aether configration options
AETHER_CFG = {}
## General Aether configuration options
AETHER_CFG['id'] = 5 # Aether config ID
## Aether Flask app (not a specific browser client) configuration (pull from "cfg_flask" table)
AETHER_CFG['app'] = {}
AETHER_CFG['app']['id'] = os.getenv('AE_APP_CFG_ID', None) # Flask app config ID
AETHER_CFG['app']['name']: str = "Aether App (Flask)" # Not set in DB???
AETHER_CFG['app']['version']: str = '3.6.0 2022-10-04' # Not set in DB???
AETHER_CFG['app']['email']: str = 'Info@OneSkyIT.com'
AETHER_CFG['app']['env'] = None # None, 'backup', 'default', 'development', 'production', 'testing'; Not set in DB???
AETHER_CFG['app']['mode'] = None # None, 'default', 'native', 'onsite'; Not set in DB???
AETHER_CFG['app']['ux_mode'] = None # In this case it is the same as mode. None, 'default', 'native', 'onsite'
AETHER_CFG['app']['theme'] = None # For future use or at least for 'light', 'dark', 'contrast' themes?
AETHER_CFG['app']['path_hosted_files_root']: str = None
AETHER_CFG['app']['path_hosted_tmp_root']: str = None
AETHER_CFG['app']['path_hosted_qr_images']: str = None # Will contain only QR code image files
## Aether API for Flask app configuration (pull from "cfg_flask" table)
AETHER_CFG['api'] = {}
AETHER_CFG['api']['protocol'] = os.getenv('AE_API_PROTOCOL', 'https') # 'https' # https
AETHER_CFG['api']['server'] = os.getenv('AE_API_SERVER', None) # 'dev-api.oneskyit.com' # linode.oneskyit.com vpn-linode linode.oneskyit.local
AETHER_CFG['api']['port'] = os.getenv('AE_API_PORT', '443') # '443' # default = 3306
AETHER_CFG['api']['path'] = os.getenv('AE_API_PATH', '') # ''
AETHER_CFG['api']['secret_key'] = os.getenv('AE_API_SECRET_KEY', None)
AETHER_CFG['api']['protocol_backup'] = 'http' # https
AETHER_CFG['api']['server_backup'] = 'dev-fastapi.oneskyit.local' # linode.oneskyit.com vpn-linode linode.oneskyit.local
AETHER_CFG['api']['port_backup'] = '5005' # default = 3306
AETHER_CFG['api']['path_backup'] = ''
AETHER_CFG['api']['secret_key_backup'] = 'the secret backup key'
AETHER_CFG['api']['temporary_token'] = {}
AETHER_CFG['api']['temporary_token']['token'] = None
AETHER_CFG['api']['temporary_token']['expire_on'] = None
## Aether database connection (pull from "cfg" table)
AETHER_CFG['db'] = {}
# AETHER_CFG['db']['server'] = 'linode.oneskyit.com' # vpn-linode linode.oneskyit.local
# AETHER_CFG['db']['port'] = '3306' # default = 3306
# AETHER_CFG['db']['name'] = 'aether_dev' #onesky_ams_dev
# AETHER_CFG['db']['username'] = 'osit_aether'
# AETHER_CFG['db']['password'] = ''
# AETHER_CFG['db']['uri'] = 'mysql://'+AETHER_CFG['db']['username']+':'+AETHER_CFG['db']['password']+'@'+AETHER_CFG['db']['server']+'/'+AETHER_CFG['db']['name'] # For SQL Alchemy DB connection
## Aether IDB client browser (pull from "cfg_flask" table)
AETHER_CFG['idb'] = {}
AETHER_CFG['idb']['name'] = 'osit'
# Aether app log files paths
AETHER_CFG['log_path'] = {}
AETHER_CFG['log_path']['app'] = '/logs/aether_app.log' # 'admin/log/app.log', '../../logs/aether_api.log'
AETHER_CFG['log_path']['app_warning'] = '/logs/aether_app_warning.log' # 'admin/log/app_warning.log' '../../logs/aether_api_warning.log'
## Aether Google's Recaptcha account (for One Sky IT; pull from "cfg" table)
AETHER_CFG['recaptcha'] = {}
AETHER_CFG['recaptcha']['url'] = 'https://www.google.com/recaptcha/api/siteverify'
AETHER_CFG['recaptcha']['secret_key'] = ''
## Aether SMTP email account (pull from "cfg" table)
AETHER_CFG['smtp'] = {}
# AETHER_CFG['smtp']['server'] = 'linode.oneskyit.com'
# AETHER_CFG['smtp']['port'] = '465'
# AETHER_CFG['smtp']['username'] = 'send_mail'
# AETHER_CFG['smtp']['password'] = '$onesky.Send_Mail.2021!'
## Aether Stripe account (for One Sky IT; pull from "cfg" table)
AETHER_CFG['stripe'] = {}
AETHER_CFG['stripe']['api_key'] = ''
AETHER_CFG['stripe']['publishable_key'] = ''
AETHER_CFG['stripe_dev'] = {}
AETHER_CFG['stripe_dev']['api_key'] = ''
AETHER_CFG['stripe_dev']['publishable_key'] = ''
## Aether modules (Event, Fundraising, Person, User, etc)
AETHER_CFG['mod_event'] = {}
AETHER_CFG['mod_event']['onsite_file_ext_change'] = [ 'ppt', 'pptx' ]
# ### ### #
## Legacy options just in case?
# Presentation management configuration options:
ONSITE_FILE_EXT_CHANGE = { 'ppt', 'pptx' }
# Server Hosted File Paths
FILES_PATH = {}
FILES_DIRECTORY = 'files/'
# Reference: https://en.wikipedia.org/wiki/List_of_file_formats
# ALLOWED_EXTENSIONS = set(['apng', 'pdf', 'pdfmac', 'pdfwin', 'png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'zip', 'tar', 'gz', 'tgz', 'xz', 'rar', '7z', 'bz2', '3gp', 'aac', 'ac3', 'flac', 'm4a', 'mp3', 'ogg', 'avi', 'flv', 'm4v', 'mkv', 'mp4', 'mpg', 'mpeg', 'mov', 'qt', 'ts', 'webm', 'docx', 'xlsx', 'pptx', 'pptxmac', 'pptxwin', 'pptm', 'pptmmac', 'pptmwin', 'ppsm', 'ppsmmac', 'ppsmwin', 'ppt', 'pptmac', 'pptwin', 'key', 'keynote', 'odt', 'odp', 'odpmac', 'odpwin', 'ods', 'txt', 'heif', 'heifs', 'heic', 'heics', 'avci', 'avcs', 'avif', 'avifs'])
# ALLOWED_EXTENSIONS_DOCUMENTS = set(['txt', 'rtf', 'docx', 'xlsx', 'odt', 'ods', 'pdf'])
# ALLOWED_EXTENSIONS_IMAGES = set(['apng', 'gif', 'jpg', 'jpeg', 'png', 'svg', 'webp', 'heif', 'heifs', 'heic', 'heics', 'avci', 'avcs', 'avif', 'avifs'])
# ALLOWED_EXTENSIONS_AUDIO = set(['mp3', 'm4a', 'ogg', 'aac', 'flac', 'oga', 'opus', 'wma', 'webm'])
# ALLOWED_EXTENSIONS_VIDEO = set(['mp4', 'webm', 'mkv', 'avi', 'flv', 'mpg', 'mpeg', 'ts', 'ogg', 'mov', 'qt'])
# ALLOWED_EXTENSIONS_PRESENTATIONS = set(['key', 'keynote', 'pdf', 'pdfmac', 'pdfwin', 'ppt', 'pptx', 'pptxmac', 'pptxwin', 'pptm', 'pptmmac', 'pptmwin', 'ppsm', 'ppsmmac', 'ppsmwin', 'odp', 'odpmac', 'odpwin'])
# Google's Recaptcha
# GOOGLE_RECAPTCHA_URL = 'https://www.google.com/recaptcha/api/siteverify'
# GOOGLE_RECAPTCHA_SECRET_KEY = ''
# Keys for Stripe
# STRIPE_API_KEY = ''
# STRIPE_PUBLISHABLE_KEY = ''
# Poster presentation configuration options:
# POSTER_IDLE_TIME = 60000 # in milliseconds; 300 seconds = 5 minutes
# POSTER_HOLD_TIME = 15000 # in milliseconds; 15 seconds
# Badge printing configuration options:
# Path used for event badge QR code images (event_badge.id filenames).
# PATH_EVENT_BADGE_QR_IMAGES_ROOT = '/mnt/data_drive/Work_OneSkyIT/event_badges/qr_images' # Will contain only QR code image files
# TEST_CFG_OPTION = 'This is a test config option'

View File

@@ -0,0 +1,43 @@
import os
# Gunicorn config variables
loglevel = "warning"
accesslog = "/logs/gunicorn_access.log" # "-" # stdout
errorlog = "/logs/gunicorn_error.log" # "-" # stderr
# "logfile" does not seem to actually do anything
# logfile = "/logs/gunicorn.log" # "-" # stderr
bind = "0.0.0.0:5005"
# bind = "unix:/tmp/gunicorn.sock"
worker_tmp_dir = "/dev/shm"
chdir = "/srv/aether_api"
# home = /path/to/environment
wsgi_app = "app.main:app"
# module = "run_server"
# callable = "app"
# plugins = "python"
# default_proc_name = "app.main:app"
# Setting a long timeout since some FastAPI API requests may take a while
timeout = 1200 # default 30; worker process silent then kill and restart
graceful_timeout = 20 # default 30; timeout after restart signal
keepalive = 300 # default 2; setting higher because behind load balancer (nginx)
# Reload does not work correctly with UvicornWorker
# https://github.com/benoitc/gunicorn/issues/2339
# Disable reload if using more than one thread
reload = True
# reload_engine = "poll"
worker_class = "uvicorn.workers.UvicornWorker" # default "sync"
# Works are processes, not threads
# workers = 9 # default 1; use 10ish for production; 2 to 4 times the number of cores
# threads = 1 # default 1; only affects Gthread worker type
workers = os.getenv('AE_API_WORKERS', None)
threads = os.getenv('AE_API_THREADS', None)
# umask = '007'

View File

@@ -0,0 +1,61 @@
anyio==3.6.2
argon2-cffi==21.3.0
argon2-cffi-bindings==21.2.0
asgiref==3.5.2
async-timeout==4.0.2
certifi==2022.9.24
cffi==1.15.1
charset-normalizer==2.1.1
click==8.1.3
Deprecated==1.2.13
dnspython==2.2.1
email-validator==1.3.0
et-xmlfile==1.1.0
fastapi==0.88.0
greenlet==2.0.0
gunicorn==20.1.0
h11==0.14.0
html2text==2020.1.16
httpcore==0.16.2
httptools==0.5.0
httpx==0.23.1
idna==3.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
mysqlclient==2.1.1
numpy==1.23.4
openpyxl==3.0.10
orjson==3.8.1
packaging==21.3
pandas==1.5.2
passlib==1.7.4
Pillow==9.3.0
pycparser==2.21
pydantic==1.10.2
PyJWT==2.6.0
pyparsing==3.0.9
python-dateutil==2.8.2
python-dotenv==0.21.0
python-multipart==0.0.5
pytz==2022.6
PyYAML==6.0
qrcode==7.3.1
redis==4.3.5
requests==2.28.1
rfc3986==1.5.0
six==1.16.0
sniffio==1.3.0
SQLAlchemy==1.4.44
starlette==0.22.0
stripe==5.0.0
typing_extensions==4.4.0
ujson==5.5.0
urllib3==1.26.12
uvicorn==0.18.3
uvloop==0.17.0
watchfiles==0.18.0
watchgod==0.8.2
websockets==10.4
wrapt==1.14.1
xlrd==2.0.1

View File

@@ -0,0 +1,59 @@
import os
# Gunicorn config variables
loglevel = "debug"
# accesslog = "/logs/gunicorn_access.log" # "-" # stdout
errorlog = "/logs/gunicorn_error.log" # "-" # stderr
# "logfile" does not seem to actually do anything
# logfile = "/logs/gunicorn.log" # "-" # stderr
bind = "0.0.0.0:5005"
# bind = "unix:/tmp/gunicorn.sock"
worker_tmp_dir = "/dev/shm"
chdir = "/srv/aether_app"
# home = /path/to/environment
wsgi_app = "run_server:app"
# module = "run_server"
# callable = "app"
# plugins = "python"
# default_proc_name = "run_server:app"
# Setting a longer timeout since some Flask app requests may take a while
timeout = 1200 # default 30; worker process silent then kill and restart
graceful_timeout = 20
keepalive = 300 # default 2; setting higher because behind load balancer (nginx)
# Disable reload if using more than one thread
reload = True
# worker_class = "sync" # default "sync"
# Works are processes, not threads
# workers = 9 # default 1; use 10ish for production; 2 to 4 times the number of cores
# threads = 1 # default 1; only affects Gthread worker type
workers = os.getenv('AE_APP_WORKERS', None)
threads = os.getenv('AE_APP_THREADS', None)
# umask = '007'
# capture_output = True
# default_proc_name = "run_server:app"
# worker_class = "worker_class"
## From FastAPI for reference
# --bind unix:/home/scott/OSIT_dev/aether_api_fastapi/gunicorn.sock
# --umask 007 app.main:app
# --workers 2
# --worker-class uvicorn.workers.UvicornWorker
# --log-level debug
# --access-logfile admin/log/access.log
# --error-logfile admin/log/error.log
# --log-file admin/log/log.log
# --capture-output
# --keep-alive 5
# --reload

View File

@@ -0,0 +1,77 @@
argon2-cffi==21.3.0
# argon2-cffi-bindings==21.2.0
async-timeout==4.0.2
bidict==0.21.4
Brotli==1.0.9
cachelib==0.9.0
certifi==2021.10.8
# cffi==1.15.0
charset-normalizer==2.0.9
click==7.1.2
cssselect2==0.4.1
# Cython==0.29.32
Deprecated==1.2.13
# dnspython==2.1.0
eventlet==0.33.2
Flask==1.1.4
Flask-Caching==2.0.1
Flask-Cors==3.0.10
Flask-MySQLdb==1.0.1
Flask-SocketIO==5.3.2
Flask-SQLAlchemy==2.5.1
Flask-WeasyPrint==0.6
fonttools==4.28.4
gevent==22.10.2
greenlet==2.0.1
gunicorn==20.1.0
html2text==2020.1.16
html5lib==1.1
idna==3.3
itsdangerous==1.1.0
Jinja2==2.11.3
MarkupSafe==2.0.1
mypy==0.930
mypy-extensions==0.4.3
mysqlclient==2.1.0
numpy
packaging==21.3
pandas==1.5.2
passlib==1.7.4
Pillow==9.3.0
pycparser==2.21
# pycrypto==2.6.1
# pycryptodome==3.16.0
pydantic==1.10.2
pydyf==0.1.2
pyparsing==3.0.9
pyphen==0.11.0
python-dateutil==2.8.2
python-engineio==4.3.0
python-socketio==5.5.0
pytz==2021.3
qrcode==7.3.1
redis==4.3.5
requests==2.28.1
# simple-crypt==4.1.7
six==1.16.0
SQLAlchemy==1.4.28
stripe==5.0.0
suds-py3==1.4.5.0
tinycss2==1.1.1
tomli==2.0.0
types-pytz==2022.1.2
types-requests==2.28.10
types-urllib3==1.26.24
typing_extensions==4.4.0
urllib3==1.26.7
uvicorn==0.18.3
# uWSGI==2.0.21
weasyprint==53.4
webencodings==0.5.1
Werkzeug==0.16.1
wrapt==1.13.3
xlrd==2.0.1
xmltodict==0.13.0
# zope.event==4.5.0
# zope.interface==5.4.0
# zopfli==0.1.9

30
conf/certs/cert.pem Normal file
View File

@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFITCCBAmgAwIBAgISBPmBtUqvB3Pj9oVx7V6htPPgMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMjExMTgyMTU0MDRaFw0yMzAyMTYyMTU0MDNaMBkxFzAVBgNVBAMM
Dioub25lc2t5aXQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
6dUxbjUia1KQy8qjr69IfX5zH1MRhlE3R4V85pIUeU09ZrbKgxSaDwNL03EC8aSm
eRAuvuIsPLH4Ol8OSeQ34blI/GipFdhRJgbGsYtKF7gfHFkG1lGvRQcGY7eZXdm7
4EqWRmYxZGBkdos155yhXDgiL67YdhZ6eH+52STjH6JpBOLCM+Aq1ZOpK1LCZ/5h
SWqGJUqSmtwyO0jA/RO8pSpD9AfFSvvOaCLK1McIpue27ODTf6NN1hDAa38A5p3A
0H2cG70uv0W3XclTLyCP7B37+HPTFyS79UIzsAg84eG0kHHVhkzBUf693ip7vK3m
UXkmVR87DvxxRcaqN2IffQIDAQABo4ICSDCCAkQwDgYDVR0PAQH/BAQDAgWgMB0G
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1Ud
DgQWBBSLsdHyqMT+Cxetefauf761+Mh7wjAfBgNVHSMEGDAWgBQULrMXt1hWy65Q
CUDmH6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9y
My5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3Jn
LzAZBgNVHREEEjAQgg4qLm9uZXNreWl0LmNvbTBMBgNVHSAERTBDMAgGBmeBDAEC
ATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNl
bmNyeXB0Lm9yZzCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB1AHoyjFTYty22IOo4
4FIe6YQWcDIThU070ivBOlejUutSAAABhIzy+N8AAAQDAEYwRAIgTEX+382iFK+M
RCyYw6MWnwAu9JqJrsKcEe+i+dzcDlQCIFrml/2Ck6pFzU3pYJimZouQ12kWl9Kk
EXqNRq1qmWJNAHYAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMAAAGE
jPL6YAAABAMARzBFAiAUbLLohaQCm2iYkRoNRvHCXnVDdB5/vmKwhNPfk//3YQIh
AMWwfMywrAUZVhiuahXA6hBp0EjmITSvuqMUDM3t52S4MA0GCSqGSIb3DQEBCwUA
A4IBAQBTk+HzCeJC+4P89DXTNyiqQcCiZVNR+3xMSQJUUkVfpaiam+2OH95CwrS/
b7VJ/ohF5wnxI0iHKbfiQBcmjlX7d8szmlboFWaoFSFq5V6mauQLTFhYIXEsKliH
xzTkvO+aFsRrdWK6aDaGQ3PC21769i/teenQfEGMIemeo2DhKpFabwpjimeSw9Z/
VZ2UycE4A4nH0PyP/004jhNAntMSUpGJjmlEcVHyy1Zj0kkgqYHKunIbhO3REBKh
NWtlePPiaTlQBwtgXM0rL/fuRnyHKNaeKKHg9fK0w3vY5kLD6v6Ga2B0agAh64yL
sikYlzNzdq9geimB/L8+EtV/cEFY
-----END CERTIFICATE-----

61
conf/certs/chain.pem Normal file
View File

@@ -0,0 +1,61 @@
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----

View File

@@ -0,0 +1,91 @@
-----BEGIN CERTIFICATE-----
MIIFITCCBAmgAwIBAgISBPmBtUqvB3Pj9oVx7V6htPPgMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMjExMTgyMTU0MDRaFw0yMzAyMTYyMTU0MDNaMBkxFzAVBgNVBAMM
Dioub25lc2t5aXQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
6dUxbjUia1KQy8qjr69IfX5zH1MRhlE3R4V85pIUeU09ZrbKgxSaDwNL03EC8aSm
eRAuvuIsPLH4Ol8OSeQ34blI/GipFdhRJgbGsYtKF7gfHFkG1lGvRQcGY7eZXdm7
4EqWRmYxZGBkdos155yhXDgiL67YdhZ6eH+52STjH6JpBOLCM+Aq1ZOpK1LCZ/5h
SWqGJUqSmtwyO0jA/RO8pSpD9AfFSvvOaCLK1McIpue27ODTf6NN1hDAa38A5p3A
0H2cG70uv0W3XclTLyCP7B37+HPTFyS79UIzsAg84eG0kHHVhkzBUf693ip7vK3m
UXkmVR87DvxxRcaqN2IffQIDAQABo4ICSDCCAkQwDgYDVR0PAQH/BAQDAgWgMB0G
A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1Ud
DgQWBBSLsdHyqMT+Cxetefauf761+Mh7wjAfBgNVHSMEGDAWgBQULrMXt1hWy65Q
CUDmH6+dixTCxjBVBggrBgEFBQcBAQRJMEcwIQYIKwYBBQUHMAGGFWh0dHA6Ly9y
My5vLmxlbmNyLm9yZzAiBggrBgEFBQcwAoYWaHR0cDovL3IzLmkubGVuY3Iub3Jn
LzAZBgNVHREEEjAQgg4qLm9uZXNreWl0LmNvbTBMBgNVHSAERTBDMAgGBmeBDAEC
ATA3BgsrBgEEAYLfEwEBATAoMCYGCCsGAQUFBwIBFhpodHRwOi8vY3BzLmxldHNl
bmNyeXB0Lm9yZzCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB1AHoyjFTYty22IOo4
4FIe6YQWcDIThU070ivBOlejUutSAAABhIzy+N8AAAQDAEYwRAIgTEX+382iFK+M
RCyYw6MWnwAu9JqJrsKcEe+i+dzcDlQCIFrml/2Ck6pFzU3pYJimZouQ12kWl9Kk
EXqNRq1qmWJNAHYAb1N2rDHwMRnYmQCkURX/dxUcEdkCwQApBo2yCJo32RMAAAGE
jPL6YAAABAMARzBFAiAUbLLohaQCm2iYkRoNRvHCXnVDdB5/vmKwhNPfk//3YQIh
AMWwfMywrAUZVhiuahXA6hBp0EjmITSvuqMUDM3t52S4MA0GCSqGSIb3DQEBCwUA
A4IBAQBTk+HzCeJC+4P89DXTNyiqQcCiZVNR+3xMSQJUUkVfpaiam+2OH95CwrS/
b7VJ/ohF5wnxI0iHKbfiQBcmjlX7d8szmlboFWaoFSFq5V6mauQLTFhYIXEsKliH
xzTkvO+aFsRrdWK6aDaGQ3PC21769i/teenQfEGMIemeo2DhKpFabwpjimeSw9Z/
VZ2UycE4A4nH0PyP/004jhNAntMSUpGJjmlEcVHyy1Zj0kkgqYHKunIbhO3REBKh
NWtlePPiaTlQBwtgXM0rL/fuRnyHKNaeKKHg9fK0w3vY5kLD6v6Ga2B0agAh64yL
sikYlzNzdq9geimB/L8+EtV/cEFY
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----

View File

@@ -0,0 +1,87 @@
-----BEGIN CERTIFICATE-----
MIIEWDCCA0CgAwIBAgISA6BbQsNijMFF+faYbEg6ck/dMA0GCSqGSIb3DQEBCwUA
MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD
EwJSMzAeFw0yMzAyMTYyMDU2MzRaFw0yMzA1MTcyMDU2MzNaMBkxFzAVBgNVBAMM
Dioub25lc2t5aXQuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEw98IvDJP
hQG7B/20/GQkct0mUP9comlP2F7j7F0vpS7yKnxhnOJ42aa5n8kPpWXcTZMIxpRo
zZdVstm2k5dJAKOCAkowggJGMA4GA1UdDwEB/wQEAwIHgDAdBgNVHSUEFjAUBggr
BgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUABUSVubY
yPQ7Fl8dcbbRIPtJRVQwHwYDVR0jBBgwFoAUFC6zF7dYVsuuUAlA5h+vnYsUwsYw
VQYIKwYBBQUHAQEESTBHMCEGCCsGAQUFBzABhhVodHRwOi8vcjMuby5sZW5jci5v
cmcwIgYIKwYBBQUHMAKGFmh0dHA6Ly9yMy5pLmxlbmNyLm9yZy8wGQYDVR0RBBIw
EIIOKi5vbmVza3lpdC5jb20wTAYDVR0gBEUwQzAIBgZngQwBAgEwNwYLKwYBBAGC
3xMBAQEwKDAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcw
ggEFBgorBgEEAdZ5AgQCBIH2BIHzAPEAdwB6MoxU2LcttiDqOOBSHumEFnAyE4VN
O9IrwTpXo1LrUgAAAYZcOq0KAAAEAwBIMEYCIQDAFaRwPVsesEdYTW21Gb3KQ26B
kT4yHyat7irgsVh9nQIhAJ0ZlotCLLtBzomB3iX+qCLLCOre7npCksiNae/x/DN6
AHYArfe++nz/EMiLnT2cHj4YarRnKV3PsQwkyoWGNOvcgooAAAGGXDqtKgAABAMA
RzBFAiAbEJuxhl758U9epkxkUiWB4BN/ATDC5IxQhS7plcl12AIhANEYMdLg6w1W
Z5tMeaqnCw9xGyHzISP23xF6SyIXw9yRMA0GCSqGSIb3DQEBCwUAA4IBAQA06YuS
yyPNOst5llW3P6BCtFt7/BX2+kUvYYfxbkobONQTfwKYqAA5Jrb5zU23/OBOjgKa
9UU750t5E8OzxItkQkhSs7TCRYO7vy1b4D09RO2cfDCeqyqerQbU6z/PubNpJLSU
2FGbFTV1U7CxHAm3NfO+COEinGDRF58vywQrZWiOIAoDNQbDz48x7mdRyAuiEIT0
/UlOZKTsIyiIAmeRsrfmggCMI2TnvoAnerEYBOwWVaZwr98u7yWMDc5sTZN8uv0u
aXXhW65ua6HJ3tTbR4y8V8ZDxLXDrChy51/heAfPbX0nd7+Ps2a+9ErT0dmPw47X
Dl1Nox3EpyK0OYLG
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFFjCCAv6gAwIBAgIRAJErCErPDBinU/bWLiWnX1owDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjAwOTA0MDAwMDAw
WhcNMjUwOTE1MTYwMDAwWjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg
RW5jcnlwdDELMAkGA1UEAxMCUjMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQC7AhUozPaglNMPEuyNVZLD+ILxmaZ6QoinXSaqtSu5xUyxr45r+XXIo9cP
R5QUVTVXjJ6oojkZ9YI8QqlObvU7wy7bjcCwXPNZOOftz2nwWgsbvsCUJCWH+jdx
sxPnHKzhm+/b5DtFUkWWqcFTzjTIUu61ru2P3mBw4qVUq7ZtDpelQDRrK9O8Zutm
NHz6a4uPVymZ+DAXXbpyb/uBxa3Shlg9F8fnCbvxK/eG3MHacV3URuPMrSXBiLxg
Z3Vms/EY96Jc5lP/Ooi2R6X/ExjqmAl3P51T+c8B5fWmcBcUr2Ok/5mzk53cU6cG
/kiFHaFpriV1uxPMUgP17VGhi9sVAgMBAAGjggEIMIIBBDAOBgNVHQ8BAf8EBAMC
AYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMBIGA1UdEwEB/wQIMAYB
Af8CAQAwHQYDVR0OBBYEFBQusxe3WFbLrlAJQOYfr52LFMLGMB8GA1UdIwQYMBaA
FHm0WeZ7tuXkAXOACIjIGlj26ZtuMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw
AoYWaHR0cDovL3gxLmkubGVuY3Iub3JnLzAnBgNVHR8EIDAeMBygGqAYhhZodHRw
Oi8veDEuYy5sZW5jci5vcmcvMCIGA1UdIAQbMBkwCAYGZ4EMAQIBMA0GCysGAQQB
gt8TAQEBMA0GCSqGSIb3DQEBCwUAA4ICAQCFyk5HPqP3hUSFvNVneLKYY611TR6W
PTNlclQtgaDqw+34IL9fzLdwALduO/ZelN7kIJ+m74uyA+eitRY8kc607TkC53wl
ikfmZW4/RvTZ8M6UK+5UzhK8jCdLuMGYL6KvzXGRSgi3yLgjewQtCPkIVz6D2QQz
CkcheAmCJ8MqyJu5zlzyZMjAvnnAT45tRAxekrsu94sQ4egdRCnbWSDtY7kh+BIm
lJNXoB1lBMEKIq4QDUOXoRgffuDghje1WrG9ML+Hbisq/yFOGwXD9RiX8F6sw6W4
avAuvDszue5L3sz85K+EC4Y/wFVDNvZo4TYXao6Z0f+lQKc0t8DQYzk1OXVu8rp2
yJMC6alLbBfODALZvYH7n7do1AZls4I9d1P4jnkDrQoxB3UqQ9hVl3LEKQ73xF1O
yK5GhDDX8oVfGKF5u+decIsH4YaTw7mP3GFxJSqv3+0lUFJoi5Lc5da149p90Ids
hCExroL1+7mryIkXPeFM5TgO9r0rvZaBFOvV2z0gp35Z0+L4WPlbuEjN/lxPFin+
HlUjr8gRsI3qfJOQFy/9rKIJR0Y/8Omwt/8oTWgy1mdeHmmjk7j1nYsvC9JSQ6Zv
MldlTTKB3zhThV1+XWYp6rjd5JW1zbVWEkLNxE7GJThEUG3szgBVGP7pSWTUTsqX
nLRbwHOoq7hHwg==
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFYDCCBEigAwIBAgIQQAF3ITfU6UK47naqPGQKtzANBgkqhkiG9w0BAQsFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTIxMDEyMDE5MTQwM1oXDTI0MDkzMDE4MTQwM1ow
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwggIiMA0GCSqGSIb3DQEB
AQUAA4ICDwAwggIKAoICAQCt6CRz9BQ385ueK1coHIe+3LffOJCMbjzmV6B493XC
ov71am72AE8o295ohmxEk7axY/0UEmu/H9LqMZshftEzPLpI9d1537O4/xLxIZpL
wYqGcWlKZmZsj348cL+tKSIG8+TA5oCu4kuPt5l+lAOf00eXfJlII1PoOK5PCm+D
LtFJV4yAdLbaL9A4jXsDcCEbdfIwPPqPrt3aY6vrFk/CjhFLfs8L6P+1dy70sntK
4EwSJQxwjQMpoOFTJOwT2e4ZvxCzSow/iaNhUd6shweU9GNx7C7ib1uYgeGJXDR5
bHbvO5BieebbpJovJsXQEOEO3tkQjhb7t/eo98flAgeYjzYIlefiN5YNNnWe+w5y
sR2bvAP5SQXYgd0FtCrWQemsAXaVCg/Y39W9Eh81LygXbNKYwagJZHduRze6zqxZ
Xmidf3LWicUGQSk+WT7dJvUkyRGnWqNMQB9GoZm1pzpRboY7nn1ypxIFeFntPlF4
FQsDj43QLwWyPntKHEtzBRL8xurgUBN8Q5N0s8p0544fAQjQMNRbcTa0B7rBMDBc
SLeCO5imfWCKoqMpgsy6vYMEG6KDA0Gh1gXxG8K28Kh8hjtGqEgqiNx2mna/H2ql
PRmP6zjzZN7IKw0KKP/32+IVQtQi0Cdd4Xn+GOdwiK1O5tmLOsbdJ1Fu/7xk9TND
TwIDAQABo4IBRjCCAUIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
SwYIKwYBBQUHAQEEPzA9MDsGCCsGAQUFBzAChi9odHRwOi8vYXBwcy5pZGVudHJ1
c3QuY29tL3Jvb3RzL2RzdHJvb3RjYXgzLnA3YzAfBgNVHSMEGDAWgBTEp7Gkeyxx
+tvhS5B1/8QVYIWJEDBUBgNVHSAETTBLMAgGBmeBDAECATA/BgsrBgEEAYLfEwEB
ATAwMC4GCCsGAQUFBwIBFiJodHRwOi8vY3BzLnJvb3QteDEubGV0c2VuY3J5cHQu
b3JnMDwGA1UdHwQ1MDMwMaAvoC2GK2h0dHA6Ly9jcmwuaWRlbnRydXN0LmNvbS9E
U1RST09UQ0FYM0NSTC5jcmwwHQYDVR0OBBYEFHm0WeZ7tuXkAXOACIjIGlj26Ztu
MA0GCSqGSIb3DQEBCwUAA4IBAQAKcwBslm7/DlLQrt2M51oGrS+o44+/yQoDFVDC
5WxCu2+b9LRPwkSICHXM6webFGJueN7sJ7o5XPWioW5WlHAQU7G75K/QosMrAdSW
9MUgNTP52GE24HGNtLi1qoJFlcDyqSMo59ahy2cI2qBDLKobkx/J3vWraV0T9VuG
WCLKTVXkcGdtwlfFRjlBz4pYg1htmf5X6DYO8A4jqv2Il9DjXA6USbW1FzXSLr9O
he8Y4IWS6wY7bCkjCWDcRQJMEhg76fsO3txE+FiYruq9RUWhiF1myv4Q6W+CyBFC
Dfvp7OOGAN6dEOM4+qR9sdjoSYKEBpsr6GtPAQw4dy753ec5
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDp1TFuNSJrUpDL
yqOvr0h9fnMfUxGGUTdHhXzmkhR5TT1mtsqDFJoPA0vTcQLxpKZ5EC6+4iw8sfg6
Xw5J5DfhuUj8aKkV2FEmBsaxi0oXuB8cWQbWUa9FBwZjt5ld2bvgSpZGZjFkYGR2
izXnnKFcOCIvrth2Fnp4f7nZJOMfomkE4sIz4CrVk6krUsJn/mFJaoYlSpKa3DI7
SMD9E7ylKkP0B8VK+85oIsrUxwim57bs4NN/o03WEMBrfwDmncDQfZwbvS6/Rbdd
yVMvII/sHfv4c9MXJLv1QjOwCDzh4bSQcdWGTMFR/r3eKnu8reZReSZVHzsO/HFF
xqo3Yh99AgMBAAECggEAMEjAWAI7TP+D3D0H/01Z0eYURg3cYsiu+kMPdzoHZcPk
D6tjll0g8cQrumnN4pFt+bY0fOCNo2vZds4tkGcCfgcJUeuXrKXaHdjM2xkIz+yK
agtdHNDJuR55/InLLsS45ZfpP3i3LsOzwwG8fArNDBKgRonbc0jxeaPgP7089Akr
fu1+inRYogwQF6IAVTb9/xk46YLKnsIGfUrWU1THITO79mXxkjyTCCbw0yaR8SSN
ZrUVb+SmAzunYQoPAA5roGoJpytcf7g+RsnRiqZWWM4RFwVZ34W0cArAplcM6pCL
WqDgglf6NyUcoi3Tf3yDwoh26jWqMEBlxmXd3Cd2MQKBgQDsziZ0J2C0BuaXP3qI
534ddkTo2Wwm1hXo/cIzB2QNydMKEX4P1M1V6CVGTQxmSrY+lQzcvbRjuP6szsbq
326l0VKSGbVRMef8ZTYhm/V6qTaM1hxvd2aQ3tx8srnr4v+gPI6oKlRhM+bfCDGj
jCbpfpI/TEY/uNPKJyRk/hSXjQKBgQD8yVyqXXcRZ4W0ptQia0ZQL3VGJoSYcyio
3pzLRrX6emmHrcoZMGTJNv6cT9wFZrJyI1oxJUF3NXJkCNJmIVaeqHCQEvOncqaQ
3aA1A37UOMVWjLygOPXPFGN1xWgr0kg6eH89jFAj3Ub0WmzoJk/UiMfXdTGQGhwS
jIGa7pVzsQKBgQDhNOEfQD/YlmOAXg9z2ex3qn24kOYpPRsTPRoOm63M6y84eRBR
kAlD9QZWCHqNYepWNDxKRmQjHtGdmP1Wa+13503GwopM0NCWmc7UQdVAtWK6p/nd
DEnP5xL7yKHGs1h2lID7b15WHx0m6U0EBAsRrpz5c9mvSmCo9XbIUVdWFQKBgHeo
IVMLdwcoB6Rhq9y3BsuCC3MvXGiFamO1LGcUi6OLOlTdMOMHg02z2IXJT47G9AUP
Muw8hGaXSBSOEHoDoersNIweTHOg07OTFPjDNM/kJ5U2fTsie0iQkBv5W7wSh9oV
m7VYq76uSZ31B8REDlm+fUpB0TozAcLN+7OI5/mhAoGAMixiZnjwYvHqbyjL4ez4
UPtsHwsWYsjhOtZsUo3JHSJVq903ogl6Zi3s+7mkgxo4qM5EwMNMedbsR61ri9Sh
rvmFGJIn0mA0FDW/Ix4TAVxVIqZNHMd9V5zZpvetdV0KIWHfBKZzayXXO9KVf/8t
WnyAnwVRN4X75oCtQ3QTcLA=
-----END PRIVATE KEY-----

5
conf/certs/privkey.pem Normal file
View File

@@ -0,0 +1,5 @@
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgTynVoZVG+2WtMNoO
Urwa0fx+u7sS/T8j4TE370MTc7qhRANCAATD3wi8Mk+FAbsH/bT8ZCRy3SZQ/1yi
aU/YXuPsXS+lLvIqfGGc4njZprmfyQ+lZdxNkwjGlGjNl1Wy2baTl0kA
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,8 @@
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA//////////+t+FRYortKmq/cViAnPTzx2LnFg84tNpWp4TZBFGQz
+8yTnc4kmz75fS/jY2MMddj2gbICrsRhetPfHtXV/WVhJDP1H18GbtCFY2VVPe0a
87VXE15/V8k1mE8McODmi3fipona8+/och3xWKE2rec1MKzKT0g6eXq8CrGCsyT7
YdEIqUuyyOP7uWrat2DX9GgdT0Kj3jlN9K5W7edjcrsZCwenyO4KbXCeAvzhzffi
7MA0BM0oNC9hkXL+nOmFg/+OTxIy7vKBg8P+OxtMb61zO7X8vC7CIAXFjvGDfRaD
ssbzSibBsu/6iGtCOGEoXJf//////////wIBAg==
-----END DH PARAMETERS-----

2
conf/mariadb/my.cnf Normal file
View File

@@ -0,0 +1,2 @@
transaction-isolation=READ-COMMITTED
binlog-format=ROW

151
conf/nextcloud/Dockerfile Normal file
View File

@@ -0,0 +1,151 @@
# DO NOT EDIT: created by update.sh from Dockerfile-debian.template
FROM php:8.1-fpm-bullseye
# entrypoint.sh and cron.sh dependencies
RUN set -ex; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
rsync \
bzip2 \
busybox-static \
libldap-common \
libmagickcore-6.q16-6-extra \
; \
rm -rf /var/lib/apt/lists/*; \
\
mkdir -p /var/spool/cron/crontabs; \
echo '*/5 * * * * php -f /var/www/html/cron.php' > /var/spool/cron/crontabs/www-data
# install the PHP extensions we need
# see https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html
ENV PHP_MEMORY_LIMIT 512M
ENV PHP_UPLOAD_LIMIT 512M
RUN set -ex; \
\
savedAptMark="$(apt-mark showmanual)"; \
\
apt-get update; \
apt-get install -y --no-install-recommends \
libcurl4-openssl-dev \
libevent-dev \
libfreetype6-dev \
libicu-dev \
libjpeg-dev \
libldap2-dev \
libmcrypt-dev \
libmemcached-dev \
libpng-dev \
libpq-dev \
libxml2-dev \
libmagickwand-dev \
libzip-dev \
libwebp-dev \
libgmp-dev \
; \
\
debMultiarch="$(dpkg-architecture --query DEB_BUILD_MULTIARCH)"; \
docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp; \
docker-php-ext-configure ldap --with-libdir="lib/$debMultiarch"; \
docker-php-ext-install -j "$(nproc)" \
bcmath \
exif \
gd \
intl \
ldap \
opcache \
pcntl \
pdo_mysql \
pdo_pgsql \
zip \
gmp \
; \
\
# pecl will claim success even if one install fails, so we need to perform each install separately
pecl install APCu-5.1.22; \
pecl install memcached-3.2.0; \
pecl install redis-5.3.7; \
pecl install imagick-3.7.0; \
\
docker-php-ext-enable \
apcu \
memcached \
redis \
imagick \
; \
rm -r /tmp/pear; \
\
# reset apt-mark's "manual" list so that "purge --auto-remove" will remove all build dependencies
apt-mark auto '.*' > /dev/null; \
apt-mark manual $savedAptMark; \
ldd "$(php -r 'echo ini_get("extension_dir");')"/*.so \
| awk '/=>/ { print $3 }' \
| sort -u \
| xargs -r dpkg-query -S \
| cut -d: -f1 \
| sort -u \
| xargs -rt apt-mark manual; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false; \
rm -rf /var/lib/apt/lists/*
# set recommended PHP.ini settings
# see https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-php-opcache
RUN { \
echo 'opcache.enable=1'; \
echo 'opcache.interned_strings_buffer=16'; \
echo 'opcache.max_accelerated_files=10000'; \
echo 'opcache.memory_consumption=128'; \
echo 'opcache.save_comments=1'; \
echo 'opcache.revalidate_freq=60'; \
} > "${PHP_INI_DIR}/conf.d/opcache-recommended.ini"; \
\
echo 'apc.enable_cli=1' >> "${PHP_INI_DIR}/conf.d/docker-php-ext-apcu.ini"; \
\
{ \
echo 'memory_limit=${PHP_MEMORY_LIMIT}'; \
echo 'upload_max_filesize=${PHP_UPLOAD_LIMIT}'; \
echo 'post_max_size=${PHP_UPLOAD_LIMIT}'; \
} > "${PHP_INI_DIR}/conf.d/nextcloud.ini"; \
\
mkdir /var/www/data; \
chown -R www-data:root /var/www; \
chmod -R g=u /var/www
VOLUME /var/www/html
ENV NEXTCLOUD_VERSION 25.0.2
RUN set -ex; \
fetchDeps=" \
gnupg \
dirmngr \
"; \
apt-get update; \
apt-get install -y --no-install-recommends $fetchDeps; \
\
curl -fsSL -o nextcloud.tar.bz2 \
"https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2"; \
curl -fsSL -o nextcloud.tar.bz2.asc \
"https://download.nextcloud.com/server/releases/nextcloud-${NEXTCLOUD_VERSION}.tar.bz2.asc"; \
export GNUPGHOME="$(mktemp -d)"; \
# gpg key from https://nextcloud.com/nextcloud.asc
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys 28806A878AE423A28372792ED75899B9A724937A; \
gpg --batch --verify nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
tar -xjf nextcloud.tar.bz2 -C /usr/src/; \
gpgconf --kill all; \
rm nextcloud.tar.bz2.asc nextcloud.tar.bz2; \
rm -rf "$GNUPGHOME" /usr/src/nextcloud/updater; \
mkdir -p /usr/src/nextcloud/data; \
mkdir -p /usr/src/nextcloud/custom_apps; \
chmod +x /usr/src/nextcloud/occ; \
\
apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $fetchDeps; \
rm -rf /var/lib/apt/lists/*
COPY *.sh upgrade.exclude /
COPY config/* /usr/src/nextcloud/config/
ENTRYPOINT ["/entrypoint.sh"]
CMD ["php-fpm"]

View File

@@ -0,0 +1,4 @@
<?php
$CONFIG = array (
'memcache.local' => '\OC\Memcache\APCu',
);

View File

@@ -0,0 +1,15 @@
<?php
$CONFIG = array (
'apps_paths' => array (
0 => array (
'path' => OC::$SERVERROOT.'/apps',
'url' => '/apps',
'writable' => false,
),
1 => array (
'path' => OC::$SERVERROOT.'/custom_apps',
'url' => '/custom_apps',
'writable' => true,
),
),
);

View File

@@ -0,0 +1,41 @@
<?php
$autoconfig_enabled = false;
if (getenv('SQLITE_DATABASE')) {
$AUTOCONFIG['dbtype'] = 'sqlite';
$AUTOCONFIG['dbname'] = getenv('SQLITE_DATABASE');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE_FILE') && getenv('MYSQL_USER_FILE') && getenv('MYSQL_PASSWORD_FILE') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('MYSQL_DATABASE_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('MYSQL_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('MYSQL_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('MYSQL_DATABASE') && getenv('MYSQL_USER') && getenv('MYSQL_PASSWORD') && getenv('MYSQL_HOST')) {
$AUTOCONFIG['dbtype'] = 'mysql';
$AUTOCONFIG['dbname'] = getenv('MYSQL_DATABASE');
$AUTOCONFIG['dbuser'] = getenv('MYSQL_USER');
$AUTOCONFIG['dbpass'] = getenv('MYSQL_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('MYSQL_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB_FILE') && getenv('POSTGRES_USER_FILE') && getenv('POSTGRES_PASSWORD_FILE') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = trim(file_get_contents(getenv('POSTGRES_DB_FILE')));
$AUTOCONFIG['dbuser'] = trim(file_get_contents(getenv('POSTGRES_USER_FILE')));
$AUTOCONFIG['dbpass'] = trim(file_get_contents(getenv('POSTGRES_PASSWORD_FILE')));
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
} elseif (getenv('POSTGRES_DB') && getenv('POSTGRES_USER') && getenv('POSTGRES_PASSWORD') && getenv('POSTGRES_HOST')) {
$AUTOCONFIG['dbtype'] = 'pgsql';
$AUTOCONFIG['dbname'] = getenv('POSTGRES_DB');
$AUTOCONFIG['dbuser'] = getenv('POSTGRES_USER');
$AUTOCONFIG['dbpass'] = getenv('POSTGRES_PASSWORD');
$AUTOCONFIG['dbhost'] = getenv('POSTGRES_HOST');
$autoconfig_enabled = true;
}
if ($autoconfig_enabled) {
$AUTOCONFIG['directory'] = getenv('NEXTCLOUD_DATA_DIR') ?: '/var/www/html/data';
}

View File

@@ -0,0 +1,17 @@
<?php
if (getenv('REDIS_HOST')) {
$CONFIG = array(
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => getenv('REDIS_HOST'),
'password' => (string) getenv('REDIS_HOST_PASSWORD'),
),
);
if (getenv('REDIS_HOST_PORT') !== false) {
$CONFIG['redis']['port'] = (int) getenv('REDIS_HOST_PORT');
} elseif (getenv('REDIS_HOST')[0] != '/') {
$CONFIG['redis']['port'] = 6379;
}
}

View File

@@ -0,0 +1,30 @@
<?php
$overwriteHost = getenv('OVERWRITEHOST');
if ($overwriteHost) {
$CONFIG['overwritehost'] = $overwriteHost;
}
$overwriteProtocol = getenv('OVERWRITEPROTOCOL');
if ($overwriteProtocol) {
$CONFIG['overwriteprotocol'] = $overwriteProtocol;
}
$overwriteCliUrl = getenv('OVERWRITECLIURL');
if ($overwriteCliUrl) {
$CONFIG['overwrite.cli.url'] = $overwriteCliUrl;
}
$overwriteWebRoot = getenv('OVERWRITEWEBROOT');
if ($overwriteWebRoot) {
$CONFIG['overwritewebroot'] = $overwriteWebRoot;
}
$overwriteCondAddr = getenv('OVERWRITECONDADDR');
if ($overwriteCondAddr) {
$CONFIG['overwritecondaddr'] = $overwriteCondAddr;
}
$trustedProxies = getenv('TRUSTED_PROXIES');
if ($trustedProxies) {
$CONFIG['trusted_proxies'] = array_filter(array_map('trim', explode(' ', $trustedProxies)));
}

View File

@@ -0,0 +1,27 @@
<?php
if (getenv('OBJECTSTORE_S3_BUCKET')) {
$use_ssl = getenv('OBJECTSTORE_S3_SSL');
$use_path = getenv('OBJECTSTORE_S3_USEPATH_STYLE');
$use_legacyauth = getenv('OBJECTSTORE_S3_LEGACYAUTH');
$autocreate = getenv('OBJECTSTORE_S3_AUTOCREATE');
$CONFIG = array(
'objectstore' => array(
'class' => '\OC\Files\ObjectStore\S3',
'arguments' => array(
'bucket' => getenv('OBJECTSTORE_S3_BUCKET'),
'key' => getenv('OBJECTSTORE_S3_KEY') ?: '',
'secret' => getenv('OBJECTSTORE_S3_SECRET') ?: '',
'region' => getenv('OBJECTSTORE_S3_REGION') ?: '',
'hostname' => getenv('OBJECTSTORE_S3_HOST') ?: '',
'port' => getenv('OBJECTSTORE_S3_PORT') ?: '',
'objectPrefix' => getenv("OBJECTSTORE_S3_OBJECT_PREFIX") ? getenv("OBJECTSTORE_S3_OBJECT_PREFIX") : "urn:oid:",
'autocreate' => (strtolower($autocreate) === 'false' || $autocreate == false) ? false : true,
'use_ssl' => (strtolower($use_ssl) === 'false' || $use_ssl == false) ? false : true,
// required for some non Amazon S3 implementations
'use_path_style' => $use_path == true && strtolower($use_path) !== 'false',
// required for older protocol versions
'legacy_auth' => $use_legacyauth == true && strtolower($use_legacyauth) !== 'false'
)
)
);
}

View File

@@ -0,0 +1,22 @@
<?php
if (getenv('SMTP_HOST') && getenv('MAIL_FROM_ADDRESS') && getenv('MAIL_DOMAIN')) {
$CONFIG = array (
'mail_smtpmode' => 'smtp',
'mail_smtphost' => getenv('SMTP_HOST'),
'mail_smtpport' => getenv('SMTP_PORT') ?: (getenv('SMTP_SECURE') ? 465 : 25),
'mail_smtpsecure' => getenv('SMTP_SECURE') ?: '',
'mail_smtpauth' => getenv('SMTP_NAME') && (getenv('SMTP_PASSWORD') || (getenv('SMTP_PASSWORD_FILE') && file_exists(getenv('SMTP_PASSWORD_FILE')))),
'mail_smtpauthtype' => getenv('SMTP_AUTHTYPE') ?: 'LOGIN',
'mail_smtpname' => getenv('SMTP_NAME') ?: '',
'mail_from_address' => getenv('MAIL_FROM_ADDRESS'),
'mail_domain' => getenv('MAIL_DOMAIN'),
);
if (getenv('SMTP_PASSWORD_FILE') && file_exists(getenv('SMTP_PASSWORD_FILE'))) {
$CONFIG['mail_smtppassword'] = trim(file_get_contents(getenv('SMTP_PASSWORD_FILE')));
} elseif (getenv('SMTP_PASSWORD')) {
$CONFIG['mail_smtppassword'] = getenv('SMTP_PASSWORD');
} else {
$CONFIG['mail_smtppassword'] = '';
}
}

View File

@@ -0,0 +1,31 @@
<?php
if (getenv('OBJECTSTORE_SWIFT_URL')) {
$autocreate = getenv('OBJECTSTORE_SWIFT_AUTOCREATE');
$CONFIG = array(
'objectstore' => [
'class' => 'OC\\Files\\ObjectStore\\Swift',
'arguments' => [
'autocreate' => $autocreate == true && strtolower($autocreate) !== 'false',
'user' => [
'name' => getenv('OBJECTSTORE_SWIFT_USER_NAME'),
'password' => getenv('OBJECTSTORE_SWIFT_USER_PASSWORD'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_USER_DOMAIN')) ?: 'Default',
],
],
'scope' => [
'project' => [
'name' => getenv('OBJECTSTORE_SWIFT_PROJECT_NAME'),
'domain' => [
'name' => (getenv('OBJECTSTORE_SWIFT_PROJECT_DOMAIN')) ?: 'Default',
],
],
],
'serviceName' => (getenv('OBJECTSTORE_SWIFT_SERVICE_NAME')) ?: 'swift',
'region' => getenv('OBJECTSTORE_SWIFT_REGION'),
'url' => getenv('OBJECTSTORE_SWIFT_URL'),
'bucket' => getenv('OBJECTSTORE_SWIFT_CONTAINER_NAME'),
]
]
);
}

4
conf/nextcloud/cron.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
set -eu
exec busybox crond -f -l 0 -L /dev/stdout

250
conf/nextcloud/entrypoint.sh Executable file
View File

@@ -0,0 +1,250 @@
#!/bin/sh
set -eu
# version_greater A B returns whether A > B
version_greater() {
[ "$(printf '%s\n' "$@" | sort -t '.' -n -k1,1 -k2,2 -k3,3 -k4,4 | head -n 1)" != "$1" ]
}
# return true if specified directory is empty
directory_empty() {
[ -z "$(ls -A "$1/")" ]
}
run_as() {
if [ "$(id -u)" = 0 ]; then
su -p "$user" -s /bin/sh -c "$1"
else
sh -c "$1"
fi
}
# usage: file_env VAR [DEFAULT]
# ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
# "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
if [ -n "${varValue}" ]; then
export "$var"="${varValue}"
elif [ -n "${fileVarValue}" ]; then
export "$var"="$(cat "${fileVarValue}")"
elif [ -n "${def}" ]; then
export "$var"="$def"
fi
unset "$fileVar"
}
if expr "$1" : "apache" 1>/dev/null; then
if [ -n "${APACHE_DISABLE_REWRITE_IP+x}" ]; then
a2disconf remoteip
fi
fi
if expr "$1" : "apache" 1>/dev/null || [ "$1" = "php-fpm" ] || [ "${NEXTCLOUD_UPDATE:-0}" -eq 1 ]; then
uid="$(id -u)"
gid="$(id -g)"
if [ "$uid" = '0' ]; then
case "$1" in
apache2*)
user="${APACHE_RUN_USER:-http}"
group="${APACHE_RUN_GROUP:-http}"
# strip off any '#' symbol ('#1000' is valid syntax for Apache)
user="${user#'#'}"
group="${group#'#'}"
;;
*) # php-fpm
user='http'
group='http'
;;
esac
else
user="$uid"
group="$gid"
fi
if [ -n "${REDIS_HOST+x}" ]; then
echo "Configuring Redis as session handler"
{
file_env REDIS_HOST_PASSWORD
echo 'session.save_handler = redis'
# check if redis host is an unix socket path
if [ "$(echo "$REDIS_HOST" | cut -c1-1)" = "/" ]; then
if [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"unix://${REDIS_HOST}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"unix://${REDIS_HOST}\""
fi
# check if redis password has been set
elif [ -n "${REDIS_HOST_PASSWORD+x}" ]; then
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}?auth=${REDIS_HOST_PASSWORD}\""
else
echo "session.save_path = \"tcp://${REDIS_HOST}:${REDIS_HOST_PORT:=6379}\""
fi
echo "redis.session.locking_enabled = 1"
echo "redis.session.lock_retries = -1"
# redis.session.lock_wait_time is specified in microseconds.
# Wait 10ms before retrying the lock rather than the default 2ms.
echo "redis.session.lock_wait_time = 10000"
} > /usr/local/etc/php/conf.d/redis-session.ini
fi
installed_version="0.0.0.0"
if [ -f /var/www/html/version.php ]; then
# shellcheck disable=SC2016
installed_version="$(php -r 'require "/var/www/html/version.php"; echo implode(".", $OC_Version);')"
fi
# shellcheck disable=SC2016
image_version="$(php -r 'require "/usr/src/nextcloud/version.php"; echo implode(".", $OC_Version);')"
if version_greater "$installed_version" "$image_version"; then
echo "Can't start Nextcloud because the version of the data ($installed_version) is higher than the docker image version ($image_version) and downgrading is not supported. Are you sure you have pulled the newest image version?"
exit 1
fi
if version_greater "$image_version" "$installed_version"; then
echo "Initializing nextcloud $image_version ..."
if [ "$installed_version" != "0.0.0.0" ]; then
echo "Upgrading nextcloud from $installed_version ..."
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_before
fi
if [ "$(id -u)" = 0 ]; then
rsync_options="-rlDog --chown $user:$group"
else
rsync_options="-rlD"
fi
# If another process is syncing the html folder, wait for
# it to be done, then escape initalization.
# You need to define the NEXTCLOUD_INIT_LOCK environment variable
lock=/var/www/html/nextcloud-init-sync.lock
count=0
limit=10
if [ -f "$lock" ] && [ -n "${NEXTCLOUD_INIT_LOCK+x}" ]; then
until [ ! -f "$lock" ] || [ "$count" -gt "$limit" ]
do
count=$((count+1))
wait=$((count*10))
echo "Another process is initializing Nextcloud. Waiting $wait seconds..."
sleep $wait
done
if [ "$count" -gt "$limit" ]; then
echo "Timeout while waiting for an ongoing initialization"
exit 1
fi
echo "The other process is done, assuming complete initialization"
else
# Prevent multiple images syncing simultaneously
touch $lock
rsync $rsync_options --delete --exclude-from=/upgrade.exclude /usr/src/nextcloud/ /var/www/html/
for dir in config data custom_apps themes; do
if [ ! -d "/var/www/html/$dir" ] || directory_empty "/var/www/html/$dir"; then
rsync $rsync_options --include "/$dir/" --exclude '/*' /usr/src/nextcloud/ /var/www/html/
fi
done
rsync $rsync_options --include '/version.php' --exclude '/*' /usr/src/nextcloud/ /var/www/html/
# Install
if [ "$installed_version" = "0.0.0.0" ]; then
echo "New nextcloud instance"
file_env NEXTCLOUD_ADMIN_PASSWORD
file_env NEXTCLOUD_ADMIN_USER
if [ -n "${NEXTCLOUD_ADMIN_USER+x}" ] && [ -n "${NEXTCLOUD_ADMIN_PASSWORD+x}" ]; then
# shellcheck disable=SC2016
install_options='-n --admin-user "$NEXTCLOUD_ADMIN_USER" --admin-pass "$NEXTCLOUD_ADMIN_PASSWORD"'
if [ -n "${NEXTCLOUD_DATA_DIR+x}" ]; then
# shellcheck disable=SC2016
install_options=$install_options' --data-dir "$NEXTCLOUD_DATA_DIR"'
fi
file_env MYSQL_DATABASE
file_env MYSQL_PASSWORD
file_env MYSQL_USER
file_env POSTGRES_DB
file_env POSTGRES_PASSWORD
file_env POSTGRES_USER
install=false
if [ -n "${SQLITE_DATABASE+x}" ]; then
echo "Installing with SQLite database"
# shellcheck disable=SC2016
install_options=$install_options' --database-name "$SQLITE_DATABASE"'
install=true
elif [ -n "${MYSQL_DATABASE+x}" ] && [ -n "${MYSQL_USER+x}" ] && [ -n "${MYSQL_PASSWORD+x}" ] && [ -n "${MYSQL_HOST+x}" ]; then
echo "Installing with MySQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database mysql --database-name "$MYSQL_DATABASE" --database-user "$MYSQL_USER" --database-pass "$MYSQL_PASSWORD" --database-host "$MYSQL_HOST"'
install=true
elif [ -n "${POSTGRES_DB+x}" ] && [ -n "${POSTGRES_USER+x}" ] && [ -n "${POSTGRES_PASSWORD+x}" ] && [ -n "${POSTGRES_HOST+x}" ]; then
echo "Installing with PostgreSQL database"
# shellcheck disable=SC2016
install_options=$install_options' --database pgsql --database-name "$POSTGRES_DB" --database-user "$POSTGRES_USER" --database-pass "$POSTGRES_PASSWORD" --database-host "$POSTGRES_HOST"'
install=true
fi
if [ "$install" = true ]; then
echo "Starting nextcloud installation"
max_retries=10
try=0
until run_as "php /var/www/html/occ maintenance:install $install_options" || [ "$try" -gt "$max_retries" ]
do
echo "Retrying install..."
try=$((try+1))
sleep 10s
done
if [ "$try" -gt "$max_retries" ]; then
echo "Installing of nextcloud failed!"
exit 1
fi
if [ -n "${NEXTCLOUD_TRUSTED_DOMAINS+x}" ]; then
echo "Setting trusted domains…"
NC_TRUSTED_DOMAIN_IDX=1
for DOMAIN in $NEXTCLOUD_TRUSTED_DOMAINS ; do
DOMAIN=$(echo "$DOMAIN" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
run_as "php /var/www/html/occ config:system:set trusted_domains $NC_TRUSTED_DOMAIN_IDX --value=$DOMAIN"
NC_TRUSTED_DOMAIN_IDX=$((NC_TRUSTED_DOMAIN_IDX+1))
done
fi
else
echo "Please run the web-based installer on first connect!"
fi
fi
# Upgrade
else
run_as 'php /var/www/html/occ upgrade'
run_as 'php /var/www/html/occ app:list' | sed -n "/Enabled:/,/Disabled:/p" > /tmp/list_after
echo "The following apps have been disabled:"
diff /tmp/list_before /tmp/list_after | grep '<' | cut -d- -f2 | cut -d: -f1
rm -f /tmp/list_before /tmp/list_after
fi
# Initialization done, reset lock
rm $lock
echo "Initializing finished"
fi
fi
# Update htaccess after init if requested
if [ -n "${NEXTCLOUD_INIT_HTACCESS+x}" ] && [ "$installed_version" != "0.0.0.0" ]; then
run_as 'php /var/www/html/occ maintenance:update:htaccess'
fi
fi
exec "$@"

View File

@@ -0,0 +1,6 @@
/config/
/data/
/custom_apps/
/themes/
/version.php
/nextcloud-init-sync.lock

View File

@@ -0,0 +1,14 @@
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.
ssl_session_cache shared:le_nginx_SSL:5m; # was 1m (1 MB)
ssl_session_timeout 1440m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH !RC4";
#ssl_ciphers HIGH:!aNULL:!MD5;

View File

@@ -0,0 +1,20 @@
server {
listen 80;
listen [::]:80;
server_name mailman2-oneskyit.localhost mailman2.oneskyit.com;
access_log /logs/nginx/access_oneskyit_mailman2.log;
index index.php;
location / {
proxy_pass http://mailman2:80;
proxy_pass_header Content-Type;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # allow websockets
proxy_pass_header Connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}

View File

@@ -0,0 +1,194 @@
upstream php-handler {
server nextcloud25:9000;
# server unix:/var/run/php/php7.4-fpm.sock;
}
# Set the `immutable` cache control options only for assets with a cache busting `v` argument
map $arg_v $asset_immutable {
"" "";
default "immutable";
}
server {
listen 80;
listen [::]:80;
server_name nextcloud.oneskyit.com;
# Prevent nginx HTTP Server Detection
server_tokens off;
# Enforce HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name nextcloud.oneskyit.com;
access_log /logs/nginx/access_oneskyit_nextcloud.log;
# Path to the root of your installation
# root /srv/nextcloud;
root /var/www/html;
# Use Mozilla's guidelines for SSL/TLS settings
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
# ssl_certificate /etc/ssl/nginx/nextcloud.oneskyit.com.crt;
# ssl_certificate_key /etc/ssl/nginx/nextcloud.oneskyit.com.key;
include /etc/nginx/options-ssl-nginx.conf;
ssl_certificate /etc/certs/fullchain.pem;
ssl_certificate_key /etc/certs/privkey.pem;
ssl_dhparam /etc/certs/ssl-dhparams.pem;
# Prevent nginx HTTP Server Detection
server_tokens off;
# HSTS settings
# WARNING: Only add the preload option once you read about
# the consequences in https://hstspreload.org/. This option
# will add the domain to a hardcoded list that is shipped
# in all major browsers and getting removed from this list
# could take several months.
#add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
# set max upload size and increase upload timeout:
client_max_body_size 512M;
client_body_timeout 300s;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on;
gzip_vary on;
gzip_comp_level 4;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Pagespeed is not supported by Nextcloud, so if your server is built
# with the `ngx_pagespeed` module, uncomment this line to disable it.
#pagespeed off;
# The settings allows you to optimize the HTTP2 bandwitdth.
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
# for tunning hints
client_body_buffer_size 512k;
# HTTP response headers borrowed from Nextcloud `.htaccess`
add_header Referrer-Policy "no-referrer" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Download-Options "noopen" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Permitted-Cross-Domain-Policies "none" always;
add_header X-Robots-Tag "none" always;
add_header X-XSS-Protection "1; mode=block" always;
# Remove X-Powered-By, which is an information leak
fastcgi_hide_header X-Powered-By;
# Specify how to handle directories -- specifying `/index.php$request_uri`
# here as the fallback means that Nginx always exhibits the desired behaviour
# when a client requests a path that corresponds to a directory that exists
# on the server. In particular, if that directory contains an index.php file,
# that file is correctly served; if it doesn't, then the request is passed to
# the front-end controller. This consistent behaviour means that we don't need
# to specify custom rules for certain paths (e.g. images and other assets,
# `/updater`, `/ocm-provider`, `/ocs-provider`), and thus
# `try_files $uri $uri/ /index.php$request_uri`
# always provides the desired behaviour.
index index.php index.html /index.php$request_uri;
# Rule borrowed from `.htaccess` to handle Microsoft DAV clients
location = / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location ^~ /.well-known {
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation { try_files $uri $uri/ =404; }
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# Rules borrowed from `.htaccess` to hide certain paths from clients
location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; }
location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; }
# Ensure this block, which passes PHP files to the PHP process, is above the blocks
# which handle static assets (as seen below). If this block is not declared first,
# then Nginx will encounter an infinite rewriting loop when it prepends `/index.php`
# to the URI, resulting in a HTTP 500 error response.
location ~ \.php(?:$|/) {
# Required for legacy support
rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
set $path_info $fastcgi_path_info;
try_files $fastcgi_script_name =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# fastcgi_param SCRIPT_FILENAME /var/www/html/$fastcgi_script_name;
fastcgi_param PATH_INFO $path_info;
fastcgi_param HTTPS on;
fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice
fastcgi_param front_controller_active true; # Enable pretty urls
fastcgi_pass php-handler;
fastcgi_intercept_errors on;
fastcgi_request_buffering off;
fastcgi_max_temp_file_size 0;
}
location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
try_files $uri /index.php$request_uri;
add_header Cache-Control "public, max-age=15778463, $asset_immutable";
access_log off; # Optional: Don't log access to assets
location ~ \.wasm$ {
default_type application/wasm;
}
}
location ~ \.woff2?$ {
try_files $uri /index.php$request_uri;
expires 7d; # Cache-Control policy borrowed from `.htaccess`
access_log off; # Optional: Don't log access to assets
}
# Rule borrowed from `.htaccess`
location /remote {
return 301 /remote.php$request_uri;
}
location / {
try_files $uri $uri/ /index.php$request_uri;
}
}

View File

@@ -0,0 +1,20 @@
server {
listen 80;
listen [::]:80;
server_name phpmyadmin-oneskyit.localhost phpmyadmin.oneskyit.com;
access_log /logs/nginx/access_oneskyit_phpmyadmin.log;
index index.php;
location / {
proxy_pass http://phpmyadmin:80;
proxy_pass_header Content-Type;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # allow websockets
proxy_pass_header Connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}

View File

@@ -0,0 +1,101 @@
server {
listen 80;
listen [::]:80;
server_name
fastapi_gunicorn.localhost
dev-api.localhost
dev-api.oneskyit.com
;
access_log /logs/nginx/access_fastapi_gunicorn.log;
error_log /logs/nginx/error_fastapi_gunicorn.log;
client_max_body_size 5120M; #4096M or 4G; 5120M or 5G;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_buffering off;
# This is needed for long running Python code. Default is 60 seconds
# Increased from 1200 to 1500 on 2022-04-17
fastcgi_connect_timeout 1500s;
fastcgi_send_timeout 1500s;
fastcgi_read_timeout 1500s;
proxy_read_timeout 1500s;
proxy_pass http://fastapi_backend;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl http2;
server_name
fastapi_gunicorn.localhost
dev-api.localhost
dev-api.oneskyit.com
;
access_log /logs/nginx/access_fastapi_gunicorn.log;
error_log /logs/nginx/error_fastapi_gunicorn.log;
include /etc/nginx/options-ssl-nginx.conf;
ssl_certificate /etc/certs/fullchain.pem;
ssl_certificate_key /etc/certs/privkey.pem;
ssl_dhparam /etc/certs/ssl-dhparams.pem;
# include brotli.conf;
# include gzip.conf;
client_max_body_size 5120M; #4096M or 4G; 5120M or 5G;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_buffering off;
# This is needed for long running Python code. Default is 60 seconds
# Increased from 1200 to 1500 on 2022-04-17
fastcgi_connect_timeout 1500s;
fastcgi_send_timeout 1500s;
fastcgi_read_timeout 1500s;
proxy_read_timeout 1500s;
proxy_pass http://fastapi_backend;
}
}
upstream fastapi_backend {
# sticky sessions
ip_hash;
# enable least connections balancing method
# least_conn;
# zone backend 64k; # Use NGINX Plus' shared memory
# server webserver1 weight=1;
# server webserver2 weight=4;
# larger number will recieve more requests
# Example of 20 vs 10: 20 will recieve twice as many requests as 10
server aether_api_gunicorn:5005 weight=20 max_fails=3 fail_timeout=30s;
# server aether_api_gunicorn_bak:5005 weight=10 max_fails=1 fail_timeout=30s;
# maintain up to 20 idle connections to the group of upstream servers
# keepalive 20;
}

View File

@@ -0,0 +1,127 @@
server {
listen 80;
listen [::]:80;
server_name
flask_gunicorn.localhost demo.localhost dev.localhost
dev.oneskyit.com
dev-app.oneskyit.com
dev-connect.oneskyit.com *.dev-connect.oneskyit.com
dev-demo.oneskyit.com *.dev-demo.oneskyit.com
dev-aapor.oneskyit.com *.dev-aapor.oneskyit.com
dev-businessgroup.oneskyt.com *.dev-businessgroup.oneskyt.com
dev-cmsc.oneskyit.com *.dev-cmsc.oneskyit.com
dev-idaa.oneskyit.com *.dev-idaa.oneskyit.com
dev-ishlt.oneskyit.com *.dev-ishlt.oneskyit.com
dev-ncsd.oneskyit.com *.dev-ncsd.oneskyit.com
dev-npa.oneskyit.com *.dev-npa.oneskyit.com
dev-rli.oneskyit.com *.dev-rli.oneskyit.com
;
access_log /logs/nginx/access_flask_gunicorn.log;
error_log /logs/nginx/error_flask_gunicorn.log;
client_max_body_size 5120M; #4096M or 4G; 5120M or 5G;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_buffering off;
# This is needed for long running Python code. Default is 60 seconds
# Increased from 1200 to 1500 on 2022-04-17
fastcgi_connect_timeout 1500s;
fastcgi_send_timeout 1500s;
fastcgi_read_timeout 1500s;
proxy_read_timeout 1500s;
proxy_pass http://flask_backend;
}
}
server {
listen 443 ssl;
listen [::]:443 ssl http2;
server_name
flask_gunicorn.localhost demo.localhost dev.localhost
dev.oneskyit.com
dev-app.oneskyit.com
dev-connect.oneskyit.com *.dev-connect.oneskyit.com
dev-demo.oneskyit.com *.dev-demo.oneskyit.com
dev-aapor.oneskyit.com *.dev-aapor.oneskyit.com
dev-businessgroup.oneskyt.com *.dev-businessgroup.oneskyt.com
dev-cmsc.oneskyit.com *.dev-cmsc.oneskyit.com
dev-idaa.oneskyit.com *.dev-idaa.oneskyit.com
dev-ishlt.oneskyit.com *.dev-ishlt.oneskyit.com
dev-ncsd.oneskyit.com *.dev-ncsd.oneskyit.com
dev-npa.oneskyit.com *.dev-npa.oneskyit.com
dev-rli.oneskyit.com *.dev-rli.oneskyit.com
;
access_log /logs/nginx/access_flask_gunicorn.log;
error_log /logs/nginx/error_flask_gunicorn.log;
include /etc/nginx/options-ssl-nginx.conf;
ssl_certificate /etc/certs/fullchain.pem;
ssl_certificate_key /etc/certs/privkey.pem;
ssl_dhparam /etc/certs/ssl-dhparams.pem;
# include brotli.conf;
# include gzip.conf;
client_max_body_size 5120M; #4096M or 4G; 5120M or 5G;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_buffering off;
# This is needed for long running Python code. Default is 60 seconds
# Increased from 1200 to 1500 on 2022-04-17
fastcgi_connect_timeout 1500s;
fastcgi_send_timeout 1500s;
fastcgi_read_timeout 1500s;
proxy_read_timeout 1500s;
proxy_pass http://flask_backend;
}
}
upstream flask_backend {
# sticky sessions
ip_hash;
# enable least connections balancing method
# least_conn;
# zone backend 64k; # Use NGINX Plus' shared memory
# server webserver1 weight=1;
# server webserver2 weight=4;
# larger number will recieve more requests
# Example of 20 vs 10: 20 will recieve twice as many requests as 10
server aether_app_gunicorn:5005 weight=20 max_fails=3 fail_timeout=30s;
# server aether_app_gunicorn_bak:5005 weight=10 max_fails=1 fail_timeout=30s;
# maintain up to 20 idle connections to the group of upstream servers
# keepalive 20;
}

View File

@@ -0,0 +1,150 @@
server {
listen 80;
listen [::]:80;
server_name oneskyit.localhost;
access_log /logs/nginx/access_oneskyit.log;
# Do not overflow the SSL send buffer (causes extra round trips)
#ssl_buffer_size 8k;
root /srv/oneskyit_site;
index index.php index.html;
# index index.html index.htm index.php;
# include php.conf;
# include brotli.conf;
# include gzip.conf;
# include expires.conf;
# These two locations remove .html and .php from filenames.
location / {
try_files $uri $uri/ $uri.html $uri.php$is_args$query_string;
}
location ~ \.php$ {
root /srv/oneskyit_site;
# index index.html index.htm index.php;
try_files $uri =404;
# try_files $uri $document_root$fastcgi_script_name =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php7:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
# location ~ \.php$ {
# try_files $uri =404;
# }
}
# # Redirect http to https
# server {
# listen 80;
# listen [::]:80;
# server_name oneskyit.com;
# return 301 https://oneskyit.com$request_uri;
# }
#
# #upstream oneskyit {
# #least_conn;
# # ip_hash;
# #server localhost:8889;
# #server localhost:8889;
# #}
#
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name docker.oneskyit.com;
access_log /logs/nginx/access_oneskyit.log;
error_log /logs/nginx/error_oneskyit.log;
# Do not overflow the SSL send buffer (causes extra round trips)
#ssl_buffer_size 8k;
include /etc/nginx/options-ssl-nginx.conf;
ssl_certificate /etc/certs/fullchain.pem;
ssl_certificate_key /etc/certs/privkey.pem;
ssl_dhparam /etc/certs/ssl-dhparams.pem;
root /srv/oneskyit_site;
index index.php index.html;
#
# root /srv/http/oneskyit.com/;
# index index.php index.html;
#
# include php.conf;
# include brotli.conf;
# include gzip.conf;
# include expires.conf;
#
# These two locations remove .html and .php from filenames.
location / {
try_files $uri $uri/ $uri.html $uri.php$is_args$query_string;
}
location ~ \.php$ {
root /srv/oneskyit_site;
# index index.html index.htm index.php;
try_files $uri =404;
# try_files $uri $document_root$fastcgi_script_name =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php7:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
# location ~ \.php$ {
# try_files $uri =404;
# }
#
# #location / {
# # include uwsgi_params;
# # #uwsgi_pass oneskyit;
# # proxy_pass http://oneskyit;
# # #uwsgi_pass uwsgi://oneskyit.com:8889;
# #
# # #proxy_pass http://apptest;
# # #uwsgi_pass uwsgi://oneskyit.com:8890;
# # #uwsgi_pass uwsgi://oneskyit.com:8889;
# #}
#
# ssl_certificate /etc/letsencrypt/live/oneskyit.com/fullchain.pem; # managed by Certbot
# #ssl_certificate /etc/letsencrypt/live/oneskyit.com-0001/fullchain.pem; # managed by Certbot
# ssl_certificate_key /etc/letsencrypt/live/oneskyit.com/privkey.pem; # managed by Certbot
# #ssl_certificate_key /etc/letsencrypt/live/oneskyit.com-0001/privkey.pem; # managed by Certbot
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
#
# #ssl_session_cache shared:SSL:5m; # was 1m (1 MB)
# #ssl_session_timeout 1h; # was 5m (5 minutes)
#
# ssl_buffer_size 8k;
#
#
# if ($scheme != "https"){
# return 301 https://$host$request_uri;
# } # managed by Certbot
#
# }

60
conf/nginx/site.conf Normal file
View File

@@ -0,0 +1,60 @@
server {
listen 80;
server_name docker.localhost;
error_log /logs/nginx/error_docker.log;
access_log /logs/nginx/access_docker.log;
root /srv/html_php;
index index.html index.htm index.php;
# location / {
# # root /usr/share/nginx/html;
# index index.html index.htm;
# }
location ~ \.php$ {
index index.html index.htm index.php;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php7:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# root /usr/share/nginx/html;
# }
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

34
conf/nginx/uwsgi_params Normal file
View File

@@ -0,0 +1,34 @@
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
# From uWSGI documentation:
# https://uwsgi-docs.readthedocs.io/en/latest/Nginx.html
#uwsgi_param QUERY_STRING $query_string;
#uwsgi_param REQUEST_METHOD $request_method;
#uwsgi_param CONTENT_TYPE $content_type;
#uwsgi_param CONTENT_LENGTH $content_length;
#uwsgi_param REQUEST_URI $request_uri;
#uwsgi_param PATH_INFO $document_uri;
#uwsgi_param DOCUMENT_ROOT $document_root;
#uwsgi_param SERVER_PROTOCOL $server_protocol;
#uwsgi_param REMOTE_ADDR $remote_addr;
#uwsgi_param REMOTE_PORT $remote_port;
#uwsgi_param SERVER_ADDR $server_addr;
#uwsgi_param SERVER_PORT $server_port;
#uwsgi_param SERVER_NAME $server_name;

1
conf/php/custom_php5.ini Normal file
View File

@@ -0,0 +1 @@
max_file_uploads = 500M

1
conf/php/custom_php7.ini Normal file
View File

@@ -0,0 +1 @@
max_file_uploads = 500M

View File

@@ -0,0 +1,3 @@
<?php
$cfg['ShowPhpInfo'] = true; // Adds a link to phpinfo() on the home page

294
docker-compose.yml Normal file
View File

@@ -0,0 +1,294 @@
version: "3.9"
services:
web:
restart: unless-stopped
container_name: ae_web_dev
build:
# context: ./builds
context: ./
dockerfile: aether_nginx.Dockerfile
env_file:
- ./.env
environment:
# This does not seem to work (yet???)
- AE_DOMAIN_LIST:'dev-aapor.oneskyit.com dev-businessgroup.oneskyt.com dev-cmsc.oneskyit.com dev-idaa.oneskyit.com dev-ishlt.oneskyit.com dev-ncsd.oneskyit.com dev-npa.oneskyit.com dev-rli.oneskyit.com'
ports:
- "80:80"
- "443:443"
- "8181:80"
- "8443:443"
# networks:
# - local-net
volumes:
- ./srv/html_php:/srv/html_php
- ./srv/oneskyit_site:/srv/oneskyit_site
- ./srv/hosted_files_dev_link:/srv/hosted_files
- ./srv/hosted_tmp_dev_link:/srv/hosted_tmp
# NOTE: Nextcloud Docker container requires (sort of) the path to be /var/www/html
# - ./srv/nextcloud:/srv/nextcloud
# - ./srv/nextcloud/app:/var/www/html
# - ./srv/nextcloud/apps:/var/www/html/apps
# - ./srv/nextcloud/config:/var/www/html/config
# - ./srv/nextcloud/data:/var/www/html/data
- ./conf/nginx/options-ssl-nginx.conf:/etc/nginx/options-ssl-nginx.conf
- ./conf/nginx/site.conf:/etc/nginx/conf.d/site.conf
# - ./conf/nginx/site-enabled_aether-phpmyadmin.conf:/etc/nginx/conf.d/site-enabled_aether-phpmyadmin.conf
# - ./conf/nginx/site-enabled_aether-mailman2.conf:/etc/nginx/conf.d/site-enabled_aether-mailman2.conf
# - ./conf/nginx/site-enabled_aether-nextcloud.conf:/etc/nginx/conf.d/site-enabled_aether-nextcloud.conf
- ./conf/nginx/site-enabled_oneskyit.conf:/etc/nginx/conf.d/site-enabled_oneskyit.conf
- ./conf/nginx/site-enabled_aether_fastapi_gunicorn.conf:/etc/nginx/conf.d/site-enabled_aether_fastapi_gunicorn.conf
# - ./conf/nginx/site-enabled_aether_fastapi_2_gunicorn.conf:/etc/nginx/conf.d/site-enabled_aether_fastapi_2_gunicorn.conf
- ./conf/nginx/site-enabled_aether_flask_gunicorn.conf:/etc/nginx/conf.d/site-enabled_aether_flask_gunicorn.conf
- ./conf/certs/oneskyit.com_fullchain.pem:/etc/certs/fullchain.pem
- ./conf/certs/privkey.pem:/etc/certs/privkey.pem
- ./conf/certs/ssl-dhparams.pem:/etc/certs/ssl-dhparams.pem
- ./logs/web:/logs
# volumes_from:
# - nextcloud25
depends_on:
- php7
- aether_api_gunicorn
- aether_app_gunicorn
# links:
# # - nextcloud25
# - php7
# - aether_api_gunicorn
# - aether_app_gunicorn
# # - aether_api_gunicorn_bak
# stdin_open: true # docker run -i
# tty: true # docker run -t
# mailman2:
# image: d3fk/mailman2
# container_name: ae_mailman2
# # hostname: mails.oneskyit.com
# hostname: mail.localhost
# restart: unless-stopped
# ports:
# - "8889:80"
# # - "8443:443"
# - "2525:25"
# - "25465:465"
# - "25587:587"
# # env_file:
# # - ./conf/mailman2.env
# environment:
# - EMAIL_HOST=mail.oneskyit.com
# # - URL_HOST=lists.localhost
# - URL_HOST=mailman2-oneskyit.localhost
# - LIST_ADMIN=admin@oneskyit.com
# - MASTER_PASSWORD=strong_pass_321
# - URL_PATTERN=http
# # - SSL_FROM_CONTAINER="true"
# # - SSL_SELFSIGNED="true"
# # - ENABLE_SPF_CHECK="true"
# - URL_ROOT=lists/
# extra_hosts:
# - "mail.oneskyit.com:127.0.0.1"
# # - "oneskyit.com:the linode ip"
# volumes:
# - ./srv/mailman2/archives:/var/lib/mailman/archives
# - ./srv/mailman2/lists:/var/lib/mailman/lists
# - ./srv/mailman2/keys:/etc/exim4/tls.d
# - ./logs/mailman2/apache2:/var/log/apache2
# - ./logs/mailman2/exim4:/var/log/exim4
# - ./logs/mailman2/mailman:/var/log/mailman
# # - ./logs/mailman2/mailman_error.log:/var/lib/mailman/logs/error
#
# # - ./customcert.pem:/etc/ssl/certs/ssl-cert-snakeoil.pem
# # - ./customcertkey.key:/etc/ssl/private/ssl-cert-snakeoil.key
# php5:
# restart: always
# container_name: ae_php5_dev
# # image: php:5-fpm
# build:
# context: ./
# dockerfile: php5.Dockerfile
# volumes:
# - ./srv/html_php:/srv/html_php
#
# - ./conf/php/custom_php5.ini:/usr/local/etc/php/conf.d/custom_php5.ini
#
# - ./logs:/logs
# ports:
# - "9005:9000"
# # networks:
# # - local-net
php7:
restart: always
container_name: ae_php7_dev
# image: php:fpm
build:
context: ./
dockerfile: php7.Dockerfile
volumes:
- ./srv/html_php:/srv/html_php
- ./srv/oneskyit_site:/srv/oneskyit_site
# - ./srv/nextcloud:/srv/nextcloud
- ./conf/php/custom_php7.ini:/usr/local/etc/php/conf.d/custom_php7.ini
- ./logs/php7:/logs
# ports:
# - "9007:9000"
# networks:
# - local-net
# phpmyadmin:
# image: phpmyadmin
# container_name: ae_phpmyadmin
# restart: unless-stopped
# depends_on:
# - mariadb
# ports:
# - 8888:80
# env_file:
# - ./.env
# environment:
# - PMA_ARBITRARY=1
# - UPLOAD_LIMIT=1G
# mariadb:
# container_name: ae_mariadb_dev
# image: mariadb/server:latest
# restart: always
# # image: mariadb:10.6
# # env_file:
# # - ./.env
# # - filename.env
# ports:
# - "3307:3306"
# volumes:
# - ./srv/mariadb:/var/lib/mysql
# # - ./conf/mariadb/my.cnf:/etc/my.cnf
# environment:
# - MARIADB_ROOT_PASSWORD='MyPassword.1248'
# # - MARIADB_DATABASE: 'my_env_db'
# # - MYSQL_ROOT_PASSWORD=
# - MYSQL_PASSWORD=MyPassword
# - MYSQL_DATABASE=nextcloud
# - MYSQL_USER=nextcloud
# nextcloud25:
# container_name: ae_nextcloud25_dev
# build:
# # context: ./builds
# context: ./
# dockerfile: nextcloud25_fpm.Dockerfile
# # image: nextcloud:fpm
# restart: unless-stopped
# links:
# - mariadb
# depends_on:
# - mariadb
# volumes:
# - ./srv/nextcloud/app:/var/www/html
# - ./srv/nextcloud/apps:/var/www/html/apps
# - ./srv/nextcloud/custom_apps:/var/www/html/custom_apps
# - ./srv/nextcloud/config:/var/www/html/config
# - ./srv/nextcloud/data:/var/www/html/data
# - ./srv/nextcloud/themes:/var/www/html/themes
# environment:
# - MYSQL_PASSWORD=MyPassword.1248
# - MYSQL_DATABASE=nextcloud
# - MYSQL_USER=nextcloud
# - MYSQL_HOST=mariadb
# - NEXTCLOUD_TRUSTED_DOMAINS=oneskyit.com
redis:
container_name: ae_redis_dev
image: redis
ports:
# host to image
# default port is 6379
- "6389:6379"
aether_api_gunicorn:
restart: always
container_name: ae_api_dev
build:
# context: ./builds
context: ./
dockerfile: aether_fastapi_gunicorn.Dockerfile
env_file:
- ./.env
ports:
- "5065:5005"
# expose:
# - 5005
# networks:
# - local-net
volumes:
- ./conf/aether_fastapi_gunicorn_conf.py:/conf/gunicorn_fastapi_conf.py
- ./conf/aether_api_config.py:/srv/aether_api/app/config.py
- ./logs/ae_api:/logs
# - ./logs/ae_api/aether_fastapi_gunicorn.log:/logs/gunicorn.log
# - ./logs/aether_fastapi_gunicorn_access.log:/logs/gunicorn_access.log
# - ./logs/aether_fastapi_gunicorn_error.log:/logs/gunicorn_error.log
# - ./logs/aether_api.log:/logs/aether_api.log
# - ./logs/ae_api/aether_api.log.1:/logs/aether_api.log.1
# - ./logs/ae_api/aether_api.log.2:/logs/aether_api.log.2
# - ./logs/ae_api/aether_api.log.3:/logs/aether_api.log.3
# - ./logs/ae_api/aether_api.log.4:/logs/aether_api.log.4
# - ./logs/ae_api/aether_api.log.5:/logs/aether_api.log.5
# - ./logs/ae_api/aether_api_warning.log:/logs/aether_api_warning.log
- ./srv/aether_api_link:/srv/aether_api
- ./srv/hosted_files_dev_link:/srv/hosted_files
- ./srv/hosted_tmp_dev_link:/srv/hosted_tmp
# links:
# - redis
depends_on:
- redis
stdin_open: true # docker run -i
tty: true # docker run -t
aether_app_gunicorn:
restart: always
container_name: ae_app_dev
build:
# context: ./builds
context: ./
dockerfile: aether_flask_gunicorn.Dockerfile
# image: tiangolo/uvicorn-gunicorn:latest
env_file:
- ./.env
ports:
- "5055:5005"
# expose:
# - 5005
# networks:
# - local-net
extra_hosts:
- dev-api.oneskyit.com:192.168.32.20
volumes:
- ./conf/aether_flask_gunicorn_conf.py:/conf/gunicorn_flask_conf.py
- ./conf/aether_app_config.py:/srv/aether_app/flask_config_v2.py
- ./logs/ae_app:/logs
# - ./logs/aether_flask_gunicorn_access.log:/logs/gunicorn_access.log
# - ./logs/aether_flask_gunicorn_error.log:/logs/gunicorn_error.log
# - ./logs/aether_app.log:/logs/aether_app.log
# - ./logs/aether_app_warning.log:/logs/aether_app_warning.log
- ./srv/aether_app_link:/srv/aether_app
- ./srv/hosted_files_dev_link:/srv/hosted_files
- ./srv/hosted_tmp_dev_link:/srv/hosted_tmp
depends_on:
- aether_api_gunicorn
stdin_open: true # docker run -i
tty: true # docker run -t
# networks:
# local-net:
# driver: bridge

3
php5.Dockerfile Normal file
View File

@@ -0,0 +1,3 @@
# FROM php:5.6.20
FROM php:5-fpm
RUN docker-php-ext-install mysqli

2
php7.Dockerfile Normal file
View File

@@ -0,0 +1,2 @@
FROM php:7-fpm
RUN docker-php-ext-install mysqli

1
srv/aether_api_link Symbolic link
View File

@@ -0,0 +1 @@
/home/scott/OSIT_dev/aether_api_fastapi

1
srv/aether_app_link Symbolic link
View File

@@ -0,0 +1 @@
/home/scott/OSIT_dev/aether_app

1
srv/hosted_files_dev_link Symbolic link
View File

@@ -0,0 +1 @@
/mnt/data_drive/srv/data/osit_app/hosted_files_dev

1
srv/hosted_files_link Symbolic link
View File

@@ -0,0 +1 @@
/mnt/data_drive/srv/data/osit_app/hosted_files

1
srv/hosted_tmp_dev_link Symbolic link
View File

@@ -0,0 +1 @@
/mnt/data_drive/srv/data/osit_app/hosted_tmp_dev

1
srv/hosted_tmp_link Symbolic link
View File

@@ -0,0 +1 @@
/mnt/data_drive/srv/data/osit_app/hosted_tmp