Ship Data Apps with AI

🌱 Start from zero·Lesson 1 of 26·~15 min·Beginner

🌐 How the web actually works

Servers, domains, DNS, HTTPS and the one front door, in plain English, so nothing later in the course feels like magic.

You'll leave with

  • A picture of what happens between typing an address and seeing your app
  • The twelve words every later lesson uses, each in one plain sentence
  • Your first look under the hood of a real website, with nothing to install

Every later lesson says things like "point DNS at the server" or "the front door can't reach the container". These fifteen minutes turn that into plain words, with nothing to install and nothing to buy (a domain and a server come later): one trip from typing an address to seeing an app, then the same trip in your own browser. I'm a data person, not a 10Γ— engineer, and I learned most of this by breaking it.

What happens when someone opens your app

Take Habooby, my dust and air-quality map for Phoenix (open it in a new tab to see what we're tracing). It lives on a server, at a subdomain of my domain. In this course an app means a website that does something useful, opened in a browser.

What are a server, a domain and a subdomain?

A server is a computer that's always on, answering requests. A domain is a name you rent by the year, like traqqit.com. Subdomains like habooby.traqqit.com are free to make under it.

Between pressing Enter and seeing the map, four things happen:

  1. The browser looks up the name. It asks DNS, the internet's address book, where habooby.traqqit.com lives, and gets back my server's IP address, its number on the internet.
    What's DNS?

    The Domain Name System turns names people remember into the numbers computers use. You edit your domain's entries at your DNS provider, usually where you bought the domain.

  2. It knocks on the HTTPS door. It connects to that address on port 443, the door for HTTPS.
    What are an IP address and a port?

    An IP address is a server's number on the internet, like 203.0.113.7 (a number reserved for examples). A port is which door on it you knock on: 443 for HTTPS, 80 for plain HTTP.

    What's HTTPS?

    The encrypted version of HTTP, the language browsers and servers speak. Nobody in between can read or change the page; the padlock in the address bar says so. (Chrome now shows a sliders icon instead: click it and look for "Connection is secure". Edge and Firefox still show a padlock.)

  3. The front door picks the app. One program, Caddy, receives every visitor's request (the browser's ask for a page or file), reads the name asked for, and forwards it to that app's container.
    What's a reverse proxy?

    The proper name for that front door: one program that receives every request and forwards it to the right app. Mine is Caddy, which is free and handles the padlock itself.

    What's a container?

    A sealed box holding one app and everything it needs, built and run by a tool called Docker.

  4. The app hands back files, and the browser runs them. The files are its response: HTML, CSS, JavaScript and usually some JSON.
    What are HTML, CSS, JavaScript and JSON?

    HTML is the page's content, CSS is how it looks, JavaScript is the code that makes it do things, and JSON is data written as plain text, like {"city": "Phoenix"}.

your browser
  | 1. "where does habooby.traqqit.com live?"  -> DNS answers with an IP address
  | 2. connects to that IP address on port 443 (HTTPS)
  v
the front door (Caddy)
  | 3. reads the name asked for, forwards the request
  v
the app's container
  | 4. sends back files: HTML, CSS, JavaScript, JSON
  v
your browser runs them, and you see the map

For most of my fleet, that's the whole trip. ("The fleet" means the live apps I run at traqqit.com; every example in this course comes from one of them.)

Static files vs a backend

Notice what my server did: it handed over files. That's a static app. None of my code runs on the server; all the running happens in the visitor's browser. Habooby, Ticket Heat and Who Owns Phoenix are exactly this.

A backend is a program on your server that answers requests itself, usually at addresses like /api/.... You need one for what a visitor must not control: secrets, logins, payments, and limits people can't cheat. Anything the browser decides, the person holding the browser can change. (First Bites works without an account; its backend only adds sync across phones and sharing with family.)

What's an API?

A URL that returns data, usually JSON, instead of a page. You'll open one further down.

