diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 655be80..1ab514f 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -7,5 +7,5 @@ "build": { "dockerfile": "Dockerfile" }, - "postAttachCommand": "docker context create prod --docker \"host=ssh://user@62.210.212.10\"" + "postCreateCommand": "docker context create prod --docker \"host=ssh://user@62.210.212.10\"" } diff --git a/Caddyfile b/Caddyfile index 6715bf7..0cd0e16 100644 --- a/Caddyfile +++ b/Caddyfile @@ -13,7 +13,8 @@ qpismont.fr { } www.qpismont.fr { - reverse_proxy my_cv:80 + root * /www/html + file_server } gitea.qpismont.fr { diff --git a/docker-compose.core.yml b/docker-compose.core.yml index d255a87..df7afbc 100644 --- a/docker-compose.core.yml +++ b/docker-compose.core.yml @@ -10,6 +10,8 @@ services: configs: - source: caddy_config target: /etc/caddy/Caddyfile + - source: caddy_portfolio_html + target: /www/html/index.html volumes: - reversecaddydata:/data - reversecaddyconfig:/config @@ -152,6 +154,9 @@ configs: wireguard_coredns_config: name: wireguard_coredns_config_${DATETIME} file: ./wireguard/CoreDns + caddy_portfolio_html: + name: caddy_portfolio_html_${DATETIME} + file: ./portfolio/index.html volumes: giteadata: diff --git a/docker-compose.observability.yml b/docker-compose.observability.yml index 15ac3a2..2028543 100644 --- a/docker-compose.observability.yml +++ b/docker-compose.observability.yml @@ -1,6 +1,19 @@ version: "3" services: + tempo: + image: grafana/tempo:2.10.7 + command: + - -config.file=/etc/tempo/tempo.yml + configs: + - source: tempo_config + target: /etc/tempo/tempo.yml + volumes: + - tempodata:/var/tempo + networks: + - prometheus_network + - wireguard_network + perses: image: persesdev/perses:latest volumes: @@ -94,12 +107,16 @@ configs: otel_collector_config: name: otel_collector_config_${DATETIME} file: ./otel-collector/config.yaml + tempo_config: + name: tempo_config_${DATETIME} + file: ./tempo/tempo.yml volumes: persesdata: prometheusdata: ntfydata: alertmanagerdata: + tempodata: networks: reverse_network: diff --git a/otel-collector/config.yaml b/otel-collector/config.yaml index 9f05a33..3d398b2 100644 --- a/otel-collector/config.yaml +++ b/otel-collector/config.yaml @@ -27,10 +27,16 @@ processors: exporters: prometheusremotewrite: endpoint: http://prometheus:9090/api/v1/write + otlphttp/tempo: + endpoint: http://tempo:4318 service: pipelines: metrics: receivers: [otlp, prometheus] processors: [memory_limiter, batch] - exporters: [prometheusremotewrite] \ No newline at end of file + exporters: [prometheusremotewrite] + traces: + receivers: [otlp] + processors: [memory_limiter, batch] + exporters: [otlphttp/tempo] \ No newline at end of file diff --git a/portfolio/index.html b/portfolio/index.html new file mode 100644 index 0000000..f72d7d6 --- /dev/null +++ b/portfolio/index.html @@ -0,0 +1,586 @@ + + +
+ + + ++ Platform / infrastructure engineer. From code to production, through CI/CD, + observability and security — an integrated ecosystem designed to be operated + over the long run. +
+ ++ Developer for over 20 years (first lines of C at age 10), + working as an engineer for 10 years. My specialty: designing coherent + distributed systems and keeping them operable over time. +
++ What I show here is infrastructure + actually running in production for my daily use, tested under failure, + with full observability and an end-to-end CI/CD chain. +
++ On the people side, I mentored two interns from the ground up on our stack — + both were hired at the end of their internship. Helping others level up + is part of how I approach the craft. +
++ My areas of focus: Rust, container orchestration, + security / isolation, networking, and self-hosted observability. +
++ Three pieces that, together, cover the essentials of a platform profile: + operating a system, designing a secure architecture, and thinking about scale. +
+ +A complete ecosystem — code → CI → production → observability — on bare metal, validated by real failure tests.
+Having a reliable personal platform to host and operate my own services, with the standards of real production: resilience, alerting, zero data loss.
+CoreDNS for *.internal resolution with fallback to Docker's DNS.A code-review and AI-assistance bot for Gitea, written in Rust, with a security-first agentic architecture.
+No AI assistance solution exists for Gitea. A real need: solo code review, implementing tests/features, usable day to day — including from a phone.
+The challenge of an agent that executes code isn't making it run, but making it run without risk of exfiltration or compromise. The decisions:
+.git "disarmed" for reading (remotes removed, credentials cleared, hooks emptied) — on a copy, with the armed original staying on the host.postCreate.An extended imgproxy-style media processing pipeline, designed for horizontal scaling and streaming.
+Process media (images, streaming) compositionally, with an architecture able to scale out horizontally — and serve as a real load-testing playground.
+NATS.An ideal candidate for load tests (k6) instrumented by my observability stack — validating system behavior at scale and documenting the breaking points.
+Rust (async / Tokio), TypeScript / Node. Looking for the right tool for the right problem.
+Docker Swarm, bare metal, Fedora Bootc (immutable OS), CI/CD (Gitea, Woodpecker).
+OpenTelemetry, Prometheus, Loki, Tempo, Perses, Alertmanager. Full stack, tested under failure.
+WireGuard, CoreDNS, overlay networks, Caddy. Designing self-hosted private networks.
+Container sandboxing, privilege separation (DBus / Polkit), threat modeling.
+NATS, distributed architectures, claim-check patterns, horizontal scaling.
++ Interested in platform / infrastructure / staff roles where technical quality + and autonomy matter. The code for everything shown here is available to review. +
+ +