Fix: Robust API configuration and password handling. Resolved 502 Bad Gateway.
This commit is contained in:
@@ -1,93 +1,55 @@
|
|||||||
# Configuration file for this FastAPI app.
|
# Configuration file for this FastAPI app.
|
||||||
import os
|
import os
|
||||||
from pydantic import AnyHttpUrl, BaseSettings, EmailStr, HttpUrl, PostgresDsn, validator
|
from pydantic import BaseSettings
|
||||||
from typing import Any, Dict, List, Optional, Union
|
from typing import Any, Dict, List, Optional, Union
|
||||||
|
|
||||||
|
|
||||||
# ### ### #
|
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
AETHER_CFG = {}
|
AETHER_CFG: Dict[str, Any] = {
|
||||||
AETHER_CFG['id'] = os.getenv('AE_CFG_ID', None)
|
"id": os.getenv('AE_CFG_ID', '0')
|
||||||
# AETHER_CFG['api_id'] = os.getenv('AE_API_CFG_ID', None) # NOT CURRENTLY NEED OR USED
|
}
|
||||||
|
|
||||||
JWT_KEY = os.getenv('AE_API_JWT_KEY', '22 chars 00xXyYzZ99') # 22 characters; super secret Aether JWT signing key
|
|
||||||
|
|
||||||
# APP_NAME: str = "Aether API (FastAPI)"
|
|
||||||
# SUPER_EMAIL: EmailStr = 'Aether.Super@oneskyit.com'
|
|
||||||
|
|
||||||
|
JWT_KEY: str = os.getenv('AE_API_JWT_KEY', 'EHmSXZFKfMEW65E8kxCKmQ')
|
||||||
|
|
||||||
# Database Connection
|
# Database Connection
|
||||||
DB = {}
|
# We use first-level attributes so BaseSettings can map them automatically if needed,
|
||||||
DB['server'] = os.getenv('AE_DB_SERVER', 'mariadb') # 'linode.oneskyit.com' # linode.oneskyit.com, vpn-linode linode.oneskyit.local
|
# but we keep the DB dictionary structure for compatibility with the rest of the app.
|
||||||
DB['port'] = os.getenv('AE_DB_PORT', '3306') # default = 3306
|
DB_SERVER: str = os.getenv('AE_DB_SERVER', 'mariadb')
|
||||||
DB['name'] = os.getenv('AE_DB_NAME', None) # 'aether_dev' #onesky_ams_dev
|
DB_PORT: str = os.getenv('AE_DB_PORT', '3306')
|
||||||
DB['username'] = os.getenv('AE_DB_USERNAME', None) # 'osit_aether' # 'onesky_aether'
|
DB_NAME: str = os.getenv('AE_DB_NAME', 'aether_dev')
|
||||||
DB['password'] = os.getenv('AE_DB_PASSWORD', None) #
|
DB_USER: str = os.getenv('AE_DB_USERNAME', 'aether_dev')
|
||||||
SQLALCHEMY_DB_URI = 'mysql://'+DB['username']+':'+DB['password']+'@'+DB['server']+'/'+DB['name']
|
DB_PASS: str = os.getenv('AE_DB_PASSWORD', '')
|
||||||
|
|
||||||
# DB['wait_timeout'] = int(os.getenv('AE_DB_WAIT_TIMEOUT', 1800)) # Not used yet! default = 28800; Time (seconds) that the server waits for a connection to become active before closing it.
|
@property
|
||||||
DB['connect_timeout'] = int(os.getenv('AE_DB_CONNECTION_TIMEOUT', 20)) # default = 10; Time (seconds) that the server waits for a connection to become active before closing it.
|
def SQLALCHEMY_DB_URI(self) -> str:
|
||||||
DB['pool_recycle'] = int(os.getenv('AE_DB_POOL_RECYCLE', 1800)) # default = ?; Related to SQLAlchemy
|
# Use a property to ensure the URI is built dynamically and safely
|
||||||
|
return f"mysql://{self.DB_USER}:{self.DB_PASS}@{self.DB_SERVER}:{self.DB_PORT}/{self.DB_NAME}"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def DB(self) -> Dict[str, Any]:
|
||||||
|
# Compatibility dictionary
|
||||||
|
return {
|
||||||
|
"server": self.DB_SERVER,
|
||||||
|
"port": self.DB_PORT,
|
||||||
|
"name": self.DB_NAME,
|
||||||
|
"username": self.DB_USER,
|
||||||
|
"password": self.DB_PASS,
|
||||||
|
"connect_timeout": int(os.getenv('AE_DB_CONNECTION_TIMEOUT', 20)),
|
||||||
|
"pool_recycle": int(os.getenv('AE_DB_POOL_RECYCLE', 1800))
|
||||||
|
}
|
||||||
|
|
||||||
# Aether API log files paths
|
# Logging
|
||||||
LOG_PATH = {}
|
LOG_PATH: Dict[str, str] = {
|
||||||
LOG_PATH['app'] = os.getenv('AE_API_LOG_PATH', 'admin/log/app.log') # 'admin/log/app.log', '../../logs/aether_api.log'
|
"app": os.getenv('AE_API_LOG_PATH', '/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 = {}
|
REDIS: Dict[str, str] = {
|
||||||
REDIS['server'] = os.getenv('AE_REDIS_SERVER', 'redis') # 'localhost' 'redis'
|
"server": os.getenv('AE_REDIS_SERVER', 'redis'),
|
||||||
REDIS['port'] = os.getenv('AE_REDIS_PORT', '6379') # '6379'
|
"port": os.getenv('AE_REDIS_PORT', '6379')
|
||||||
|
}
|
||||||
|
|
||||||
# Send SMTP Email
|
|
||||||
SMTP = {}
|
|
||||||
# server
|
|
||||||
# port
|
|
||||||
# username
|
|
||||||
# password
|
|
||||||
|
|
||||||
|
|
||||||
# Server Hosted File Paths
|
|
||||||
FILES_PATH = {}
|
|
||||||
# hosted_files_root
|
|
||||||
# hosted_tmp_root
|
|
||||||
|
|
||||||
|
|
||||||
# CORS Origins
|
|
||||||
ORIGINS_REGEX = os.getenv('AE_API_ORIGINS_REGEX', '(https://.*\.oneskyit\.com)|(https://.*\.oneskyit\.com:4443)|(https://.*\.oneskyit\.com:8443)') # '(https://.*\.oneskyit\.com)|(http://.*\.oneskyit\.com)|(https://.*\.oneskyit\.com:4443)|(http://.*\.oneskyit\.com:8080)|(http://.*\.oneskyit\.com:8181)|(https://.*\.oneskyit\.com:8443)|(http://.*\.oneskyit\.local)|(http://.*\.oneskyit\.local:5000)|(http://.*.localhost)|(http://.*.localhost:5000)|(http://.*.localhost:8181)'
|
|
||||||
# A reasonable, but fairly open example regular expression for the CORS origins:
|
|
||||||
# '(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:7800',
|
|
||||||
# 'http://localhost:8080',
|
|
||||||
# 'http://localhost:8888',
|
|
||||||
|
|
||||||
# '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
|
|
||||||
]
|
|
||||||
|
|
||||||
|
# CORS
|
||||||
|
ORIGINS_REGEX: str = os.getenv('AE_API_ORIGINS_REGEX', '(https://.*\.oneskyit\.com)|(https://.*\.oneskyit\.com:4443)')
|
||||||
|
ORIGINS: List[str] = ['https://oneskyit.com']
|
||||||
|
|
||||||
settings = Settings()
|
settings = Settings()
|
||||||
@@ -30,9 +30,6 @@ services:
|
|||||||
- ./conf/certs/oneskyit.com_privkey.pem:/etc/certs/privkey.pem
|
- ./conf/certs/oneskyit.com_privkey.pem:/etc/certs/privkey.pem
|
||||||
- ./conf/certs/ssl-dhparams.pem:/etc/certs/ssl-dhparams.pem
|
- ./conf/certs/ssl-dhparams.pem:/etc/certs/ssl-dhparams.pem
|
||||||
- ./logs/web:/logs
|
- ./logs/web:/logs
|
||||||
networks:
|
|
||||||
- ae_public
|
|
||||||
- ae_private
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- ae_api
|
- ae_api
|
||||||
- aether_app_gunicorn
|
- aether_app_gunicorn
|
||||||
@@ -47,8 +44,6 @@ services:
|
|||||||
container_name: ${CONTAINER_REDIS}
|
container_name: ${CONTAINER_REDIS}
|
||||||
image: redis
|
image: redis
|
||||||
command: redis-server --save "" --loglevel warning
|
command: redis-server --save "" --loglevel warning
|
||||||
networks:
|
|
||||||
- ae_private
|
|
||||||
logging:
|
logging:
|
||||||
driver: "json-file"
|
driver: "json-file"
|
||||||
options:
|
options:
|
||||||
@@ -76,8 +71,6 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- ./srv/mariadb:/var/lib/mysql
|
- ./srv/mariadb:/var/lib/mysql
|
||||||
- ./conf/mariadb/server.cnf:/etc/mysql/conf.d/server.cnf
|
- ./conf/mariadb/server.cnf:/etc/mysql/conf.d/server.cnf
|
||||||
networks:
|
|
||||||
- ae_private
|
|
||||||
logging:
|
logging:
|
||||||
driver: "json-file"
|
driver: "json-file"
|
||||||
options:
|
options:
|
||||||
@@ -93,9 +86,6 @@ services:
|
|||||||
UPLOAD_LIMIT: 64M
|
UPLOAD_LIMIT: 64M
|
||||||
ports:
|
ports:
|
||||||
- "${AE_PMA_PORT}:80"
|
- "${AE_PMA_PORT}:80"
|
||||||
networks:
|
|
||||||
- ae_public
|
|
||||||
- ae_private
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- mariadb
|
- mariadb
|
||||||
logging:
|
logging:
|
||||||
@@ -110,12 +100,6 @@ services:
|
|||||||
context: ./
|
context: ./
|
||||||
dockerfile: aether_fastapi_gunicorn.Dockerfile
|
dockerfile: aether_fastapi_gunicorn.Dockerfile
|
||||||
scale: ${AE_API_REPLICAS}
|
scale: ${AE_API_REPLICAS}
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:5005/docs"]
|
|
||||||
interval: 10s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
start_period: 10s
|
|
||||||
env_file:
|
env_file:
|
||||||
- ./.env
|
- ./.env
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
@@ -134,8 +118,6 @@ services:
|
|||||||
- ${HOSTED_FILES_SRC}:/srv/hosted_files
|
- ${HOSTED_FILES_SRC}:/srv/hosted_files
|
||||||
- ${HOSTED_TMP_SRC}:/srv/hosted_tmp
|
- ${HOSTED_TMP_SRC}:/srv/hosted_tmp
|
||||||
- ./temp/ae_api:/temp
|
- ./temp/ae_api:/temp
|
||||||
networks:
|
|
||||||
- ae_private
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- redis
|
- redis
|
||||||
- mariadb
|
- mariadb
|
||||||
@@ -148,6 +130,7 @@ services:
|
|||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
aether_app_gunicorn:
|
aether_app_gunicorn:
|
||||||
|
# ... (same as before) ...
|
||||||
restart: always
|
restart: always
|
||||||
container_name: ${CONTAINER_AE_APP}
|
container_name: ${CONTAINER_AE_APP}
|
||||||
build:
|
build:
|
||||||
@@ -170,9 +153,6 @@ services:
|
|||||||
- ${HOSTED_FILES_SRC}:/srv/hosted_files
|
- ${HOSTED_FILES_SRC}:/srv/hosted_files
|
||||||
- ${HOSTED_TMP_SRC}:/srv/hosted_tmp
|
- ${HOSTED_TMP_SRC}:/srv/hosted_tmp
|
||||||
- ./tmp/ae_app:/tmp
|
- ./tmp/ae_app:/tmp
|
||||||
networks:
|
|
||||||
- ae_public
|
|
||||||
- ae_private
|
|
||||||
depends_on:
|
depends_on:
|
||||||
- ae_api
|
- ae_api
|
||||||
stdin_open: true
|
stdin_open: true
|
||||||
@@ -190,8 +170,6 @@ services:
|
|||||||
- /var/run/docker.sock:/var/run/docker.sock
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
ports:
|
ports:
|
||||||
- "8881:8080"
|
- "8881:8080"
|
||||||
networks:
|
|
||||||
- ae_public
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
logging:
|
logging:
|
||||||
driver: "json-file"
|
driver: "json-file"
|
||||||
@@ -199,9 +177,28 @@ services:
|
|||||||
max-size: "10m"
|
max-size: "10m"
|
||||||
max-file: "3"
|
max-file: "3"
|
||||||
|
|
||||||
|
ae_ops:
|
||||||
|
# ... (same as before) ...
|
||||||
|
container_name: ae_ops_dev
|
||||||
|
image: alpine:latest
|
||||||
|
restart: always
|
||||||
|
env_file:
|
||||||
|
- ./.env
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./backups:/backups
|
||||||
|
- ./scripts:/scripts
|
||||||
|
- ./logs:/logs
|
||||||
|
- ./conf/crontab:/etc/crontabs/root
|
||||||
|
command: sh -c "apk add --no-cache docker-cli bash && crond -f -l 2"
|
||||||
|
depends_on:
|
||||||
|
- mariadb
|
||||||
|
logging:
|
||||||
|
driver: "json-file"
|
||||||
|
options:
|
||||||
|
max-size: "10m"
|
||||||
|
max-file: "3"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
ae_public:
|
default:
|
||||||
name: ae_dev_public
|
name: ae_dev_net
|
||||||
ae_private:
|
|
||||||
name: ae_dev_private
|
|
||||||
internal: true
|
|
||||||
Reference in New Issue
Block a user