Skip to content

Docker setup #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 23, 2025
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
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
__pycache__/
*.pyc
*.pyo
*.pyd
venv/
.venv
58 changes: 58 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Jupyter Notebook
.ipynb_checkpoints

# Environments
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# env
.env

### macOS ###
.DS_Store
.AppleDouble
.LSOverride
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM python:3.12-slim

WORKDIR /app

# installation of only the necessary dependencies for linux
# this helps to keep the container lightweight
RUN apt-get update && apt-get install -y \
curl \
libpq-dev \
postgresql-client \
gcc \
&& rm -rf /var/lib/apt/lists/*

RUN pip install poetry

RUN poetry config virtualenvs.create false

COPY pyproject.toml poetry.lock ./

RUN poetry install --no-interaction --no-root --no-cache

COPY . .

EXPOSE 8000

CMD ["poetry", "run", "python", "app.py"]
91 changes: 91 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,93 @@
# cybergator

CyberGator: A Dynamic Framework for Cyber Resilience Assessment

## Project Overview

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).

---

## Pre-requisites

- **[Docker](https://www.docker.com/get-started)**
- **[Docker Compose](https://docs.docker.com/compose/install/)**
- **[Python >= 3.12](https://www.datacamp.com/blog/how-to-install-python)**
- **[Poetry](https://python-poetry.org/docs/#installation)**

Verify installations:

`docker --version`

`poetry --version`

---

## Running the Application (Development)

1. Clone the Repository

```
git clone [email protected]:OzPol/cybergator.git
cd cybergator
```

2. Create your .env file
Your .env file should be placed in the root of the project (same level as the Dockerfile)

3. Make sure your Docker desktop is running! :)

4. Build the container

```
docker-compose build
```

5. Run the container

```
docker-compose up
```

6. Check the homepage in the browser

```
http://localhost:8000
```

7. When you are done, you can stop the container

```
docker-compose down
```

### Important Notes

- In general, you only need to rebuild the container when there are changes to dependencies.
- 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.

## How to add and install new depencies to the application

1. Run the container in detached mode:

```
docker-compose up -d
```

2. Install the dependency/package

```
docker exec -it cybergator_app poetry add <your-package-name>
```

3. Rebuild and run the container

```
docker-compose up --build
```

4. Optional - clean old images

```
docker image prune -f
```
53 changes: 53 additions & 0 deletions app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import dash
from dash import html
from app.databases.psql_db import get_sql_connection
from app.databases.neo4j_db import run_query

app = dash.Dash(__name__)

# This is test code for testing supabase connection
# Should move away once we start creatign actual functionality...
conn = get_sql_connection()

psql_status = "Error: Unable to connect to Supabase."
if conn:
try:
cursor = conn.cursor()
cursor.execute("SELECT NOW();")
result = cursor.fetchone()
print("Supabase Current Time:", result[0])

psql_status = f"Supabase Current Time: {result[0]}"

except Exception as e:
print("Supabase query error:", e)
psql_status = "Error: Unable to fetch time from Supabase."

finally:
cursor.close()
conn.close()

# Test Neo4j Connection
neo4j_status = "Error: Unable to connect to Neo4j."
try:
result = run_query("MATCH (n) RETURN count(n) AS node_count")
node_count = result[0]['node_count'] if result else 0
print(f"Neo4j Node Count: {node_count}")

neo4j_status = f"Neo4j Node Count: {node_count}"

except Exception as e:
print("Neo4j connection error:", e)
neo4j_status = "Error: Unable to fetch data from Neo4j."

# Define Test Dash Layout
app.layout = html.Div([
html.H1("Database Connection Test"),
html.P(psql_status),
html.P(neo4j_status)
])

# --- Run Dash App ---
if __name__ == "__main__":
app.run_server(debug=True, host="0.0.0.0", port=8000)

32 changes: 32 additions & 0 deletions app/databases/neo4j_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import os
from dotenv import load_dotenv
from neo4j import GraphDatabase

load_dotenv()

NEO4J_URI = os.getenv("NEO4J_URI")
NEO4J_USER = os.getenv("NEO4J_USER")
NEO4J_PASSWORD = os.getenv("NEO4J_PASSWORD")

def get_neo4j_connection():
"""Returns a Neo4j database connection."""
try:
driver = GraphDatabase.driver(NEO4J_URI, auth=(NEO4J_USER, NEO4J_PASSWORD))
driver.verify_connectivity
print("✅ Neo4j Aura Connection successful!")
return driver
except Exception as e:
print("❌ Neo4j connection error", e)
return None

def run_query(query, parameters=None):
"""Runs a Cypher query and returns results."""
driver = get_neo4j_connection()
if driver is None:
return []

with driver.session() as session:
results = session.run(query, parameters).data()

driver.close()
return results
17 changes: 17 additions & 0 deletions app/databases/psql_db.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import os
import psycopg2
from dotenv import load_dotenv

load_dotenv()

POSTGRES_URL = os.getenv("SUPABASE_DB_URL")

def get_sql_connection():
"""Creates and returns a new postgres database connection."""
try:
conn = psycopg2.connect(POSTGRES_URL)
print("✅ Supabase Connection successful!")
return conn
except psycopg2.Error as e:
print("❌ Supabase connection error:", e)
return None
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
services:
app:
build: .
container_name: cybergator_app
volumes:
- ./app:/app/app # Mount the app directory
- ./tests:/app/tests # Mount the tests directory
- ./pyproject.toml:/app/pyproject.toml # Mount pyproject.toml
- ./poetry.lock:/app/poetry.lock # Mount poetry.lock
ports:
- "8000:8000"
Loading