Twice is a clone of the Once distribution system used by Campfire and Writebook.
Through Twice you can generate and distribute license keys with which users can install and run Docker containers of your products on their own servers.
Twice gives you the ability to issue license keys that can be used to install a product.
Products are Docker containers installed from Docker images hosted on a private Docker Registry.
The whole installation process looks like this:
# Download and install the Twice CLI,
# and then install a product with the license key nx1w-qg52-e5t3-kpa4 from auth.example.com
/bin/bash -c "$(curl -fsSL http://auth.example.com/install/nx1w-qg52-e5t3-kpa4)"
# Install a product with the license key nx1w-qg52-e5t3-kpa4 from example.org
twice setup nx1w-qg52-e5t3-kpa4@example.org
✅ Docker is installed
✅ Docker is running
✅ License is valid
├──Auth server: example.org
├──License key: nx1w-qg52-e5t3-kpa4
├──License owner: kaladin.stormblessed@example.com
└──Product: Sphere Sorter
✅ Product added to the config
✅ App downloaded
Enter the domain (e.g. example.com) where you\'ll run the app: example.com
Do you want to enable HTTPS? (YES/no): yes
├──Domain: example.com
└──HTTPS: true
Is this correct? (yes/NO): yes
✅ Product config saved
✅ App is running
curl -H "Host: example.com" https://localhost/up
OK
twice status
┌────────────────────────┬───────────────┬─────────────────────┬────────────────┬─────────┐
│ ID │ PRODUCT │ LICENSE │ AUTH SERVER │ STATUS │
├────────────────────────┼───────────────┼─────────────────────┼────────────────┼─────────┤
│ sphere-sorter-580e3812 │ Sphere Sorter │ nx1w-qg52-e5t3-kpa4 │ example.org │ Running │
└────────────────────────┴───────────────┴─────────────────────┴────────────────┴─────────┘
twice stop sphere-sorter-580e3812
✅ Product stopped
twice status
┌────────────────────────┬───────────────┬─────────────────────┬────────────────┬─────────┐
│ ID │ PRODUCT │ LICENSE │ AUTH SERVER │ STATUS │
├────────────────────────┼───────────────┼─────────────────────┼────────────────┼─────────┤
│ sphere-sorter-580e3812 │ Sphere Sorter │ nx1w-qg52-e5t3-kpa4 │ example.org │ Stopped │
└────────────────────────┴───────────────┴─────────────────────┴────────────────┴─────────┘
You can distribute one or more products this way, and even copies of the same product.
A detailed explanation of how all of this works, and how Twice came to be, can be found here. Release 0.1.0 contains all the code referenced in that article.
This is a mono-repo that contains 3 projects:
- Auth
- CLI
- Registry
Auth handles 3 tasks - it provides installation scripts and binaries, it is the auth backend for the Registry, and it manages products and license keys.
CLI installs a product associated with a given license key and manages all installed products.
Registry is a Docker Registry that hosts app images for products.
First, make sure you have the following installed:
- Ruby 3.4 or newer
- Go 1.23 or newer
- Docker
- Docker Compose
Second, from the root of the project run bin/setup
.
This will setup the Registry and the Auth server so that they can talk to one another. And it will compile the CLI, and prepare it to be distributed using the Auth server.
Third, in a separate terminal window, from the registry
directory,
run docker compose up
to start the registry.
Check out the docker-compose.yml file to see how the registry is configured, and change it for your OS.
Fourth, in another terminal window from the auth
directory run:
bundle
bin/rails db:create db:migrate db:fixtures:load
bin/dev
This will install all the necessary dependencies, create the database, run the migrations, and then start the server on localhost:3000.
You can login with any Developer account to the Auth UI.
Out-of-the-box there are several accounts already pre-populated
(if you've run bin/rails db:fixtures:load
). You can take a look
at developers.yml to see which
accounts exists and what their credentials are.
In the UI you can create products, developers, customers, and purchase licenses for customers.
You can also install a product directly from the auth server using this command:
/bin/bash -c "$(curl -fsSL http://localhost:3000/install/nx1w-qg52-e5t3-kpa4)"
This will download and install the cli binary, and then run it, passing it the license key from the URL.
Using the same credentials you can login to the Registry and push any Docker image you like to it.
Just note that only developer accounts have push access to the registry
docker login --username jezrien@example.com --password password http://localhost:5000
docker pull hello-world
docker tag hello-world http://localhost:5000/hello-world
docker push http://localhost:5000/hello-world
To delete images from the registry you can use
bin/delete-image localhost:5000 hello-world jezrien@example.com password
To install a product using the CLI you have to run the following command from the cli
directory:
go run cmd/twice/main.go setup <license-key>
# e.g. `go run cmd/twice/main.go setup nx1w-qg52-e5t3-kpa4`
This will pull the product's Docker image from the registry and spin up a container for it
To uninstall the CLI run
rm /usr/local/bin/twice
That's it.
This project is licensed under the MIT License, you can read the full license here.
Long story short, you can do whatever you want with this code, as long as you include the original, unchanged, license of this project in your project and give proper attribution.