Initial commit
This commit is contained in:
26
docker-compose.yaml
Normal file
26
docker-compose.yaml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
services:
|
||||||
|
website:
|
||||||
|
container_name: website
|
||||||
|
build: ./src
|
||||||
|
labels:
|
||||||
|
- "traefik.enable=true"
|
||||||
|
- "traefik.http.routers.flask.rule=Host(`portfolio.vavaas.dev`)"
|
||||||
|
- "traefik.http.routers.flask.entrypoints=websecure"
|
||||||
|
- "traefik.http.routers.flask.tls.certresolver=myresolver"
|
||||||
|
- "traefik.http.services.flask.loadbalancer.server.port=5000"
|
||||||
|
|
||||||
|
- "traefik.http.routers.redirect-vavaas.rule=Host(`vavaas.dev`,`www.vavaas.dev`)"
|
||||||
|
- "traefik.http.routers.redirect-vavaas.entrypoints=web,websecure"
|
||||||
|
- "traefik.http.routers.redirect-vavaas.tls.certresolver=myresolver"
|
||||||
|
- "traefik.http.routers.redirect-vavaas.middlewares=redirect-to-portfolio"
|
||||||
|
- "traefik.http.middlewares.redirect-to-portfolio.redirectregex.regex=^https?://vavaas.dev/(.*)"
|
||||||
|
- "traefik.http.middlewares.redirect-to-portfolio.redirectregex.replacement=https://portfolio.vavaas.dev/$1"
|
||||||
|
- "traefik.http.middlewares.redirect-to-portfolio.redirectregex.permanent=true"
|
||||||
|
networks:
|
||||||
|
- web
|
||||||
|
volumes:
|
||||||
|
- "./src/data:/data"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
web:
|
||||||
|
external: true
|
||||||
13
src/Dockerfile
Normal file
13
src/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
WORKDIR /data
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir -r /data/requirements.txt
|
||||||
|
|
||||||
|
RUN ls
|
||||||
|
RUN pwd
|
||||||
|
|
||||||
|
CMD ["gunicorn", "-b", "0.0.0.0:5000", "app:app"]
|
||||||
BIN
src/data/__pycache__/app.cpython-311.pyc
Normal file
BIN
src/data/__pycache__/app.cpython-311.pyc
Normal file
Binary file not shown.
15
src/data/app.py
Normal file
15
src/data/app.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from flask import Flask, render_template
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route("/")
|
||||||
|
def home():
|
||||||
|
return render_template("index.html", title="Accueil")
|
||||||
|
|
||||||
|
@app.route("/projects")
|
||||||
|
def projects():
|
||||||
|
return render_template("projects.html", title="Projets")
|
||||||
|
|
||||||
|
@app.route("/contact")
|
||||||
|
def contact():
|
||||||
|
return render_template("contact.html", title="Contact")
|
||||||
2
src/data/requirements.txt
Normal file
2
src/data/requirements.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
flask
|
||||||
|
gunicorn
|
||||||
174
src/data/static/css/style.css
Normal file
174
src/data/static/css/style.css
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
* ======================================
|
||||||
|
Base styles
|
||||||
|
====================================== */
|
||||||
|
:root {
|
||||||
|
--bs-body-bg: #2c2c2c;
|
||||||
|
--bs-body-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: #2c2c2c; /* Dark background to match navbar */
|
||||||
|
color: #f8f9fa; /* Light text for readability */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
flex: 1 0 auto;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================
|
||||||
|
Header / Navbar tweaks
|
||||||
|
====================================== */
|
||||||
|
.navbar {
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav-link {
|
||||||
|
color: #f8f9fa; /* Ensure nav links are visible */
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav-link.active {
|
||||||
|
text-decoration: underline;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav-link:hover {
|
||||||
|
color: #ffc107; /* Bootstrap warning color for hover highlight */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================
|
||||||
|
Footer
|
||||||
|
====================================== */
|
||||||
|
footer {
|
||||||
|
flex-shrink: 0;
|
||||||
|
background: #343a40; /* Dark gray, same tone as navbar */
|
||||||
|
color: #f8f9fa;
|
||||||
|
border-top: 1px solid #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer img {
|
||||||
|
margin-left: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================
|
||||||
|
Projects page cards
|
||||||
|
====================================== */
|
||||||
|
.projects-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-card {
|
||||||
|
background: #3c3f44; /* Slightly lighter than page background */
|
||||||
|
color: #f8f9fa;
|
||||||
|
padding: 1.5rem;
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 10px rgba(0,0,0,0.3);
|
||||||
|
transition: transform 0.2s, box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
box-shadow: 0 6px 15px rgba(0,0,0,0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================
|
||||||
|
Links
|
||||||
|
====================================== */
|
||||||
|
a {
|
||||||
|
color: #0d6efd; /* Bootstrap primary color */
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ======================================
|
||||||
|
Responsive tweaks
|
||||||
|
====================================== */
|
||||||
|
@media (max-width: 576px) {
|
||||||
|
main {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Zoom effect for profile picture */
|
||||||
|
.profile-pic {
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-pic:hover {
|
||||||
|
transform: scale(1.1); /* Zoom in slightly on hover */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hero section styling */
|
||||||
|
.hero-section {
|
||||||
|
background: linear-gradient(135deg, #1f1f1f, #2c2c2c); /* dark gradient */
|
||||||
|
box-shadow: 0 8px 20px rgba(0,0,0,0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero-section p, .hero-section h1 {
|
||||||
|
color: #f8f9fa; /* Ensure text is readable on dark bg */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Profile picture hover zoom */
|
||||||
|
.profile-pic {
|
||||||
|
transition: transform 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-pic:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hero box animation */
|
||||||
|
.hero-box {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
animation: fadeInUp 1s forwards;
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Project box hover scale */
|
||||||
|
.hover-scale {
|
||||||
|
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hover-scale:hover {
|
||||||
|
transform: scale(1.03);
|
||||||
|
box-shadow: 0 10px 25px rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fade-in animation */
|
||||||
|
@keyframes fadeInUp {
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.project-row .row > div > .bg-dark {
|
||||||
|
background-color: #1c1c1c; /* slightly darker than default bg-dark */
|
||||||
|
}
|
||||||
|
/* Alternate spacing for left/right boxes */
|
||||||
|
.project-row .row:nth-child(even) {
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-img {
|
||||||
|
max-height: 180px; /* adjust as you like */
|
||||||
|
width: auto; /* keeps proportions */
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
BIN
src/data/static/img/companion.png
Executable file
BIN
src/data/static/img/companion.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 7.5 KiB |
BIN
src/data/static/img/kfs.png
Executable file
BIN
src/data/static/img/kfs.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
src/data/static/img/monster.png
Executable file
BIN
src/data/static/img/monster.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 498 B |
BIN
src/data/static/img/override.png
Executable file
BIN
src/data/static/img/override.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
src/data/static/img/profile.png
Executable file
BIN
src/data/static/img/profile.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 246 KiB |
BIN
src/data/static/img/profile.webp
Executable file
BIN
src/data/static/img/profile.webp
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
55
src/data/templates/base.html
Normal file
55
src/data/templates/base.html
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{{ title if title else "Portfolio" }}</title>
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<!-- Header / Navbar -->
|
||||||
|
<header>
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="{{ url_for('home') }}">Mon Portfolio</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav ms-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {% if title=='Accueil' %}active{% endif %}" href="{{ url_for('home') }}">Accueil</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {% if title=='Projets' %}active{% endif %}" href="{{ url_for('projects') }}">Projets</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link {% if title=='Contact' %}active{% endif %}" href="{{ url_for('contact') }}">Contact</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main content -->
|
||||||
|
<main class="container my-5">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="bg-dark text-center text-lg-start py-3 border-top">
|
||||||
|
<div class="container d-flex justify-content-center align-items-center">
|
||||||
|
<p class="mb-0 text-light">
|
||||||
|
© 2025 Avec amour et
|
||||||
|
<img src="{{ url_for('static', filename='img/monster.png') }}" alt="Battery" width="16" height="16" class="ms-1">
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Bootstrap JS -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
src/data/templates/contact.html
Normal file
5
src/data/templates/contact.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>Contact</h1>
|
||||||
|
<p>Tu peux me joindre à <a href="mailto:vavaas.dev@gmail.com">vavaas.dev@gmail.com</a></p>
|
||||||
|
{% endblock %}
|
||||||
93
src/data/templates/index.html
Normal file
93
src/data/templates/index.html
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="container py-5">
|
||||||
|
<!-- Hero / Presentation Box -->
|
||||||
|
<div class="p-5 mb-5 rounded-4 bg-dark text-light shadow hero-box">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-6 mb-4 mb-md-0">
|
||||||
|
<h1 class="display-4 mb-3">Bienvenue sur mon portfolio</h1>
|
||||||
|
<p class="lead">
|
||||||
|
Salut ! Je suis Valentin, développeur bas-niveau passionné par la cybersécurité et le DevOps.
|
||||||
|
Ici, vous pouvez découvrir mes projets et me contacter directement.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 text-center">
|
||||||
|
<img src="{{ url_for('static', filename='img/profile.webp') }}"
|
||||||
|
alt="Profile picture"
|
||||||
|
class="rounded-circle img-fluid profile-pic"
|
||||||
|
style="width: 250px; height: 250px; object-fit: cover;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Featured Projects Title -->
|
||||||
|
<h2 class="text-light text-center mb-5">Featured Projects</h2>
|
||||||
|
|
||||||
|
<!-- Featured Project Boxes -->
|
||||||
|
<div class="container mb-5">
|
||||||
|
<!-- Project 1 (left) -->
|
||||||
|
<div class="row mb-5 justify-content-start">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<a href="https://github.com/Kbz-8/42_KFS" class="text-decoration-none">
|
||||||
|
<div class="p-4 rounded-4 bg-dark text-light shadow hover-scale">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<!-- Text -->
|
||||||
|
<div class="col-md-7">
|
||||||
|
<h4>Kernel From Scratch</h4>
|
||||||
|
<p>Création d'un kernel en Zig 0.13 avec pilotes claviers et graphiques, IDT, GDT, gestion mémoire et shell intégré</p>
|
||||||
|
</div>
|
||||||
|
<!-- Image -->
|
||||||
|
<div class="col-md-5 text-center">
|
||||||
|
<img src="{{ url_for('static', filename='img/kfs.png') }}"
|
||||||
|
alt="Projet 1" class="img-fluid rounded shadow project-img">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Project 2 (right) -->
|
||||||
|
<div class="row mb-5 justify-content-end">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<a href="https://github.com/Namonay/swifty-companion" class="text-decoration-none">
|
||||||
|
<div class="p-4 rounded-4 bg-dark text-light shadow hover-scale">
|
||||||
|
<div class="row align-items-center flex-md-row-reverse">
|
||||||
|
<div class="col-md-7">
|
||||||
|
<h4>Swifty Companion</h4>
|
||||||
|
<p>Application mobile Android et iOS utilisant l'API de 42 pour avoir des informations sur les campus</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 text-center">
|
||||||
|
<img src="{{ url_for('static', filename='img/companion.png') }}"
|
||||||
|
alt="Projet 2" class="img-fluid rounded shadow project-img">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Project 3 (left) -->
|
||||||
|
<div class="row mb-5 justify-content-start">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<a href="https://github.com/C18H24O2/override" class="text-decoration-none">
|
||||||
|
<div class="p-4 rounded-4 bg-dark text-light shadow hover-scale">
|
||||||
|
<div class="row align-items-center">
|
||||||
|
<div class="col-md-7">
|
||||||
|
<h4>Override</h4>
|
||||||
|
<p>Défis de cybersécurité sous formes de CTF, avec reverse engineering, pwn et exploitation de failles</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-5 text-center">
|
||||||
|
<img src="{{ url_for('static', filename='img/override.png') }}"
|
||||||
|
alt="Projet 3" class="img-fluid rounded shadow project-img">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
9
src/data/templates/projects.html
Normal file
9
src/data/templates/projects.html
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
<h1>Mes Projets</h1>
|
||||||
|
<ul>
|
||||||
|
<li>Projet 1 – Devenir un tigre</li>
|
||||||
|
<li>Projet 2 – Un script d’automatisation pour acheter des monsters</li>
|
||||||
|
<li>Projet 3 – Trouver un job</li>
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
Reference in New Issue
Block a user