Deploy means getting your files onto the server and telling the front door where they are. For a static app, that's the whole job.

πŸ¦₯ So we start with no backend, no database and no logins, and add each only when a feature forces it. Build static-first comes early; Add a backend only when forced comes much later.

πŸ›‘ Static also means public: anyone can download any file in the served folder by asking for its name, so secrets never go there. One of my apps once had a file of secret keys sitting in its served folder. I replaced the keys and took the file out. Deploy behind one front door shows the layout that prevents it.

Domains, DNS and the padlock

An A record is one line in your domain's DNS that points a name at an IP address: myapp β†’ YOUR_VPS_IP. (In this course, myapp, yourdomain.com and YOUR_VPS_IP are stand-ins for your app's name, your domain and your server's IP address.)

Each record has a TTL (time to live): how many seconds other computers may remember the answer. 300 is five minutes. So "saved" doesn't mean live: your provider can take minutes to publish a change, and anyone holding an old answer keeps it until the TTL runs out.

πŸ“ When I launched Acento, my Argentine Spanish trainer, the DNS provider said "request accepted", and then the name didn't exist for more than three and a half minutes. The app had already passed its checks, so only the name was missing, and the certificate arrived on its own once the name existed. My laptop gave unreliable answers, so the final check ran from the server.

The padlock needs a certificate, free from Let's Encrypt. Caddy requests one by itself once DNS points the name at your server, and renews it before it expires. Let's Encrypt checks real public DNS, so this can't be faked: no DNS, no padlock.

What's a certificate?

A small signed file proving to browsers that this server really is myapp.yourdomain.com, issued after a check that you control the name. Let's Encrypt is a nonprofit that issues them free.

The padlock isn't decoration. Browsers only allow the microphone, location, installing as an app, and service workers (the offline helper in Make it an app on their phone) over HTTPS (testing on your own computer is the exception). Acento listens to your pronunciation and First Bites installs like an app; neither would work without it.

Soon you'll meet Claude Code, an AI assistant that works in your project folder: you describe a job in plain English, and it reads files and runs commands, asking your permission first. From Your own server on, it does the DNS part, and this example shows what a real check looks like:

EXAMPLE β€” YOU ASK CLAUDE CODE (MUCH LATER IN THE COURSE)

Claude Code
Youmyapp already runs behind Caddy. Add an A record for it without touching my other records. Then, from the server, check that https://myapp.yourdomain.com answers 200 and show me who issued its certificate.
ClaudeAdded myapp.yourdomain.com β†’ YOUR_VPS_IP. A few minutes later, from the server, https://myapp.yourdomain.com answers 200, and its certificate was issued by Let's Encrypt.↳ hostinger-dns Β· update DNS records↳ Bash Β· ssh root@YOUR_VPS_IP 'curl -sI https://myapp.yourdomain.com'↳ Bash Β· ssh root@YOUR_VPS_IP 'curl -vI https://myapp.yourdomain.com 2>&1 | grep -i issuer'

What's happening underneath: one new DNS line, then a real HTTPS request from the server, not your laptop: ssh runs a command on another computer, here your server. If Claude says "done" without a check like that, ask for one.

Your server, containers and the front door

All this runs on a VPS: a rented, always-on Linux computer. One small one can run many apps.

What's a VPS?

A virtual private server: your own slice of a big computer in a data center, rented by the month (small ones start around $5; prices vary, so check before you buy). It runs Linux, the free operating system most servers use.

