Your own isolated AT Protocol network, for testing, research, and demos. A snowglobe has its own PDS, PLC directory, relay and Jetstream, and nothing in it reaches Bluesky's network. It uses https and the real network's sign-in (OAuth), so an app built for the real network runs against it with no test-only code.
Why? Some things worth trying on atproto can hurt real users if they go wrong: a change to a lexicon, a new OAuth flow, an app that writes records in a new way. A snowglobe is a network of your own, where a mistake touches nobody. We use it to build against the spaces alpha PDS, a group host and atmo.rsvp.
How? Run one on your machine from this repo, or open the one we host, lighthouse.snowglobe.at. snowglobe.at says more about the project.
One file, snowglobe.yml, says what a snowglobe runs. snowglobe.default.yml
is the one to start from. It gives you:
- one current PDS (personal data server, where an account's records live and where it signs in), at
https://main.snowglobe.local.snowglobe.at, with two test accounts,aliceandbob; - a PLC directory, the phone book that says which PDS holds each
did:plcaccount; your app is told its address; - Jetstream, a simple stream of every write on the network, for apps that follow it;
- Slingshot, which looks up a handle's DID and PDS inside the network;
- PDSls, to browse the network's records;
- the network's own page, with its services, accounts and live activity.
The file also holds commented examples for adding more, up to a full setup:
- more PDSes. With more than one, a relay turns on by itself: it merges every PDS's writes into one stream, which Jetstream then follows;
- the permissioned-spaces alpha, a PDS build with shared spaces;
- a lexicon authority, the one account every PDS reads record type definitions (lexicons) from;
- Tap, which follows the stream and fetches whole repos for an app that keeps its own copy of the data;
- a group host, a server that runs groups as accounts of their own, each with a handle under the host's name;
- your own app.
docs/examples/atmo.yml is a larger file, with three PDSes, a relay and a
lexicon authority, that Example: atmo builds on.
Every name is under the snowglobe's own domain, <globe>.local.snowglobe.at, served by nginx with a
certificate from a local CA that the snowglobe makes for itself. There is no AppView and no feed generator.
The snowglobe shows the whole file and what each part does.
Every service in a snowglobe has its own https name under the snowglobe's domain, such as
alice.snowglobe.local.snowglobe.at for the default file. Handles, sign-in (OAuth) and DID documents
all carry those names, so your computer has to send the names to the snowglobe, and trust its
certificate. Here is what to do.
Before you start it: install Docker with Compose, and Node 20 or newer. Use Linux, or Windows with WSL 2.
After it is up, to open it in a browser or reach it from an app:
- The names reach the snowglobe on their own. Public DNS answers every name under
local.snowglobe.atwith127.0.0.1, wheresnowglobe upstarts a name router that passes each connection to the snowglobe the name is under, so every snowglobe on the machine answers at once.- If the browser says "server not found", your router is dropping that answer. See When the browser cannot open it.
- With Docker in a dev container, or on another machine, forward its port 443 to your computer (From a browser on your own computer).
- Trust the snowglobe's certificate authority (CA). Run
snowglobe truston the machine that runs Docker. For another machine, see From a browser on your own computer. A command started withsnowglobe runtrusts it without this.
Why not just use ports? The PDSes are not published on ports at all: only nginx (443), the proxy, the PLC, Jetstream and MailDev are. A PDS's address is its name, and that name is what a DID document, a handle lookup and an OAuth sign-in resolve to, so an app has to be told it is on a test network to use a port instead. A snowglobe can still be small: a file with one PDS, the PLC and Jetstream checks and renders (The file and the commands). It keeps the https names, and they are what make an app run unchanged.
npm install -g @openmeet/snowglobe # puts the snowglobe command on your PATH
snowglobe up --default # the first run pulls and builds images, which takes a whileTo change what it runs, copy the default file into your folder, give it a name of its own on the
globe: line (snowglobe is the default file's, and a snowglobe belongs to the file that first
brought it up), edit it, and run snowglobe up:
cp "$(npm root -g)/@openmeet/snowglobe/snowglobe.default.yml" snowglobe.yml.
To keep the command with one project instead, run npm install --save-dev @openmeet/snowglobe, then
npx snowglobe up --default for the default, or npx snowglobe up once the folder has a
snowglobe.yml (copy it from node_modules/@openmeet/snowglobe/snowglobe.default.yml). Either
command also fits in a package.json script.
Now try it. The snowglobe's names work for any program on the machine, and --cacert gives curl the
snowglobe's certificate authority (CA), so it trusts the snowglobe's https:
# Sign up a new account, then look up alice's account through Slingshot
snowglobe account carol CAROL # CAROL: the prefix of her login variables, such as CAROL_PASSWORD
curl -s --cacert ~/.local/share/snowglobe/ca/ca.crt \
'https://slingshot.snowglobe.local.snowglobe.at/xrpc/com.bad-example.identity.resolveMiniDoc?identifier=alice.snowglobe.local.snowglobe.at'To look around in a browser, you need two things: the browser has to trust the snowglobe's
certificate, and it has to be able to find the snowglobe. If Docker runs on the same computer as your
browser, run snowglobe trust and open https://snowglobe.local.snowglobe.at/, the network's page,
which lists every service, account and write. If Docker runs in a dev container or on another
machine, also forward its port 443 to your computer;
From a browser on your own computer walks through both.
The default snowglobe comes with one app to look at, PDSls,
the record browser. https://pdsls.snowglobe.local.snowglobe.at/at://alice.snowglobe.local.snowglobe.at shows alice's repo,
once your browser can reach the snowglobe as above.
Stop the snowglobe with snowglobe down. Add -v to delete its data too, every account
included. Everything a snowglobe makes is kept in your own account, in
~/.local/share/snowglobe (or under XDG_DATA_HOME), and nothing in the checkout
(Which snowglobe, and where it lives).
To run your own app inside of a snowglobe, see Your app in a snowglobe.
Snowglobe runs on Linux, and on Windows under WSL 2. Both are tested. macOS is not supported yet. If you try it on a Mac, please open an issue with what broke, or that it worked.
- The snowglobe: what a
snowglobe.ymlholds, the commands, the snowglobe's names, up and down, and what it writes. - Your app in a snowglobe:
snowglobe run, and the tools that make an app's accounts, invite codes, lexicons and routes. - From a browser on your own computer: the name router, Docker on another machine, and trusting the CA.
- How it works: what runs and how it is wired, Slingshot, and the relay build.
- Configuration: the settings.
- Testing Snowglobe: the test suite and the smoke run.
- Example: Statusphere: the atproto example app on a snowglobe, with two small changes. CI runs it end to end.
- Example: atmo: an events app on a local snowglobe.
- The older plain-http stack (
npm run up) is not in this version. Its code and README are in the v0.2.0 tag (v0.1.0 has the first version of it). - Changelog: what changed in each version, and how to upgrade.
MIT