Projects · This website

Under the hood of bertrand-didier.tech.

A static site written with Astro, versioned on GitHub, published automatically to my server on every change. All set up in one day, on 1 November 2026. Here is how the pieces fit together.

Built with Claude Code

from git push to live
≈ 20 s
Docker containers for the site, the API and the sensitive projects
4
added cost for market prices
0 €
of pages served over HTTPS
100 %

Diagram 1

The journey of a visit.

One server answers three addresses. Pick a request to follow its path, from the browser to the right container.

Request:
YouBrowserbertrand-didier.tech
HostingerDNSname → server address
VPS Hostinger · Ubuntu 24.04 · Docker
RoutingTraefikHTTPS, Let’s Encrypt certificates
bertrand-didier.technginxthe files built by Astro
…/api/Market serviceNode.js 22, prices in memory
restricted subdomainWordPresspages built in PHPMySQL

    Diagram 2

    From my editor to the live site.

    I never copy files by hand. Every change pushed to the main branch triggers an automatic chain, always the same.

    0.0 sreal time, sped up

      My MacGitHubMy server

      Durations measured on the day’s deploys (18 to 23 seconds in total). If a step fails, the live site stays on the previous version.

      Diagram 3

      Market prices, with no subscription.

      The market dashboard (stocks, indices and 10-year rates) is fed by a small home-made service. It queries Yahoo Finance and CNBC at a fixed pace and keeps the result in memory. Visitors read that copy, so the number of calls to the sources does not depend on traffic.

      00:00one simulated hour
      The service to Yahoo Finance and CNBCprices every minute · history every 30 min
      Visitors to the serviceeach open page rereads the cache every minute, visible tab only
      0calls to external sources
      0reads served from the cache (example traffic)

      938 calls per hour to the sources (15 quotes a minute, plus 19 history calls every 30 minutes), whether there is one visitor or a thousand. The visits shown here are example traffic. Data is delayed and for information only.

      The building blocks

      What runs the site.

      RoleToolWhy this choice
      Domain name and DNSHostingerThe domain was already there. Three names point to the server: the bare domain, www and the sensitive projects’ subdomain.
      ServerVPS Hostinger, Ubuntu 24.04A server of my own, which also hosts the sensitive projects and my AI lab.
      ContainersDockerEach service lives in its own box and restarts without touching the others.
      Routing and HTTPSTraefik v3 + Let's EncryptIt reads the domain name and path of every request, and renews the certificates on its own.
      SiteAstro 7Produces static HTML, fast and with no database. The content fits in one file.
      Web servernginxServes the files built by Astro, read-only.
      ChartsuPlotA very light charting library (about 50 KB).
      Market serviceNode.js 22About a hundred lines, with no dependency to install.
      Private accessWordPress + MySQLThe former WordPress site, moved to its own subdomain: an area for sensitive projects, not visible to the public.
      Code and historyGit + GitHubEvery change is tracked and can be undone.
      PublishingGitHub Actions + rsync over SSHBuilds the site and sends only the changed files.
      PortraitNode.js script + sharpThe portrait is computed from my photo, then recoloured.
      PartnerClaude CodeWriting code, configuring the server and deploys, in dialogue.

      Log of 1 November

      One day, one detour, one live site.

      1. Start

        A domain, a server, a WordPress

        The bertrand-didier.tech domain showed a WordPress site, already installed in a container on my Hostinger VPS.

      2. Detour

        Web hosting, a dead end

        First idea: publish the site from Git on Hostinger web hosting. My plan being an “AI Builder” one, it does not accept custom code, which support confirmed.

      3. Decision

        Everything on the VPS

        WordPress moves to its own subdomain and hosts the sensitive projects, not visible to the public; the main domain hosts the new site. Traefik routes both.

      4. Pipeline

        GitHub, Astro and automatic deployment

        Creation of the repository, the Astro site and the GitHub Actions workflow. A dedicated account on the server receives the files, with an SSH key used for nothing else.

      5. Data

        The market dashboard

        The Node.js service caches prices and the uPlot chart shows one year rebased to 100, with the 10-year OAT on the right axis.

      6. Design

        Three passes

        A banner with the Philharmonie at night, several portrait attempts, then a clean editorial redesign: large type, brick accent, and a recoloured portrait that stays true to the photo.

      With Claude

      A partner, Claude Code.

      The whole site was built in dialogue with Claude Code, Anthropic’s coding assistant. It writes, configures and checks; I set the course, review and approve.

      hours of work on the code
      5
      commits in the Git history
      19
      successful deploys, no failures
      19
      lines of code and configuration
      ≈ 2 100

      What Claude does

      • Writes the code: Astro pages, styles, market price service, deploy workflow.
      • Configures the server remotely: Docker containers, Traefik rules, moving WordPress.
      • Diagnoses problems, such as the server key that had changed after a reinstall, or the chart that did not follow the window width.
      • Proposes the design and adjusts it after each round of feedback, down to the portrait, computed by a script.
      • Checks every release in a browser, on desktop and mobile.

      What I keep

      • The course: what the site must show and in what order.
      • The choices: VPS rather than web hosting, design, portrait, content.
      • Sensitive actions: adding keys and secrets, done by hand and never handed to the assistant.
      • Reviewing, and the decision to publish.

      Figures taken from the Git repository and the GitHub Actions history when version 1.1 was released.

      Security

      Precautions taken.

      No password travels through the publishing chain, and no secret is written in the code.

      • HTTPS everywhere

        Traefik obtains and renews Let’s Encrypt certificates automatically for all three addresses.

      • SSH keys, no passwords

        The deploy account has no password. Its key is restricted and only gives access to the site folder.

      • Authenticated server

        GitHub checks the server’s fingerprint before every upload: a machine impersonating it would be refused.

      • Encrypted secrets

        The deploy key is stored in GitHub’s encrypted secrets, never in the repository.

      • Read-only

        nginx can only read the site files. The market service is only reachable on the /api/ path.

      • No personal data

        The site publishes no e-mail address or phone number: contact goes through LinkedIn.

      What’s next

      The next sections.