Upload a file, get a public URL. A small Go CLI that publishes assets to a Google Cloud Storage bucket served through Cloud CDN.
Free and MIT licensed. macOS and Linux, amd64 and arm64.
Files that need a stable public URL and nothing else.
A logo for an email signature, a resume PDF, an image shared in a chat. They all
live in one public bucket behind a custom domain. pushcdn uploads
them with sensible headers and prints the URL.
One or many files, optional destination folder or rename, content type inferred from the extension, progress bar on a terminal.
Prefix match or server-side glob such as '*logo*', so listings stay fast on large buckets.
pushcdn rm asks before deleting.
Defaults to public, max-age=3600. Override per upload with --cache-control.
Uses Application Default Credentials from gcloud. No token cache, no service account file.
The repository ships the Terraform for the public bucket.
brew tap bcollard/push-to-cdn
brew install --cask push-to-cdn
go install github.com/bcollard/push-to-cdn@latest
Download an archive from GitHub Releases and put pushcdn on your PATH.
# one-time setup
gcloud auth application-default login
pushcdn config set bucket cdn.runlocal.dev
pushcdn config set base-url https://cdn.runlocal.dev
# upload
pushcdn upload ~/Pictures/logo.png
# https://cdn.runlocal.dev/logo.png
# upload into a folder, or rename
pushcdn upload logo.png -d brand/
pushcdn upload logo.png -d brand/icon.png
# list, filter, delete, print URL
pushcdn ls
pushcdn ls '*logo*'
pushcdn rm old.png
pushcdn url logo.png
Resolution order: environment variable, stored config, built-in default.
| Key | Environment variable | Description |
|---|---|---|
bucket | PUSHCDN_BUCKET | GCS bucket name |
project | PUSHCDN_PROJECT | GCP project ID (informational) |
base-url | PUSHCDN_BASE_URL | Public URL prefix used when printing URLs |
Stored in ~/.config/pushcdn/config.json with mode 0600.
roles/storage.objectViewer to allUsers. Everything in it is public. Do not upload anything sensitive.bucket and base-url. The Terraform in the repository creates the bucket. The load balancer and DNS are separate.cdn.runlocal.dev after you verify domain ownership in Google Search Console. A hyphenated name such as cdn-runlocal-dev avoids that step.Cache-Control. Upload with a short --cache-control value, or upload under a new name.