Each app gets its own container, so when one crashes, its visitors see an error (a 502: the front door can't reach it) and the other apps carry on.

Three rules keep the server safe:

  • Only the front door listens (waits for visitors) on the public web ports, 80 and 443. The only other public door is SSH, which you use to log in (Your own server).
  • Apps publish no ports: a published port is a hole straight to the whole internet.
  • Apps sit on a private network inside the server, and Caddy reaches each one by its container name.

Caddy keeps its settings in a text file called the Caddyfile. Here's one app's whole front-door config, padlock included:

myapp.yourdomain.com {
  # container name : the app's own port, inside the private network (not a public port)
  reverse_proxy myapp:80
}

πŸ“ When I added my medical price tool, healthcare.traqqit.com, the server already ran my map app and several other services. The new container joined the private network, published no port, and went live without touching the other apps.

⚠️ Tutorials often publish a port, so the app also answers at YOUR_VPS_IP:8000, around the front door. That's how databases and admin panels end up open to the whole internet.

πŸ¦₯ No Kubernetes (software for juggling many servers), and no second server. You'd add one when this one is full or downtime costs real money.

APIs, CORS and same-origin

An API, remember, is a URL that returns data instead of a page. Habooby uses a free weather API called Open-Meteo. Open Phoenix's temperature as raw data and look at the address bar: the URL itself asks the question (latitude=33.45, longitude=-112.07, current=temperature_2m). Near the end of the reply, on one long line or laid out neatly:

"current": { "time": "2026-10-03T04:45", "interval": 900, "temperature_2m": 83.7 }

No page, only data. That was Phoenix in Β°F when I ran it; yours will differ. (time is in GMT, not your clock.)

Your page's code can ask APIs too, but the browser enforces a rule called CORS: a page may only read another site's API if that site allows it.

What are CORS and an "origin"?

An origin is the https:// plus the full name, so tickets.traqqit.com and habooby.traqqit.com are different origins. CORS (Cross-Origin Resource Sharing) lets an API grant other origins permission with an Access-Control-Allow-Origin header, a labeled line of extra information that travels with every request and response. No header, no data.

Open-Meteo allows everyone, so Habooby asks it straight from your browser. The U.S. Census Bureau's free address lookup doesn't, like many free government APIs. The URL still opens fine in a tab; only your page is blocked from reading the answer, with a red error in DevTools (the browser's developer tools, which you'll open below):

Access to fetch at 'https://api.example.com/data' from origin 'https://myapp.yourdomain.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

When an API doesn't allow it, the fleet goes through the front door instead. Ticket Heat's address search asks tickets.traqqit.com, and the front door fetches the Census answer for it. That's a few lines of front-door settings, not a program of mine, so Ticket Heat is still static. To the browser it's all one site (one origin), so the trick is called same-origin and the rule never comes up. My own backends work the same way: /api/ goes to the backend's container, everything else to the page's.

myapp.yourdomain.com {
  handle /api/* {
    reverse_proxy myapp-api:3000
  }
  handle {
    reverse_proxy myapp:80
  }
}

⚠️ If this error appears, AI helpers may suggest mode: 'no-cors' or a free public "CORS proxy". Neither fixes it: the first hides the answer from your page, and the second routes your visitors through a stranger's server. Use the front-door route, and check an API's terms before proxying it.

The bonus: when I moved the fleet to one shared accounts store (one backend that keeps everyone's logins for all my apps: Accounts without building auth), Acento's /api/ moved with one changed line, and the page never noticed. Add a backend only when forced builds this.

Twelve words, and a first look under the hood

These twelve words come back in every later lesson; notice which ones you couldn't explain yet. The glossary keeps them all.

WordIn one sentence
HTML / CSS / JavaScriptA page's content, its looks, and its behavior.
NodeRuns JavaScript outside the browser, on your computer or server.
TerminalA window where you type commands; Claude Code works in one.
RepoA project folder where a tool called git remembers every saved version.
localhostYour own computer acting as a server, for testing.
JSONData as plain text that people and programs can both read.
IP address and portA server's number, and which door on it you knock on.
Status codeThe server's verdict: 200 OK, 404 not found, 502 the front door can't reach the app.
DeployGetting files onto the server and telling the front door where they are.
ContainerA sealed box running one program.
Reverse proxyThe front door that passes each request to the right box.
APIA URL that returns data instead of a page.

"Live" comes in three flavors

  • Listed: linked from your home page, and Google shows it in search.
  • Unlisted: it works, but nothing links to it and a noindex tag asks search engines to skip it.
  • Private: behind a password.

Several of my apps went live on day one but stayed off my home page until polished, and one private report sits behind a password. Launch, honestly covers moving between them.

⚠️ Unlisted isn't secret: every HTTPS certificate is published in public logs that bots watch. Truly private needs a password.

1

Let Claude quiz you

Open claude.ai and sign in, or make a free account (that's enough here; Claude Code needs a paid plan from the next lesson). Send the first message below, word for word. You should get a short explanation, then a first question; answer in your own words, and "I don't know" is fine.

EXAMPLE β€” YOU ASK CLAUDE AT CLAUDE.AI

Claude
YouExplain what happens between typing a web address and seeing the page, using DNS, server, reverse proxy and HTTPS, in plain words for someone who has never coded. Then quiz me, one question at a time.
Claude…Question 1: your browser has the server's IP address. Which port does it connect to?
You80?
ClaudeClose. 80 is plain HTTP; an https:// address uses 443. Question 2: who decides which app gets the request?

What's happening underneath: Claude answers from its training, not by looking at a real site, and can be wrong with total confidence. If an answer contradicts the trip above, ask "which step is that?" When Claude and what you see in DevTools (the next step) disagree, trust DevTools.

2

Watch the trip in your own browser

What are DevTools?

Tools built into desktop browsers that show what a page is doing underneath: every file, every error. Looking can't break anything.

  1. Open Ticket Heat, or any site, in Chrome or Edge on a computer. (Safari hides these tools until you switch them on, and phones can't do this step.)
  2. Press Ctrl+Shift+I (Mac: Cmd+Option+I). A panel opens.
  3. Click Network (behind the Β» arrows if you can't see it).
  4. Hard-reload with Ctrl+Shift+R (Mac: Cmd+Shift+R), which skips the browser's saved copies. Rows pour in, one per file.
  5. Click the first row, the page itself (its Name is the site's address, and its Type column says document), and open the Headers tab:
Request URL: https://tickets.traqqit.com/ Request Method: GET Status Code: 200 Remote Address: SERVER_IP:443

That's the trip. GET means "send me this". Remote Address is the IP that DNS handed back (real digits where I wrote SERVER_IP), :443 is the HTTPS door, and Status Code 200 (some versions say 200 OK) means it worked. Under Response Headers, server: Caddy and via: 1.1 Caddy are my front door signing its work.

The page's own CSS and JavaScript are inside that first file. The other rows are the map library, fonts and map tiles (from other companies' servers, so their Remote Address differs), a small analytics script, and data.json, Ticket Heat's data, from mine. Tile addresses end in key=: that key is made to be public, not a secret. Nothing on my server did any thinking: static.

⚠️ Asking claude.ai what a header's name means is fine. Never paste header values from a site you're logged into: Request Headers carry your login cookie, Response Headers can set one, and a cookie works like a password. And never paste code into the Console tab of DevTools because a stranger told you to.

Your turn

  • Open DevTools on any site, hard-reload, and find the IP address and the :443 in the first request. (A big site may show a delivery network's address or a long IPv6 one in square brackets; either counts.)
  • On one of my apps, find the two response headers that name the front door (both say Caddy).
  • Find Phoenix's temperature in the Open-Meteo JSON.
  • Finish Claude's quiz and ask it to score you out of 5. Done when you can tell the four steps (look up the name, knock on port 443, the front door picks the app, the app returns files) in your own words.
  • Write one line in a notes file, choosing listed, unlisted or private: "My first app starts as ___ because ...".
  • Ask Claude to quiz you on the three words in the table you find hardest.

Next, Set up your workshop: VS Code (a free code editor), Claude Code and a terminal you aren't scared of, ending with your first page on localhost.