2026-05-08 14:06:08 +02:00
2025-08-18 22:10:27 +02:00
2025-11-19 19:08:21 +01:00
2025-09-13 09:32:59 +02:00
wip
2026-05-08 14:06:08 +02:00
wip
2026-05-08 14:06:08 +02:00
wip
2026-05-08 14:06:08 +02:00
2025-09-07 12:43:19 +02:00
wip
2026-05-08 14:06:08 +02:00
2025-09-07 19:02:26 +02:00
2025-09-07 19:02:26 +02:00
2025-09-07 01:14:19 +02:00
2025-08-07 00:16:46 +02:00
wip
2026-05-08 14:06:08 +02:00
wip
2026-05-08 14:06:08 +02:00

CloudSave

CloudSave is a small client/server tool to keep save folders in sync across multiple computers. It is aimed at games that do not provide their own cloud sync, such as emulators, old games, or any title that stores progress in a local directory.

The project is still in alpha.

What Is In The Repository

This repository currently contains three Go binaries:

  • cmd/cli: the end-user CLI (cloudsave)
  • cmd/server: the HTTP API server
  • cmd/web: a small read-only web UI that talks to the API server

Build

The module targets Go 1.24 in go.mod, while the container image builds with Go 1.26.3 from dockerfile. In practice, using a recent Go toolchain is recommended.

To build all binaries for the platforms configured in the project:

./build.sh

Artifacts are written to ./build.

If you only want one binary, you can also build it directly:

go build -o cloudsave ./cmd/cli
go build -o cloudsave_server ./cmd/server
go build -o cloudsave_web ./cmd/web

Server

The server exposes an authenticated HTTP API on port 8080 by default.

Data Directory

By default, the server uses:

/var/lib/cloudsave

You can override it with:

cloudsave_server -document-root /path/to/cloudsave-data

Inside this directory, the server expects:

  • .htpasswd: credentials file
  • data/: stored save archives and metadata

Authentication

The API uses HTTP Basic Auth. Credentials are read from .htpasswd.

Example:

test:$2y$10$uULsuyROe3LVdTzFoBH7HO0zhvyKp6CX2FDNl7quXMFYqzitU0kc.

The code currently expects bcrypt hashes when validating passwords.

Start The Server

cloudsave_server

Useful flags from cmd/server/runner.go:

  • -document-root: change the storage directory
  • -port: change the listening port
  • -no-cache: use the lazy repository instead of the eager cache
  • -verbose: enable more logs

On non-Windows systems, sending SIGHUP reloads the eager cache and the .htpasswd file.

Docker

The repository contains a server-only container setup:

Run it with:

docker compose up --build

This maps:

  • port 8080
  • local ./data to /var/lib/cloudsave

Before starting the container, you still need to create ./data/.htpasswd.

Client

The CLI stores its local database in the user config directory under cloudsave/data.

It keeps:

  • per-game metadata
  • current local archive
  • backup archives
  • remote.json per game when a remote is configured

Saved credentials are stored separately in credential.json.

Important: the login command stores credentials in plain text. This is also stated in the code.

Typical Workflow

1. Register a game

cloudsave add /home/user/gamedata

You can override the displayed name:

cloudsave add -name "My Game" /home/user/gamedata

Note: the -remote flag exists on add, but the current implementation does not persist it. Use cloudsave remote -set after add.

2. List registered games

cloudsave list

To include local backup IDs:

cloudsave list -include-backup

3. Create or refresh the local archive

cloudsave scan

This scans all registered folders. If a folder changed since the last scan, the current archive is moved to the backup history and a new data.tar.gz archive is created.

4. Configure the remote server for a game

cloudsave remote -set GAME_ID http://localhost:8080

To list configured remotes:

cloudsave remote -list

5. Save credentials locally

cloudsave login http://localhost:8080

This verifies the credentials against the server and then stores them locally in plain text.

6. Synchronize with the server

cloudsave sync

The sync command:

  • groups games by remote URL
  • authenticates once per remote
  • compares local and remote metadata
  • pushes or pulls as needed
  • asks for a resolution if versions conflict

7. Restore a save locally

Apply the latest local archive for a game:

cloudsave apply GAME_ID

Apply a specific backup:

cloudsave apply GAME_ID BACKUP_ID

Other CLI Commands

Show metadata for one game:

cloudsave show GAME_ID

Pull one game and its backups from a remote into a local path:

cloudsave pull http://localhost:8080 GAME_ID /path/to/restore

Show local version information:

cloudsave version

Show remote version information:

cloudsave version -a http://localhost:8080

Remove a registered game and its local backups:

cloudsave remove GAME_ID

Web UI

The repository also contains a small web frontend in cmd/web.

It uses a JSON config file, for example:

{
  "server": {
    "port": 8081
  },
  "remote": {
    "url": "http://localhost:8080"
  }
}

Then start it with:

cloudsave_web -config /path/to/config.json

The web UI itself does not manage users. It forwards HTTP Basic Auth credentials to the configured API server.

Current Caveats

These points are worth knowing in the current state of the project:

  • the software is still alpha
  • credentials saved by cloudsave login are stored in plain text
  • the Docker setup only runs the API server, not the web UI
  • add -remote is exposed by the CLI but is not currently persisted by the service layer
Description
No description provided
Readme MIT 248 KiB
0.0.4d Latest
2025-09-02 19:31:27 +02:00
Languages
Go 91%
HTML 5.6%
Shell 3.4%