Spaces:
Running
Running
| title: HuggingPost | |
| emoji: ๐ฎ | |
| colorFrom: pink | |
| colorTo: indigo | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: true | |
| license: agpl-3.0 | |
| secrets: | |
| - name: HF_TOKEN | |
| description: HF token with WRITE access โ enables DB+uploads backup persistence to a private HF Dataset. | |
| - name: CLOUDFLARE_WORKERS_TOKEN | |
| description: Cloudflare API token to auto-provision an outbound proxy and the Keep-Alive monitor. | |
| [](https://github.com/somratpro/huggingpost) | |
| [](https://opensource.org/licenses/MIT) | |
| [](https://huggingface.co/spaces/somratpro/HuggingPost) | |
| [](https://github.com/gitroomhq/postiz-app) | |
| **Self-host [Postiz](https://postiz.com) (open-source social-media scheduler โ X, LinkedIn, Facebook, Threads, TikTok, YouTube, Pinterest, Reddit, Mastodon, Discord, Slack, and more) on the free Hugging Face Spaces tier.** Persistent across restarts via private HF Dataset backup. No external database, no paid storage required. | |
| ## Table of Contents | |
| - [โจ Features](#-features) | |
| - [๐ Quick Start](#-quick-start) | |
| - [๐ Configuration](#-configuration) | |
| - [๐พ Backup & Persistence](#-backup--persistence) | |
| - [๐ Keep It Awake](#-keep-it-awake) | |
| - [๐ Cloudflare Proxy *(Optional)*](#-cloudflare-proxy-optional) | |
| - [๐ Connecting Social Accounts](#-connecting-social-accounts) | |
| - [๐๏ธ Architecture](#๏ธ-architecture) | |
| - [๐ Troubleshooting](#-troubleshooting) | |
| - [๐ Links](#-links) | |
| ## โจ Features | |
| - ๐ **30+ Social Platforms** โ schedule posts to X, LinkedIn, Facebook, Threads, TikTok, YouTube, Reddit, Mastodon, Discord, Slack, Pinterest, etc. | |
| - โก **One-click deploy** โ duplicate the Space, add `HF_TOKEN`, you're done. | |
| - ๐พ **Persistent across restarts** โ PostgreSQL + uploaded media auto-backed up to a private HF Dataset every 5 min and restored on boot. | |
| - ๐ **Keep-Alive** โ add `CLOUDFLARE_WORKERS_TOKEN` as a Space secret and a cron monitor is created automatically via Cloudflare Workers. | |
| - ๐ **Outbound firewall workaround** โ optional Cloudflare Worker proxy auto-provisioned for blocked platform APIs. | |
| - ๐ **Secrets generated** โ `JWT_SECRET` auto-generated on first boot and persisted, no manual setup. | |
| - ๐ **100% HF-Native** โ no external Postgres/Redis/storage accounts needed for the default path. | |
| - ๐ **Pinned to v2.11.3** โ last release before Postiz mandated Temporal (which doesn't fit in a single HF container). | |
| ## ๐ Quick Start | |
| ### Step 1: Duplicate this Space | |
| [](https://huggingface.co/spaces/somratpro/HuggingPost?duplicate=true) | |
| ### Step 2: Add `HF_TOKEN` | |
| In your new Space's **Settings โ Variables and secrets โ New secret**: | |
| | Secret | How to get it | | |
| | :--- | :--- | | |
| | `HF_TOKEN` | [huggingface.co/settings/tokens](https://huggingface.co/settings/tokens) โ New token โ **Write** access | | |
| > [!WARNING] | |
| > Without `HF_TOKEN`, your data (accounts, scheduled posts, uploaded media) is **lost on every Space restart**. Set this up first. | |
| ### Step 3: Wait for the build (~5โ8 min first time) | |
| Watch progress in the **Logs** tab. The Postiz build is heavy because it compiles a Next.js frontend + NestJS backend. | |
| ### Step 4: Open the Space | |
| Land on the HuggingPost dashboard. Click **Open Postiz โ** to reach the login page. **Sign up** to create the first admin account โ registration is auto-activated unless you set `RESEND_API_KEY`. | |
| ### Step 5: Set Up Keep-Alive (1 min) | |
| Add your **Cloudflare Workers Token** as a Space secret named `CLOUDFLARE_WORKERS_TOKEN`. HuggingPost will automatically create a Worker cron that pings `/health` every 10 min. Without this, the Space will sleep and scheduled posts won't fire. | |
| ## ๐ Configuration | |
| ### Required | |
| | Variable | Purpose | | |
| | :--- | :--- | | |
| | `HF_TOKEN` | Write-access HF token โ enables backup persistence | | |
| ### Recommended | |
| | Variable | Default | Purpose | | |
| | :--- | :--- | :--- | | |
| | `SYNC_INTERVAL` | `3600` | Backup interval in seconds (1 hour) | | |
| | `BACKUP_DATASET_NAME` | `huggingpost-backup` | Private dataset name (`<user>/<name>`) | | |
| | `RESEND_API_KEY` | โ | Required only if you want signup activation emails | | |
| ### Storage (Optional โ for media offload) | |
| By default, uploaded media (post images/videos) is stored in `/postiz/uploads` inside the container and included in the HF Dataset backup. If your media exceeds ~80 MB total, switch to Cloudflare R2: | |
| | Variable | Purpose | | |
| | :--- | :--- | | |
| | `STORAGE_PROVIDER` | Set to `cloudflare` | | |
| | `CLOUDFLARE_ACCOUNT_ID` | R2 account ID | | |
| | `CLOUDFLARE_ACCESS_KEY` | R2 access key | | |
| | `CLOUDFLARE_SECRET_ACCESS_KEY` | R2 secret | | |
| | `CLOUDFLARE_BUCKETNAME` | R2 bucket name | | |
| | `CLOUDFLARE_BUCKET_URL` | Public R2 URL prefix | | |
| R2 free tier is 10 GB storage + 1M reads/month โ plenty for typical use. | |
| ### Advanced | |
| | Variable | Default | Purpose | | |
| | :--- | :--- | :--- | | |
| | `JWT_SECRET` | auto-generated | If unset, generated and persisted on first boot | | |
| | `SYNC_MAX_FILE_BYTES` | `104857600` (100 MB) | Skip backup if tarball exceeds this size | | |
| | `DISABLE_REGISTRATION` | `false` | Set to `true` after creating your admin account | | |
| | `API_LIMIT` | `30` | Public API hourly rate limit | | |
| ## ๐พ Backup & Persistence | |
| Every `SYNC_INTERVAL` seconds (default 5 min), HuggingPost: | |
| 1. Runs `pg_dump` on the Postiz database. | |
| 2. Tars the dump + `/postiz/uploads` + `/postiz/.secrets`. | |
| 3. Uploads `snapshots/latest.tar.gz` to your private dataset `<your-username>/huggingpost-backup`. | |
| On boot, the reverse happens โ secrets restored first, then DB drop+recreate+replay, then uploads copied back. Your scheduled posts, accounts, and media survive restarts. | |
| **To inspect or download your backup:** | |
| ```bash | |
| huggingface-cli download --repo-type dataset <your-username>/huggingpost-backup | |
| ``` | |
| > [!NOTE] | |
| > The dataset is **private** by default. Don't share its URL publicly โ the SQL dump contains your full Postiz state, including encrypted social-media tokens. | |
| ## ๐ Keep It Awake | |
| Free HF Spaces sleep after ~48h of no traffic. A sleeping Space cannot fire scheduled posts. Add your `CLOUDFLARE_WORKERS_TOKEN` as a Space secret. HuggingPost will automatically create a Cloudflare Worker cron that pings the Space every 10 minutes to keep it active. The dashboard shows the current "Keep Awake" status. | |
| ## ๐ Cloudflare Proxy *(Optional)* | |
| Hugging Face Spaces sometimes block outbound HTTP to specific social-platform APIs. HuggingPost ships the same transparent Cloudflare Worker proxy used in HuggingClip / HuggingClaw / Hugging8n. | |
| **Auto-setup:** | |
| 1. Create a Cloudflare API Token with `Workers Scripts: Edit` permission. | |
| 2. Add `CLOUDFLARE_WORKERS_TOKEN` as a Space secret. | |
| 3. Restart the Space. | |
| HuggingPost will create or update a Worker named `<your-space-host>-proxy` and route blocked outbound traffic through it transparently. You can add extra domains with `CLOUDFLARE_PROXY_DOMAINS` (comma-separated, merged with built-in defaults). Set to `*` to proxy all external traffic. | |
| ## ๐ Connecting Social Accounts | |
| Each social platform requires you to register your Postiz instance as an OAuth app. The callback URL pattern is: | |
| ``` | |
| https://<your-space-host>/app/api/integrations/social/<platform>/callback | |
| ``` | |
| (Note the `/app` prefix โ Postiz UI is mounted there so its API is too.) | |
| For each platform you want (X, LinkedIn, Facebook, etc.), follow the [Postiz provider docs](https://docs.postiz.com/providers) to obtain client ID + secret, then enter them inside Postiz **Settings โ Channels** (NOT as Space secrets โ Postiz stores them encrypted in its DB). | |
| > [!TIP] | |
| > Some platforms (like X) require a publicly verifiable domain. The HF Space subdomain (`*.hf.space`) works for most but not all platforms. Check each platform's app-creation requirements. | |
| ## ๐๏ธ Architecture | |
| ``` | |
| HuggingPost/ | |
| โโโ Dockerfile # Two-stage: build Postiz v2.11.3 โ runtime | |
| โโโ start.sh # Orchestrator (Postgres โ Redis โ restore โ procs) | |
| โโโ health-server.js # Port 7860: dashboard + reverse proxy split | |
| โโโ postiz-sync.py # Backup/restore DB + uploads to HF Dataset | |
| โโโ cloudflare-proxy.js # Transparent outbound proxy injected via NODE_OPTIONS | |
| โโโ cloudflare-proxy-setup.py | |
| โโโ cloudflare-keepalive-setup.py | |
| โโโ docker-compose.yml # Local dev convenience | |
| โโโ .env.example # Configuration reference | |
| โโโ README.md | |
| ``` | |
| **Single-port routing** (port 7860, the only port HF Spaces exposes): | |
| | Path | Target | Notes | | |
| | :--- | :--- | :--- | | |
| | `/` | HuggingPost dashboard (local) | Status + Keep Awake tile | | |
| | `/health`, `/status` | local | JSON handlers | | |
| | `/app` or `/app/*` | Postiz nginx `:5000` | `/app` stripped โ Next.js built with `basePath="/app"` | | |
| | `/_next/*`, `/static/*` | 301 โ `/app/<path>` | Catches absolute-URL leaks | | |
| | anything else | 404 | โ | | |
| **Internal processes:** | |
| | Process | Port | Notes | | |
| | :--- | :--- | :--- | | |
| | `health-server.js` | 7860 (public) | Dashboard + reverse proxy | | |
| | nginx | 5000 (internal) | Routes `/api`โ3000, `/uploads`โfs, `/`โ4200 | | |
| | Postiz backend (NestJS) | 3000 | Started by PM2 | | |
| | Postiz frontend (Next.js) | 4200 | Started by PM2, `basePath=/app` baked at build | | |
| | Postiz workers | โ | BullMQ consumer | | |
| | Postiz cron | โ | Schedule tick | | |
| | `postgres` | 5432 | โ | | |
| | `redis-server` | 6379 | โ | | |
| | `postiz-sync.py` (loop) | โ | โ | | |
| Total resident set ~3โ6 GB under typical load โ well within HF free tier's 16 GB. | |
| ## ๐ Troubleshooting | |
| **First boot takes 5โ8 minutes** | |
| The Next.js frontend is not compiled during the Docker build (the HF builder's ~4 GB memory limit is less than `next build` needs). Instead it compiles on first container startup where 16 GB is available. Watch `[frontend-build]` lines in the Logs tab. Postiz starts automatically when done. All subsequent restarts are fast โ the compiled `.next` is stored in the HF Dataset backup and restored at boot. | |
| **"Postiz backend unavailable" on first load** | |
| On restarts after the first boot, wait 30โ90 s for PM2 processes to come up. Check the dashboard status badges. | |
| **Data lost after restart** | |
| `HF_TOKEN` is not set, or it doesn't have write access. Add it and the next restart will restore from backup. The backup must have run at least once before the restart. | |
| **Backup too large (>100 MB)** | |
| Either move media to Cloudflare R2 (`STORAGE_PROVIDER=cloudflare`) or raise `SYNC_MAX_FILE_BYTES`. The HF Dataset itself supports much larger files, but huge backups slow restart. | |
| **Scheduled posts didn't fire while I was away** | |
| The Space slept. Add `CLOUDFLARE_WORKERS_TOKEN` as a Space secret to enable automatic keep-awake monitoring. | |
| **OAuth callback fails for X/Facebook/LinkedIn** | |
| Some platforms reject `*.hf.space` subdomains as redirect URIs. You may need to put a custom domain in front (Cloudflare โ HF Space CNAME). | |
| **Out of memory during build (exit 137 / OOMKilled)** | |
| The Dockerfile patches `apps/frontend/next.config.js` to disable sourcemap generation (`productionBrowserSourceMaps: false` + Sentry `sourcemaps.disable: true`). Without these, peak build memory exceeds HF Space builder limits. If you forked and removed those sed patches, OOM returns. Builds also run apps sequentially (backend โ workers โ cron โ frontend) at 3 GB heap each โ parallel builds OOM. | |
| **`prisma-db-push` fails on first boot** | |
| Usually means Postgres didn't finish starting. Container will exit and HF will auto-restart โ second boot usually succeeds. If it persists, check Logs for the actual Prisma error. | |
| ## ๐ Links | |
| - [Postiz on GitHub](https://github.com/gitroomhq/postiz-app) | |
| - [Postiz docs](https://docs.postiz.com) | |
| - [HuggingFace Spaces docs](https://huggingface.co/docs/hub/spaces) | |
| - More projects: [Hugging8n](https://huggingface.co/spaces/somratpro/Hugging8n) (n8n), [HuggingClip](https://huggingface.co/spaces/somratpro/HuggingClip) (Paperclip), [HuggingClaw](https://huggingface.co/spaces/somratpro/HuggingClaw) (OpenClaw), [HuggingMes](https://huggingface.co/spaces/somratpro/HuggingMes) (Messari) | |
| ## ๐ License | |
| Wrapper code: MIT. Postiz itself: AGPL-3.0 โ see [github.com/gitroomhq/postiz-app](https://github.com/gitroomhq/postiz-app/blob/main/LICENSE) for terms. | |
| *Made with โค๏ธ by [@somratpro](https://github.com/somratpro)* | |