Skip to content

Commit 56c06e1

Browse files
authored
Merge pull request #2 from OzPol/docker-setup
Docker setup
2 parents 72b8adc + 6e89efe commit 56c06e1

10 files changed

+968
-3
lines changed

.dockerignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
__pycache__/
2+
*.pyc
3+
*.pyo
4+
*.pyd
5+
venv/
6+
.venv

.gitignore

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# Distribution / packaging
7+
.Python
8+
build/
9+
develop-eggs/
10+
dist/
11+
downloads/
12+
eggs/
13+
.eggs/
14+
lib/
15+
lib64/
16+
parts/
17+
sdist/
18+
var/
19+
wheels/
20+
share/python-wheels/
21+
*.egg-info/
22+
.installed.cfg
23+
*.egg
24+
MANIFEST
25+
26+
# Unit test / coverage reports
27+
htmlcov/
28+
.tox/
29+
.nox/
30+
.coverage
31+
.coverage.*
32+
.cache
33+
nosetests.xml
34+
coverage.xml
35+
*.cover
36+
*.py,cover
37+
.hypothesis/
38+
.pytest_cache/
39+
cover/
40+
41+
# Jupyter Notebook
42+
.ipynb_checkpoints
43+
44+
# Environments
45+
.venv
46+
env/
47+
venv/
48+
ENV/
49+
env.bak/
50+
venv.bak/
51+
52+
# env
53+
.env
54+
55+
### macOS ###
56+
.DS_Store
57+
.AppleDouble
58+
.LSOverride

