haileyok/cocoon
{ "createdAt": "2025-03-23T17:50:36Z", "defaultBranch": "main", "description": "An ATProtocol Personal Data Server written in Go with a SQLite block and blob store", "fullName": "haileyok/cocoon", "homepage": "", "language": "Go", "name": "cocoon", "pushedAt": "2025-11-17T18:20:50Z", "stargazersCount": 51, "topics": [], "updatedAt": "2025-11-22T23:11:25Z", "url": "https://github.com/haileyok/cocoon"}Cocoon
Section titled “Cocoon”[!WARNING] I migrated and have been running my main account on this PDS for months now without issue, however, I am still not responsible if things go awry, particularly during account migration. Please use caution.
Cocoon is a PDS implementation in Go. It is highly experimental, and is not ready for any production use.
Quick Start with Docker Compose
Section titled “Quick Start with Docker Compose”Prerequisites
Section titled “Prerequisites”- Docker and Docker Compose installed
- A domain name pointing to your server (for automatic HTTPS)
- Ports 80 and 443 open in i.e. UFW
Installation
Section titled “Installation”-
Clone the repository
Terminal window git clone https://github.com/haileyok/cocoon.gitcd cocoon -
Create your configuration file
Terminal window cp .env.example .env -
Edit
.envwith your settingsRequired settings:
Terminal window COCOON_DID="did:web:your-domain.com"COCOON_HOSTNAME="your-domain.com"COCOON_CONTACT_EMAIL="you@example.com"COCOON_RELAYS="https://bsky.network"# Generate with: openssl rand -hex 16COCOON_ADMIN_PASSWORD="your-secure-password"# Generate with: openssl rand -hex 32COCOON_SESSION_SECRET="your-session-secret" -
Start the services
Terminal window # Pull pre-built image from GitHub Container Registrydocker-compose pulldocker-compose up -dOr build locally:
Terminal window docker-compose builddocker-compose up -d -
Get your invite code
On first run, an invite code is automatically created. View it with:
Terminal window docker-compose logs create-inviteOr check the saved file:
Terminal window cat keys/initial-invite-code.txtIMPORTANT: Save this invite code! You’ll need it to create your first account.
-
Monitor the services
Terminal window docker-compose logs -f
What Gets Set Up
Section titled “What Gets Set Up”The Docker Compose setup includes:
- init-keys: Automatically generates cryptographic keys (rotation key and JWK) on first run
- cocoon: The main PDS service running on port 8080
- create-invite: Automatically creates an initial invite code after Cocoon starts (first run only)
- caddy: Reverse proxy with automatic HTTPS via Let’s Encrypt
Data Persistence
Section titled “Data Persistence”The following directories will be created automatically:
./keys/- Cryptographic keys (generated automatically)rotation.key- PDS rotation keyjwk.key- JWK private keyinitial-invite-code.txt- Your first invite code (first run only)
./data/- SQLite database and blockstore- Docker volumes for Caddy configuration and certificates
Optional Configuration
Section titled “Optional Configuration”SMTP Email Settings
Section titled “SMTP Email Settings”COCOON_SMTP_USER="your-smtp-username"COCOON_SMTP_PASS="your-smtp-password"COCOON_SMTP_HOST="smtp.example.com"COCOON_SMTP_PORT="587"COCOON_SMTP_EMAIL="noreply@example.com"COCOON_SMTP_NAME="Cocoon PDS"S3 Storage
Section titled “S3 Storage”COCOON_S3_BACKUPS_ENABLED=trueCOCOON_S3_BLOBSTORE_ENABLED=trueCOCOON_S3_REGION="us-east-1"COCOON_S3_BUCKET="your-bucket"COCOON_S3_ENDPOINT="https://s3.amazonaws.com"COCOON_S3_ACCESS_KEY="your-access-key"COCOON_S3_SECRET_KEY="your-secret-key"Management Commands
Section titled “Management Commands”Create an invite code:
docker exec cocoon-pds /cocoon create-invite-code --uses 1Reset a user’s password:
docker exec cocoon-pds /cocoon reset-password --did "did:plc:xxx"Updating
Section titled “Updating”docker-compose pulldocker-compose up -dImplemented Endpoints
Section titled “Implemented Endpoints”[!NOTE] Just because something is implemented doesn’t mean it is finished. Tons of these are returning bad errors, don’t do validation properly, etc. I’ll make a “second pass” checklist at some point to do all of that.
Identity
Section titled “Identity”-
com.atproto.identity.getRecommendedDidCredentials -
com.atproto.identity.requestPlcOperationSignature -
com.atproto.identity.resolveHandle -
com.atproto.identity.signPlcOperation -
com.atproto.identity.submitPlcOperation -
com.atproto.identity.updateHandle
-
com.atproto.repo.applyWrites -
com.atproto.repo.createRecord -
com.atproto.repo.putRecord -
com.atproto.repo.deleteRecord -
com.atproto.repo.describeRepo -
com.atproto.repo.getRecord -
com.atproto.repo.importRepo(Works “okay”. Use with extreme caution.) -
com.atproto.repo.listRecords -
com.atproto.repo.listMissingBlobs
Server
Section titled “Server”-
com.atproto.server.activateAccount -
com.atproto.server.checkAccountStatus -
com.atproto.server.confirmEmail -
com.atproto.server.createAccount -
com.atproto.server.createInviteCode -
com.atproto.server.createInviteCodes -
com.atproto.server.deactivateAccount -
com.atproto.server.deleteAccount -
com.atproto.server.deleteSession -
com.atproto.server.describeServer -
com.atproto.server.getAccountInviteCodes -
com.atproto.server.getServiceAuth [ ]- not going to add app passwordscom.atproto.server.listAppPasswords-
com.atproto.server.refreshSession -
com.atproto.server.requestAccountDelete -
com.atproto.server.requestEmailConfirmation -
com.atproto.server.requestEmailUpdate -
com.atproto.server.requestPasswordReset -
com.atproto.server.reserveSigningKey -
com.atproto.server.resetPassword []- not going to add app passwordscom.atproto.server.revokeAppPassword-
com.atproto.server.updateEmail
-
com.atproto.sync.getBlob -
com.atproto.sync.getBlocks -
com.atproto.sync.getLatestCommit -
com.atproto.sync.getRecord -
com.atproto.sync.getRepoStatus -
com.atproto.sync.getRepo -
com.atproto.sync.listBlobs -
com.atproto.sync.listRepos [ ]- BGS doesn’t even have this implemented lolcom.atproto.sync.notifyOfUpdate-
com.atproto.sync.requestCrawl -
com.atproto.sync.subscribeRepos
-
com.atproto.label.queryLabels -
com.atproto.moderation.createReport(Note: this should be handled by proxying, not actually implemented in the PDS) -
app.bsky.actor.getPreferences -
app.bsky.actor.putPreferences
License
Section titled “License”This project is licensed under MIT license. server/static/pico.css is also licensed under MIT license, available at https://github.com/picocss/pico/.