diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..52a5257 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,86 @@ +pipeline { + agent any + + environment { + DEPLOY_HOST = "192.168.178.180" + DEPLOY_USER = "ubuntu" + APP_DIR = "/srv/mitm-webserver" + } + + stages { + stage('Checkout') { + steps { + git branch: 'main', url: 'http://192.168.178.96:3000/marcus/mitm-webserver.git' + } + } + + stage('Build Frontend') { + steps { + dir('frontend') { + sh 'npm ci' + sh 'npm run build' + } + } + } + + stage('Prepare Backend') { + steps { + dir('backend') { + sh ''' + python3 -m venv venv + ./venv/bin/pip install --upgrade pip + ./venv/bin/pip install -r requirements.txt + ''' + } + } + } + + stage('Deploy to VM') { + steps { + // Use Jenkins credentials (username + password) + withCredentials([usernamePassword(credentialsId: 'deploy-pass-id', usernameVariable: 'USER', passwordVariable: 'PASS')]) { + // Install sshpass if not available + sh ''' + if ! command -v sshpass >/dev/null 2>&1; then + echo "Installing sshpass..." + sudo apt-get update -y && sudo apt-get install -y sshpass + fi + ''' + + // Upload frontend build + sh ''' + sshpass -p "$PASS" rsync -avz --delete \ + -e "ssh -o StrictHostKeyChecking=no" \ + frontend/dist/ $USER@$DEPLOY_HOST:$APP_DIR/frontend/dist/ + ''' + + // Upload backend code + sh ''' + sshpass -p "$PASS" rsync -avz --delete \ + -e "ssh -o StrictHostKeyChecking=no" \ + backend/ $USER@$DEPLOY_HOST:$APP_DIR/backend/ + ''' + + // Restart backend service + sh ''' + sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no \ + $USER@$DEPLOY_HOST " + cd $APP_DIR/backend && + source venv/bin/activate && + sudo systemctl restart mitm-webserver-backend.service + " + ''' + } + } + } + } + + post { + success { + echo '✅ Deployment successful (password-based SSH)!' + } + failure { + echo '❌ Deployment failed!' + } + } +} diff --git a/frontend/src/App.css b/frontend/src/App.css index 902778b..4039e55 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -4,3 +4,10 @@ padding: 2rem; text-align: center; } + +.drawer-pages { + display: flex; + justify-content: flex-start; + align-items: center; + gap: 10px; +} diff --git a/frontend/src/header/Header.tsx b/frontend/src/header/Header.tsx index 6d48663..8224fdd 100644 --- a/frontend/src/header/Header.tsx +++ b/frontend/src/header/Header.tsx @@ -14,8 +14,18 @@ import { } from "@mui/material"; import MenuIcon from "@mui/icons-material/Menu"; import { useNavigate, useLocation, To } from "react-router-dom"; +import { Home } from "@mui/icons-material"; -const pages = [{ name: "Home", path: "/" }]; +const pages = [ + { + name: ( + + Home + + ), + path: "/", + }, +]; export default function Header() { const [drawerOpen, setDrawerOpen] = React.useState(false);