Compare commits

..

3 Commits

Author SHA1 Message Date
Mateusz Gruszczyński
6fc91198a0 switch to debian in docker 2026-03-20 09:48:42 +01:00
Mateusz Gruszczyński
92eb925c94 switch to debian in docker 2026-03-20 09:41:08 +01:00
Mateusz Gruszczyński
51da117ab4 switch to debian in docker 2026-03-20 09:40:56 +01:00
5 changed files with 83 additions and 8 deletions

View File

@@ -88,8 +88,6 @@ APP_DOMAIN=ksef.local:8785 ./deploy_docker.sh
## Konta ## Konta
Nie ma już wymogu seedów do logowania. Użyj CLI:
```bash ```bash
flask --app run.py create-company flask --app run.py create-company
flask --app run.py create-user flask --app run.py create-user

View File

@@ -1,11 +1,12 @@
from dotenv import load_dotenv import time
from pathlib import Path from pathlib import Path
from dotenv import load_dotenv
from flask import Flask, render_template, request, url_for from flask import Flask, render_template, request, url_for
from flask_login import current_user from flask_login import current_user
from werkzeug.middleware.proxy_fix import ProxyFix
from dotenv import load_dotenv
from sqlalchemy import inspect, text from sqlalchemy import inspect, text
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import OperationalError, SQLAlchemyError
from werkzeug.middleware.proxy_fix import ProxyFix
from config import Config from config import Config
from redis.exceptions import RedisError from redis.exceptions import RedisError
from app.cli import register_cli from app.cli import register_cli
@@ -30,7 +31,25 @@ def _ensure_column(table_name: str, column_name: str, ddl: str):
db.session.commit() db.session.commit()
def _wait_for_database(app, attempts: int = 30, delay: float = 1.0) -> bool:
for attempt in range(1, attempts + 1):
try:
with db.engine.connect() as conn:
conn.execute(text('SELECT 1'))
if attempt > 1:
app.logger.info('Database became available after %s attempt(s).', attempt)
return True
except OperationalError:
app.logger.warning('Database not ready yet (%s/%s). Waiting...', attempt, attempts)
time.sleep(delay)
return False
def _bootstrap_database(app): def _bootstrap_database(app):
if not _wait_for_database(app):
app.logger.error('Database is still unavailable after waiting. Skipping bootstrap.')
return
try: try:
db.create_all() db.create_all()
patches = [ patches = [

View File

@@ -8,6 +8,7 @@ from pathlib import Path
import psutil import psutil
from flask import current_app from flask import current_app
from sqlalchemy import inspect from sqlalchemy import inspect
from sqlalchemy.engine import make_url
from app.extensions import db from app.extensions import db
from app.models.audit_log import AuditLog from app.models.audit_log import AuditLog
@@ -199,19 +200,52 @@ class SystemDataService:
continue continue
count = db.session.execute(db.select(db.func.count()).select_from(table)).scalar() or 0 count = db.session.execute(db.select(db.func.count()).select_from(table)).scalar() or 0
table_rows.append({'table': table_name, 'rows': int(count)}) table_rows.append({'table': table_name, 'rows': int(count)})
uri = current_app.config.get('SQLALCHEMY_DATABASE_URI', '') uri = current_app.config.get('SQLALCHEMY_DATABASE_URI', '')
sqlite_path = None sqlite_path = None
sqlite_size = None sqlite_size = None
db_driver = None
db_host = None
db_port = None
db_name = None
db_user = None
try:
url = make_url(uri)
db_driver = url.drivername
db_host = url.host
db_port = url.port
db_name = url.database
db_user = url.username
except Exception:
pass
if uri.startswith('sqlite:///') and not uri.endswith(':memory:'): if uri.startswith('sqlite:///') and not uri.endswith(':memory:'):
sqlite_path = uri.replace('sqlite:///', '', 1) sqlite_path = uri.replace('sqlite:///', '', 1)
try: try:
sqlite_size = self._human_size(Path(sqlite_path).stat().st_size) sqlite_size = self._human_size(Path(sqlite_path).stat().st_size)
except FileNotFoundError: except FileNotFoundError:
sqlite_size = 'brak pliku' sqlite_size = 'brak pliku'
if engine.name == 'sqlite':
db_label = 'SQLite'
elif engine.name == 'postgresql':
db_label = 'PostgreSQL'
elif engine.name == 'mysql':
db_label = 'MySQL'
else:
db_label = engine.name
table_rows_sorted = sorted(table_rows, key=lambda item: (-item['rows'], item['table'])) table_rows_sorted = sorted(table_rows, key=lambda item: (-item['rows'], item['table']))
return { return {
'engine': engine.name, 'engine': engine.name,
'engine_label': db_label,
'driver': db_driver,
'uri': self._mask_uri(uri), 'uri': self._mask_uri(uri),
'host': db_host,
'port': db_port,
'database': db_name,
'username': db_user,
'tables_count': len(table_rows), 'tables_count': len(table_rows),
'sqlite_path': sqlite_path, 'sqlite_path': sqlite_path,
'sqlite_size': sqlite_size, 'sqlite_size': sqlite_size,

View File

@@ -12,13 +12,25 @@ services:
- ./:/app - ./:/app
- ./db/sqlite:/app/db/sqlite - ./db/sqlite:/app/db/sqlite
depends_on: depends_on:
- redis redis:
condition: service_healthy
postgres:
condition: service_healthy
required: false
mysql:
condition: service_healthy
required: false
restart: unless-stopped restart: unless-stopped
redis: redis:
image: redis:7-alpine image: redis:7-alpine
ports: ports:
- "6379:6379" - "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 20
restart: unless-stopped restart: unless-stopped
postgres: postgres:
@@ -30,9 +42,14 @@ services:
POSTGRES_PASSWORD: ${DB_PASSWORD:-ksef} POSTGRES_PASSWORD: ${DB_PASSWORD:-ksef}
TZ: ${APP_TIMEZONE:-Europe/Warsaw} TZ: ${APP_TIMEZONE:-Europe/Warsaw}
volumes: volumes:
- ./db/pgsql:/var/lib/postgresql/data - ./db/pgsql:/var/lib/postgresql
ports: ports:
- "${DB_PORT:-5432}:5432" - "${DB_PORT:-5432}:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-ksef} -d ${DB_NAME:-ksef}"]
interval: 5s
timeout: 5s
retries: 20
restart: unless-stopped restart: unless-stopped
mysql: mysql:
@@ -49,6 +66,11 @@ services:
- ./db/mysql:/var/lib/mysql - ./db/mysql:/var/lib/mysql
ports: ports:
- "${DB_PORT:-3306}:3306" - "${DB_PORT:-3306}:3306"
healthcheck:
test: ["CMD-SHELL", "mysqladmin ping -h 127.0.0.1 -uroot -p${MYSQL_ROOT_PASSWORD:-root} --silent"]
interval: 5s
timeout: 5s
retries: 20
restart: unless-stopped restart: unless-stopped
caddy: caddy:

View File

@@ -43,6 +43,8 @@ def test_admin_system_data_page(auth_client, monkeypatch):
assert 'Połączenie CEIDG' in body assert 'Połączenie CEIDG' in body
assert 'Proces i health systemu' in body assert 'Proces i health systemu' in body
assert 'Użytkownicy' in body assert 'Użytkownicy' in body
assert 'Typ bazy:' in body
assert 'Silnik SQLAlchemy:' in body
assert 'Diagnoza' not in body assert 'Diagnoza' not in body
assert 'Co sprawdzić' not in body assert 'Co sprawdzić' not in body