Dockerfile

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
FROM python:3.12-slim
2+
3+
WORKDIR /app
4+
5+
# installation of only the necessary dependencies for linux
6+
# this helps to keep the container lightweight
7+
RUN apt-get update && apt-get install -y \
8+
curl \
9+
libpq-dev \
10+
postgresql-client \
11+
gcc \
12+
&& rm -rf /var/lib/apt/lists/*
13+
14+
RUN pip install poetry
15+
16+
RUN poetry config virtualenvs.create false
17+
18+
COPY pyproject.toml poetry.lock ./
19+
20+
RUN poetry install --no-interaction --no-root --no-cache
21+
22+
COPY . .
23+
24+
EXPOSE 8000
25+
26+
CMD ["poetry", "run", "python", "app.py"]

README.md

+91
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,93 @@
11
# cybergator
2+
23
CyberGator: A Dynamic Framework for Cyber Resilience Assessment
4+
5+
## Project Overview
6+
7+
CyberGator is a cyber resilience assessment framework designed for dynamic risk evaluation, attack simulation, and adaptive defense strategy generation. It integrates Flask, Plotly Dash, Neo4j, PostgreSQL (via Supabase), and AI-driven simulations to model and improve system resilience against Advanced Persistent Threats (APTs).
8+
9+
---
10+
11+
## Pre-requisites
12+
13+
- **[Docker](https://www.docker.com/get-started)**
14+
- **[Docker Compose](https://docs.docker.com/compose/install/)**
15+
- **[Python >= 3.12](https://www.datacamp.com/blog/how-to-install-python)**
16+
- **[Poetry](https://python-poetry.org/docs/#installation)**
17+
18+
Verify installations:
19+
20+
`docker --version`
21+
22+
`poetry --version`
23+
24+
---
25+
26+
## Running the Application (Development)
27+
28+
1. Clone the Repository
29+
30+
```
31+
git clone [email protected]:OzPol/cybergator.git
32+
cd cybergator
33+
```
34+
35+
2. Create your .env file
36+
Your .env file should be placed in the root of the project (same level as the Dockerfile)
37+
38+
3. Make sure your Docker desktop is running! :)
39+
40+
4. Build the container
41+
42+
```
43+
docker-compose build
44+
```
45+
46+
5. Run the container
47+
48+
```
49+
docker-compose up
50+
```
51+
52+
6. Check the homepage in the browser
53+
54+
```
55+
http://localhost:8000
56+
```
57+
58+
7. When you are done, you can stop the container
59+
60+
```
61+
docker-compose down
62+
```
63+
64+
### Important Notes
65+
66+
- In general, you only need to rebuild the container when there are changes to dependencies.
67+
- It's recommended to install dependencies INSIDE the container to avoid issues. Your local `poetry.lock` and `pyproject.toml` files will be automatically updated :) You can find detailed instructions for this in the next section.
68+
69+
## How to add and install new depencies to the application
70+
71+
1. Run the container in detached mode:
72+
73+
```
74+
docker-compose up -d
75+
```
76+
77+
2. Install the dependency/package
78+
79+
```
80+
docker exec -it cybergator_app poetry add <your-package-name>
81+
```
82+
83+
3. Rebuild and run the container
84+
85+
```
86+
docker-compose up --build
87+
```
88+
89+
4. Optional - clean old images
90+
91+
```
92+
docker image prune -f
93+
```

app.py

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import dash
2+
from dash import html
3+
from app.databases.psql_db import get_sql_connection
4+
from app.databases.neo4j_db import run_query
5+
6+
app = dash.Dash(__name__)
7+
8+
# This is test code for testing supabase connection
9+
# Should move away once we start creatign actual functionality...
10+
conn = get_sql_connection()
11+
12+
psql_status = "Error: Unable to connect to Supabase."
13+
if conn:
14+
try:
15+
cursor = conn.cursor()
16+
cursor.execute("SELECT NOW();")
17+
result = cursor.fetchone()
18+
print("Supabase Current Time:", result[0])
19+
20+
psql_status = f"Supabase Current Time: {result[0]}"
21+
22+
except Exception as e:
23+
print("Supabase query error:", e)
24+
psql_status = "Error: Unable to fetch time from Supabase."
25+
26+
finally:
27+
cursor.close()
28+
conn.close()
29+
30+
# Test Neo4j Connection
31+
neo4j_status = "Error: Unable to connect to Neo4j."
32+
try:
33+
result = run_query("MATCH (n) RETURN count(n) AS node_count")
34+
node_count = result[0]['node_count'] if result else 0
35+
print(f"Neo4j Node Count: {node_count}")
36+
37+
neo4j_status = f"Neo4j Node Count: {node_count}"
38+
39+
except Exception as e:
40+
print("Neo4j connection error:", e)
41+
neo4j_status = "Error: Unable to fetch data from Neo4j."
42+
43+
# Define Test Dash Layout
44+
app.layout = html.Div([
45+
html.H1("Database Connection Test"),
46+
html.P(psql_status),
47+
html.P(neo4j_status)
48+
])
49+
50+
# --- Run Dash App ---
51+
if __name__ == "__main__":
52+
app.run_server(debug=True, host="0.0.0.0", port=8000)
53+

app/databases/neo4j_db.py

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import os
2+
from dotenv import load_dotenv
3+
from neo4j import GraphDatabase
4+
5+
load_dotenv()
6+
7+
NEO4J_URI = os.getenv("NEO4J_URI")
8+
NEO4J_USER = os.getenv("NEO4J_USER")
9+
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")
10+
11+
def get_neo4j_connection():
12+
"""Returns a Neo4j database connection."""
13+
try:
14+
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
15+
driver.verify_connectivity
16+
print("✅ Neo4j Aura Connection successful!")
17+
return driver
18+
except Exception as e:
19+
print("❌ Neo4j connection error", e)
20+
return None
21+
22+
def run_query(query, parameters=None):
23+
"""Runs a Cypher query and returns results."""
24+
driver = get_neo4j_connection()
25+
if driver is None:
26+
return []
27+
28+
with driver.session() as session:
29+
results = session.run(query, parameters).data()
30+
31+
driver.close()
32+
return results

app/databases/psql_db.py

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import os
2+
import psycopg2
3+
from dotenv import load_dotenv
4+
5+
load_dotenv()
6+
7+
POSTGRES_URL = os.getenv("SUPABASE_DB_URL")
8+
9+
def get_sql_connection():
10+
"""Creates and returns a new postgres database connection."""
11+
try:
12+
conn = psycopg2.connect(POSTGRES_URL)
13+
print("✅ Supabase Connection successful!")
14+
return conn
15+
except psycopg2.Error as e:
16+
print("❌ Supabase connection error:", e)
17+
return None

docker-compose.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
services:
2+
app:
3+
build: .
4+
container_name: cybergator_app
5+
volumes:
6+
- ./app:/app/app # Mount the app directory
7+
- ./tests:/app/tests # Mount the tests directory
8+
- ./pyproject.toml:/app/pyproject.toml # Mount pyproject.toml
9+
- ./poetry.lock:/app/poetry.lock # Mount poetry.lock
10+
ports:
11+
- "8000:8000"

0 commit comments

Comments
 (0)