Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

# FreeIPA
IPA_SERVER_HOSTNAME=
IPA_PASSWORD=

# PostgreSQL
POSTGRES_DB=
POSTGRES_USER=
POSTGRES_PASSWORD=

# tMatch
LDAP_HOST=
LDAP_PORT=
LDAP_USER=
LDAP_PASSWORD=
LDAP_BASE_DN=

SMTP_SERVER=
SMTP_PORT=
SMTP_USERNAME=
SMTP_PASSWORD=
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@

.env
srv/
certs/
src/**/__pycache__
src/specs/*
Expand Down
117 changes: 38 additions & 79 deletions compose.yml
Original file line number Diff line number Diff line change
@@ -1,124 +1,83 @@

services:
freeipa:
image: freeipa/freeipa-server:almalinux-10
container_name: freeipa-server
hostname: ipa.example.test
hostname: auth-tmatch.isc-vs.dev
tty: true
stdin_open: true

privileged: false
cap_add:
- SYS_ADMIN
security_opt:
- seccomp=unconfined
- apparmor=unconfined

cgroup: host


environment:
- IPA_SERVER_HOSTNAME=ipa.example.test
- PASSWORD=thaitiePh5Haevie0cah
- SYSTEMD_SECCOMP=0

- IPA_SERVER_HOSTNAME=${IPA_SERVER_HOSTNAME}
- PASSWORD=${IPA_PASSWORD}

volumes:
- ./ipa_data:/data:Z
- /sys/fs/cgroup:/sys/fs/cgroup:rw

- ./srv/freeipa-data:/data:Z

tmpfs:
- /run
- /tmp
- /var/lib/journal
- /run/lock


ports:
- "3180:80"
- "31443:443"
- "31389:389"
- "31636:636"
- "3188:88"
- "3188:88/udp"
- "31464:464"
- "31464:464/udp"

- "12343:443"
- "12389:389"
- "12336:636"

command:
- ipa-server-install
- -U
- -r
- EXAMPLE.TEST
- TMATCH.ISC-VS.DEV
- --domain
- example.test
- tmatch.isc-vs.dev
- --no-ntp
- --no-host-dns
- --skip-mem-check

restart: unless-stopped

keycloak:
image: quay.io/keycloak/keycloak:26.5.3
container_name: keycloak-server
environment:
- KC_BOOTSTRAP_ADMIN_USERNAME=admin
- KC_BOOTSTRAP_ADMIN_PASSWORD=admin
- KC_DB=postgres
- KC_DB_URL_HOST=keycloak-db
- KC_DB_URL_DATABASE=keycloak
- KC_DB_USERNAME=keycloak
- KC_DB_PASSWORD=0291040404
- KC_HOSTNAME=ipa.example.test
- KC_HTTPS_CERTIFICATE_FILE=/opt/keycloak/conf/server.crt
- KC_HTTPS_CERTIFICATE_KEY_FILE=/opt/keycloak/conf/server.key
volumes:
- /srv/tmatch/keycloak/providers:/opt/keycloak/providers
- /srv/tmatch/keycloak/themes:/opt/keycloak/themes
- ./certs/server.crt:/opt/keycloak/conf/server.crt
- ./certs/server.key:/opt/keycloak/conf/server.key
ports:
- "3181:8080"
- "31443:8443"
command:
- start
restart: unless-stopped
depends_on:
- keycloak-db
- freeipa

keycloak-db:
image: postgres:16-alpine
container_name: keycloak_db
environment:
- POSTGRES_DB=keycloak
- POSTGRES_USER=keycloak
- POSTGRES_PASSWORD=nieM1ui7ak9sheitohsh
volumes:
- ./keycloak_data:/var/lib/postgresql/data
restart: unless-stopped

tmatch_db:
image: postgres:16-alpine
container_name: tmatch_db
environment:
- POSTGRES_DB=tmatch_db
- POSTGRES_USER=tmatch
- POSTGRES_PASSWORD=Oochoghahp6ie7aiza9p
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
ports:
- "3132:5432"
restart: unless-stopped
volumes:
- tmatch_db_data:/var/lib/postgresql/data
- ./srv/tmatch_db_data:/var/lib/postgresql/data

tmatch_app:
build: .
container_name: tmatch_app
restart: unless-stopped
environment:
- LDAP_HOST=${LDAP_HOST}
- LDAP_PORT=${LDAP_PORT}
- LDAP_USER=${LDAP_USER}
- LDAP_PASSWORD=${LDAP_PASSWORD}
- LDAP_BASE_DN=${LDAP_BASE_DN}

- SMTP_SERVER=${SMTP_SERVER}
- SMTP_PORT=${SMTP_PORT}
- SMTP_USERNAME=${SMTP_USERNAME}
- SMTP_PASSWORD=${SMTP_PASSWORD}

- DB_NAME=${POSTGRES_DB}
- DB_USER=${POSTGRES_USER}
- DB_PASSWORD=${POSTGRES_PASSWORD}
ports:
- "8084:8501"
depends_on:
- tmatch_db
- freeipa
volumes:
- tmatch_specs_data:/app/specs
- ./srv/tmatch_specs_data:/app/specs

volumes:
tmatch_specs_data:
tmatch_db_data:
tmatch_specs_data:
tmatch_db_data:
tmatch_keycloak_data:
7 changes: 5 additions & 2 deletions dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ WORKDIR /app
COPY src/pyproject.toml src/uv.lock .
RUN uv sync --frozen --no-install-project

COPY src/* .
COPY src/ .

RUN uv sync --frozen

CMD ["uv", "run", "streamlit", "run", "main.py"]
COPY entrypoint.sh ./
RUN chmod +x entrypoint.sh

CMD ["sh", "./entrypoint.sh"]

12 changes: 12 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#!/bin/sh
set -e

echo "Running migrations..."
uv run alembic upgrade head

echo "Seeding database..."
uv run python seed.py

echo "Starting app..."
exec uv run streamlit run main.py
3 changes: 3 additions & 0 deletions src/alembic/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@

from alembic import context

from config import DATABASE_URL
from models import Base

# this is the Alembic Config object, which provides
# access to the values within the .ini file in use.
config = context.config

config.set_main_option("sqlalchemy.url", DATABASE_URL)

# Interpret the config file for Python logging.
# This line sets up loggers basically.
if config.config_file_name is not None:
Expand Down
8 changes: 4 additions & 4 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import streamlit as st
from services.auth import validate_session
from services.db import get_db
from utils.nav import PAGE_ROLES, PAGE_CONFIG, allowed, landing_page, login_page
from utils.nav import PAGE_ROLES, PAGE_CONFIG, allowed, projects_page, login_page

st.session_state.session = validate_session()

Expand Down Expand Up @@ -50,15 +50,15 @@ def set_program():
st.session_state.program_id = program_id

if len(roles) == 0:
page_list = [landing_page]
page_list = [projects_page]
else:
page_list = [landing_page] + [
page_list = [
PAGE_CONFIG[page_name]
for page_name, allowed_roles in PAGE_ROLES.items()
if allowed(roles, allowed_roles)
]
if not page_list:
page_list = [landing_page]
page_list = [projects_page]

else:
page_list = [login_page]
Expand Down
25 changes: 25 additions & 0 deletions src/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os

# PostgreSQL
DB_HOST = "tmatch_db"
DB_PORT = 5432
DB_NAME = os.environ.get("DB_NAME", "")
DB_USER = os.environ.get("DB_USER", "")
DB_PASSWORD = os.environ.get("DB_PASSWORD", "")

DATABASE_URL = (
f"postgresql+psycopg://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
)

# LDAP
LDAP_HOST = os.environ.get("LDAP_HOST", "")
LDAP_PORT = os.environ.get("LDAP_PORT", "")
LDAP_USER = os.environ.get("LDAP_USER", "")
LDAP_PASSWORD = os.environ.get("LDAP_PASSWORD", "")
LDAP_BASE_DN = os.environ.get("LDAP_BASE_DN", "")

# Email
SMTP_SERVER = os.environ.get("SMTP_SERVER", "")
SMTP_PORT = int(os.environ.get("SMTP_PORT", 587))
SMTP_USERNAME = os.environ.get("SMTP_USERNAME", "")
SMTP_PASSWORD = os.environ.get("SMTP_PASSWORD", "")
25 changes: 25 additions & 0 deletions src/seed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

from sqlalchemy.orm import sessionmaker
from models.role import Role
from seeds.keywords import create_keywords
from seeds.programs import create_programs
from seeds.roles import create_roles

from seeds.engine import engine

Session = sessionmaker(bind=engine)
session = Session()

with session as s:
if s.query(Role).count() > 0:
print("Database already seeded. Skipping.")
exit(0)

create_roles()
print("Created roles")

create_keywords()
print("Created keywords")

create_programs()
print("Created programs")
4 changes: 0 additions & 4 deletions src/seed/engine.py

This file was deleted.

20 changes: 0 additions & 20 deletions src/seed/roles.py

This file was deleted.

13 changes: 0 additions & 13 deletions src/seed/seed.py

This file was deleted.

5 changes: 5 additions & 0 deletions src/seeds/engine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

from sqlalchemy import create_engine
from config import DATABASE_URL

engine = create_engine(DATABASE_URL)
13 changes: 7 additions & 6 deletions src/seed/keywords.py → src/seeds/keywords.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from sqlalchemy.orm import sessionmaker

from models.keyword import Keyword
from seed.engine import engine
from seeds.engine import engine

Session = sessionmaker(bind=engine)
session = Session()

def create_keywords():
keywords = [
Expand Down Expand Up @@ -86,8 +85,10 @@ def create_keywords():
"forecasting",
]

for i in range(len(keywords)):
new_keyword = Keyword(name=keywords[i])
with Session() as s:
for i in range(len(keywords)):
new_keyword = Keyword(name=keywords[i])

session.add(new_keyword)
session.commit()
s.add(new_keyword)

s.commit()
Loading
Loading