To continue innovating in this space and supporting our larger projects, we need to keep our small team focused on the most impactful work. On 29 November 2024, we will be sunsetting Charm Cloud. At that time we will be removing the servers from production and archiving the project on GitHub. Charm Cloud is self-hostable, so you can back up your data before that time and continue using this project on your own server.
The code will continue to be open source and publicly available. If you love this project and would like to maintain a fork, please do.
Learn more about self-hosting Charm Cloud.
To configure both Skate and Glow to work with your own server, you'll need to update the Charm Cloud client environment variables. Glow historically integrated into the Charm Cloud via a stashing feature, but as of Skate v1.0.0 and Glow v2.0.0 the Charm Cloud integration in both applications has been removed (Skate now operates on a local database: to migrate your data see the Skate v1.0.0 Release Notes). For those using older versions, you can continue to use Charm Cloud features with your own server. Here are the relevant environment variables:
// Config contains the Charm client configuration.
type Config struct {
Host string `env:"CHARM_HOST" envDefault:"cloud.charm.sh"`
SSHPort int `env:"CHARM_SSH_PORT" envDefault:"35353"`
HTTPPort int `env:"CHARM_HTTP_PORT" envDefault:"35354"`
Debug bool `env:"CHARM_DEBUG" envDefault:"false"`
Logfile string `env:"CHARM_LOGFILE" envDefault:""`
KeyType string `env:"CHARM_KEY_TYPE" envDefault:"ed25519"`
DataDir string `env:"CHARM_DATA_DIR" envDefault:""`
IdentityKey string `env:"CHARM_IDENTITY_KEY" envDefault:""`
}
Source: https://github.com/charmbracelet/charm/blob/main/client/client.go
Thanks for using the Charm Cloud and please chat us up in Discord if you have any questions.
Charm is a set of tools that makes adding a backend to your terminal-based applications fun and easy. Quickly build modern CLI applications without worrying about user accounts, data storage and encryption.
- Charm KV: an embeddable, encrypted, cloud-synced key-value store built on BadgerDB
- Charm FS: a Go
fs.FS
compatible cloud-based user filesystem - Charm Crypt: end-to-end encryption for stored data and on-demand encryption for arbitrary data
- Charm Accounts: invisible user account creation and authentication
Thereās also the powerful Charm Client for directly accessing
Charm services. Self-hosting a Charm Cloud is as simple as
running charm serve
.
Use a package manager:
# macOS or Linux
brew install charmbracelet/tap/charm
# Arch Linux (btw)
pacman -S charm
# Nix
nix-env -iA nixpkgs.charm
# Debian/Ubuntu
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://repo.charm.sh/apt/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/charm.gpg
echo "deb [signed-by=/etc/apt/keyrings/charm.gpg] https://repo.charm.sh/apt/ * *" | sudo tee /etc/apt/sources.list.d/charm.list
sudo apt update && sudo apt install charm
# Fedora/RHEL
echo '[charm]
name=Charm
baseurl=https://repo.charm.sh/yum/
enabled=1
gpgcheck=1
gpgkey=https://repo.charm.sh/yum/gpg.key' | sudo tee /etc/yum.repos.d/charm.repo
sudo yum install charm
Or download a package or binary from the releases page. All major platforms and architectures are supported, including FreeBSD and ARM.
You can also just build and install it yourself:
git clone https://github.com/charmbracelet/charm.git
cd charm
go install
A powerful, embeddable key-value store built on BadgerDB. Store user data, configuration, create a cache or even store large files as values.
When you use Charm KV your users automatically get cloud backup, multi-machine syncing, end-to-end encryption, and the option to self-host.
import "github.com/charmbracelet/charm/kv"
// Open a database (or create one if it doesnāt exist)
db, err := kv.OpenWithDefaults("my-cute-db")
if err != nil {
log.Fatal(err)
}
defer db.Close()
// Fetch updates and easily define your own syncing strategy
if err := db.Sync(); err != nil {
log.Fatal(err)
}
// Save some data
if err := db.Set([]byte("fave-food"), []byte("gherkin")); err != nil {
log.Fatal(err)
}
// All data is binary
if err := db.Set([]byte("profile-pic"), someJPEG); err != nil {
log.Fatal(err)
}
Charm KV can also enhance existing BadgerDB implementations. It works with standard Badger transactions and provides top level functions that mirror those in Badger.
For details on Charm KV, see the Charm KV docs.
Each Charm user has a virtual personal filesystem on the Charm server. Charm FS provides a Go fs.FS implementation for the user along with additional write and delete methods. If you're building a tool that requires file storage, Charm FS will provide it on a networked-basis without friction-filled authentication flows.
import charmfs "github.com/charmbracelet/charm/fs"
// Open the userās filesystem
cfs, err := charmfs.NewFS()
if err != nil {
log.Fatal(err)
}
// Save a file
data := bytes.NewBuffer([]byte("some data"))
if err := cfs.WriteFile("./path/to/file", data, fs.FileMode(0644), int64(data.Len())); err != nil {
log.Fatal(err)
}
// Get a file
f, err := cfs.Open("./path/to/file")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Just read whole file in one shot
data, err := cfs.ReadFile("./path/to/file")
if err != nil {
log.Fatal(err)
}
Are there any file size limits?
There are no limitations in file size per se, although there's a 1 GB cap on storage for the free Charm accounts, but you can get unlimited if you self-host the Charm Cloud.
Is it possible to not have a local copy of the database?
No. Skate uses BadgerDB and keeps a local copy of the key-value store. The local databases are synced through the Charm Cloud.
For more on Charm FS see the Charm FS docs.
All data sent to a Charm server is fully encrypted on the client. Charm Crypt provides methods for easily encrypting and decrypting data for a Charm user. All key management and account linking is handled seamlessly by Charm.
For more on Charm Crypt see the Charm Crypt docs.
The best part of Charm accounts is that both you and your users donāt need to think about them. Charm authentication is based on SSH keys, so account creation and authentication is built into all Charm tools and is invisible and frictionless.
If a user already has Charm keys, we authenticate with them. If not, we create new ones. Users can also easily link multiple machines to their account, and linked machines will seamlessly gain access to their owners Charm data. Of course, users can revoke machinesā access too.
You can use charm backup-keys
to backup your account keys. Your account can
be recovered using charm import-keys charm-keys-backup.tar
The charm
binary also includes easy access to a lot of the functionality
available in the libraries. This could be useful in scripts, as a standalone
utility or when testing functionality.
# Link a machine to your Charm account
charm link
# Set a value
charm kv set weather humid
# Print out a tree of your files
charm fs tree /
# Encrypt something
charm crypt encrypt < secretphoto.jpg > encrypted.jpg.json
# For more info
charm help
The Charm client can be configured using environment variables. These are the defaults:
CHARM_HOST
: Server public URL (default cloud.charm.sh)CHARM_SSH_PORT
: SSH port to connect to (default 35353)CHARM_HTTP_PORT
: HTTP port to connect to (default 35354)CHARM_DEBUG
: Whether debugging logs are enabled (default false)CHARM_LOGFILE
: The file path to output debug logsCHARM_KEY_TYPE
: The type of key to create for new users (default ed25519)CHARM_DATA_DIR
: The path to where the user data is storedCHARM_IDENTITY_KEY
: The path to the identity key used for auth
Charm libraries point at our Charmbracelet, Inc. servers by default (thatās
cloud.charm.sh), however it's very easy for users to host their own Charm
instances. The charm
binary is a single, statically-linked executable capable
of serving an entire Charm instance:
charm serve
The Charm server can be configured using environment variables. These are the defaults:
CHARM_SERVER_BIND_ADDRESS
: Network interface to listen to (default 0.0.0.0)CHARM_SERVER_HOST
: Hostname to advertise (default localhost)CHARM_SERVER_SSH_PORT
: SSH server port to listen to (default 35353)CHARM_SERVER_HTTP_PORT
: HTTP server port to listen to (default 35354)CHARM_SERVER_STATS_PORT
: Stats server port to listen to (default 35355)CHARM_SERVER_HEALTH_PORT
: Health server port to listen to (default 35356)CHARM_SERVER_DATA_DIR
: Server data directory (default ./data)CHARM_SERVER_USE_TLS
: Whether to use TLS (default false)CHARM_SERVER_TLS_KEY_FILE
: The TLS key file path to useCHARM_SERVER_TLS_CERT_FILE
: The TLS cert file path to useCHARM_SERVER_PUBLIC_URL
: Server public URL, useful when hosting the Charm server behind a TLS enabled reverse proxyCHARM_SERVER_ENABLE_METRICS
: Whether to enable collecting Prometheus metrics (default false) Metrics can be accessed fromhttp://<CHARM_SERVER_HOST>:<CHARM_SERVER_STATS_PORT>/metrics
CHARM_SERVER_USER_MAX_STORAGE
: Maximum FS storage for a user (default 0) Zero means no limit
To change hosts, users can set CHARM_HOST
to the domain or IP of their
choosing:
export CHARM_HOST=burrito.example.com
See instructions for Systemd and Docker.
The max data you can store on our Charm Cloud servers is 1GB per account.
By default, self-hosted servers don't have a data storage limit. Should you
want to set a max storage limit on your server, you can do so using
CHARM_SERVER_USER_MAX_STORAGE
To set up TLS, you should set CHARM_SERVER_USE_TLS
to true
, and specify
CHARM_SERVER_HOST
, CHARM_SERVER_TLS_KEY_FILE
, and
CHARM_SERVER_TLS_CERT_FILE
file paths.
- Glow: Render markdown on the CLI, with pizzazz! š š»
- Skate: A personal key-value store š¼
- Your app here! Let us know what you build
Weād love to hear your thoughts on this project. Feel free to drop us a note!
Part of Charm.
Charmēē±å¼ęŗ ā¢ Charm loves open source