Spaces:
Running
Running
File size: 13,504 Bytes
b4d7c1c 7ac2f89 b4d7c1c 5d2b465 b4d7c1c 5d2b465 b4d7c1c 5d2b465 b4d7c1c 2869840 b4d7c1c 5d2b465 b4d7c1c ff3303a b4d7c1c 8de0b02 b4d7c1c 8de0b02 b4d7c1c 5d2b465 b4d7c1c 5d2b465 ff3303a 8de0b02 b4d7c1c 8de0b02 b4d7c1c 8de0b02 b4d7c1c 866a8e6 b4d7c1c 866a8e6 b4d7c1c 5d2b465 b4d7c1c 8de0b02 b4d7c1c 83c8430 b4d7c1c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | ---
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
Similar projects by [@somratpro](https://github.com/somratpro) β all free, one-click deploy on HF Spaces:
| Project | What it runs | HF Space | GitHub |
| :--- | :--- | :--- | :--- |
| **HuggingFlow** | DeerFlow β deep research agent | [Space](https://huggingface.co/spaces/somratpro/HuggingFlow) | [Repo](https://github.com/somratpro/HuggingFlow) |
| **HuggingClip** | Paperclip β AI agent orchestration platform | [Space](https://huggingface.co/spaces/somratpro/HuggingClip) | [Repo](https://github.com/somratpro/huggingclip) |
| **HuggingClaw** | OpenClaw β Claude Code in the browser | [Space](https://huggingface.co/spaces/somratpro/HuggingClaw) | [Repo](https://github.com/somratpro/huggingclaw) |
| **HuggingMes** | Hermes β Self-hosted agent gateway | [Space](https://huggingface.co/spaces/somratpro/HuggingMes) | [Repo](https://github.com/somratpro/huggingmes) |
| **Hugging8n** | n8n β workflow & automation platform | [Space](https://huggingface.co/spaces/somratpro/Hugging8n) | [Repo](https://github.com/somratpro/hugging8n) |
## π 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)*
|