Shoutrrr: a self-hosted social media scheduler you run on your own server
An open-source alternative to Buffer, Typefully, and Hootsuite. Write once and schedule everywhere.
At a glance
- What is it?
- Shoutrrr is an Apache-2.0 Laravel and React application that schedules posts to X, Bluesky, LinkedIn, Facebook, Instagram, Threads and Discord from one calendar. It ships as a single Docker image that runs the web app, queue worker and scheduler together, and it defaults to SQLite.
- Who is it for?
- Adopt Shoutrrr if you already run Docker on a box you control and you want your social tokens, drafts and analytics to stay there, and if your targets are among the seven supported networks. Skip it if you need short-video-first networks, or if you want a vendor to carry the OAuth maintenance burden.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Shoutrrr replaces, and for whom
Buffer, Typefully and Hootsuite are hosted products. You pay per seat, you hand over OAuth tokens for every connected account, and your drafts and analytics live in someone else's database. Shoutrrr is the same category of tool built to run on your own infrastructure. The README states the pitch directly: "Write once, publish everywhere. Schedule posts to X, Bluesky, LinkedIn, Facebook, Instagram, Threads, and Discord from one calendar, on your own server, with your own data."
The intended users are individuals and small teams, and the README adds a second audience: agencies that need to keep clients separated. Workspaces, role-based memberships, email invitations and ownership transfer exist for that reason, and every record is scoped to its workspace. If you post to one account on one network, the workspace machinery is overhead you will click past. If you manage three client brands and a personal feed, the scoping is the feature.
The licence is Apache-2.0, which matters here more than usual: you are running a service that stores credentials for third-party APIs, and a permissive licence means you can read the token handling rather than trust a description of it.
The publish path: composer, queue, per-target retries
The architecture visible in the README is a Laravel application with a React and Inertia frontend, and the Docker image "runs the web app, queue worker, and scheduler in one container." That single-container design is the central engineering decision. On a hosted scheduler the queue is someone else's problem; here the queue worker and the scheduler run beside the web process, which is why the project describes the image as "ideal for a single box."
The data flow starts in the composer, which the README describes as a draft surface with media, alt text and "live per-account text and video limits (including detected X subscription limits)." Long posts are split into threads automatically "where the platform supports it." The platform table shows which ones do: X, Bluesky, Threads and Discord support threads; LinkedIn, Facebook and Instagram are listed as single post only. That table is also where the real constraints live. Instagram publishing requires media and caps text at 2,200 characters. X on a free account is limited to 280 characters and a 2 minute 20 second video, while Premium tiers allow up to 25,000 characters and up to 4 hours of video. Discord accepts up to 2000 characters and 10 files of at most 10 MiB each.
From the composer a post goes to the queue or publishes immediately. The README states that each target "publishes independently and retries on failure," so one network rejecting a post does not cancel the others. Connected accounts are linked by OAuth 2.0 for X and LinkedIn, ATProto OAuth or app passwords for Bluesky, Facebook Login for Facebook and Instagram, and a channel webhook URL for Discord. Tokens are stored encrypted and refreshed automatically. Analytics are per-network and uneven: LinkedIn analytics are listed as not available for personal accounts, and Discord reports reactions only.
Installing Shoutrrr with Docker and publishing a first post
The README recommends the prebuilt image. Pull it first:
docker pull ghcr.io/coollabsio/shoutrrr:latestYou need an application key before the container will run. Create a production env file with the URL the browser will use, then generate the key with a throwaway container and paste the output into the APP_KEY line:
cat > .env.prod <<'EOF'
APP_URL=http://localhost:8080
APP_KEY=base64:PASTE_GENERATED_KEY_HERE
EOF
docker run --rm --entrypoint php ghcr.io/coollabsio/shoutrrr:latest /var/www/html/artisan key:generate --showThe second command prints a base64 key. Replace the placeholder with it. The README does not document what happens if the key is missing or rotated after data exists, so treat it as a value to generate once and keep.
Next, create the two persistent volumes the README names, one for storage and one for the SQLite database, then start the container on port 8080:
docker volume create shoutrrr-storage
docker volume create shoutrrr-sqlite
docker run -d \
--name shoutrrr \
--env-file .env.prod \
-p 8080:8080 \
-v shoutrrr-storage:/var/www/html/storage \
-v shoutrrr-sqlite:/var/www/html/database/sqlite \
ghcr.io/coollabsio/shoutrrr:latestOpen http://localhost:8080. The README describes email and password sign-up with verification, plus optional two-factor (TOTP) and passkeys. Once you are in, connect an account, write a draft in the composer, and either drop it into the queue or publish immediately. To publish on a schedule instead, set recurring posting slots in the workspace timezone and place the draft in the queue; the month calendar shows what is pending.
The repository also carries docker-compose.production.yaml and docker-compose.yml. The latter is minimal, defining a single app service named shoutrrr on a bridge network called shoutrrr, with restart: unless-stopped and host.docker.internal mapped through host-gateway. If you prefer Compose over a long docker run line, that file is the starting point, but the env file and volumes still have to be supplied.
Where Shoutrrr stops being the right tool
The platform table is the honest boundary. Seven networks are supported, and the ones people most often ask about for this kind of tool, TikTok and YouTube, are not in it. If your publishing plan is video-first, Shoutrrr does not cover it and no configuration will change that.
Analytics are the second gap, and the README says so rather than hiding it. LinkedIn analytics are unavailable for personal accounts. Bluesky reports likes, reposts and replies but no impressions. Discord reports reactions. Only X and Facebook list impressions. If you are choosing a scheduler because you want a single dashboard of reach across networks, you will get a partial one, and the missing rows are determined by provider APIs rather than by Shoutrrr.
Self-hosting shifts operational work onto you. OAuth tokens expire, providers change scopes, and the README's own feature list includes getting "nudged when one needs reconnecting." On a hosted product that nudge arrives because a company employs people to keep the integrations current. Here it arrives because you are running the current release. The single-container default also concentrates failure: the web app, queue worker and scheduler share one process group, so a crash affects scheduled publishing, not just the interface. The README notes you can move to Postgres and Redis "later if you need to scale out," which is an admission that the SQLite default is a single-box answer.
Media is a quieter constraint. The .env.example describes FILESYSTEM_DISK with a public option and an s3 option for object storage, and warns that direct video uploads require bucket CORS to allow PUT. A default install that stores media on the container filesystem is fine until the volume fills or the host is rebuilt.
Shoutrrr compared with hosted schedulers and with Apprise
Against Buffer, Typefully and Hootsuite the difference is not features, it is custody. A hosted scheduler holds your OAuth tokens and your posting history on its servers and charges per seat for team access. Shoutrrr holds them in encrypted form in your own database, behind volumes you created, and charges nothing. The trade is that you inherit upgrades and integration breakage. A hosted product also tends to add networks faster, because adding a network is a business decision rather than a pull request.
The comparison that trips people up is Apprise, which appears repeatedly in related searches. Apprise is a notification library: you hand it a URL and it delivers a message to one of many services. Shoutrrr, despite the similar name and the same self-hosting audience, is a scheduling application with a calendar, a queue, a composer, workspaces and analytics. It is a place where posts are written and planned. Apprise is a transport you call from your own code. If what you want is a cron job that pings you when a backup finishes, Shoutrrr's social calendar is the wrong shape entirely, and so is its seven-network list.
There is a third option worth naming: running nothing and posting by hand. For one account on one network at low volume, the setup cost of a Docker host, an app key, backups and periodic upgrades exceeds the time saved. Shoutrrr pays off at the point where coordination, not typing, is the bottleneck.
Maintenance, upgrades and what the licence leaves to you
The repository is not archived and the last push was on 2026-09-03. Releases are frequent: v1.4.4 on 2026-08-24, v1.4.3 and v1.4.2 earlier in August. That cadence is the good news for a self-hosted tool, because it means the OAuth integrations are being touched. It also means you should expect to pull new images rather than run one for a year.
Upgrade cost is dominated by the database and the app key, not by the image. The README's quick start uses SQLite on a named volume, and the .env.example mentions Postgres and Redis as later options. The README does not document a rollback procedure, so the practical safeguard is a copy of the SQLite volume or a database dump before you pull a new tag. The Dockerfile bakes APP_VERSION into the frontend bundle and exposes it to PHP at runtime, and notes that an empty value at build time yields a blank version badge rather than a failure, so a locally built image will not tell you which version you are running.
On licensing: Apache-2.0 permits commercial and private use, modification and redistribution, and it includes an explicit patent grant. It also requires that you keep the licence and notices and state significant changes if you redistribute. Running Shoutrrr on your own server for your own team is ordinary use and does not trigger redistribution obligations. That is a description of the licence text, not legal advice; if you plan to ship a modified Shoutrrr to customers, read the Apache-2.0 terms or ask counsel.
One deployment detail worth checking before you commit: the .env.example documents TRUSTED_PROXIES for running behind Coolify or Traefik, and states that HTTPS redirects and OAuth callback URLs are generated from the trusted proxy headers. Get that wrong behind a reverse proxy and the OAuth flow is where it will show.
Editorial conclusion
Adopt Shoutrrr if you already run Docker on a box you control and you want your social tokens, drafts and analytics to stay there, and if your targets are among the seven supported networks. Skip it if you need short-video-first networks, or if you want a vendor to carry the OAuth maintenance burden. Before committing, verify the APP_KEY generation step, confirm your FILESYSTEM_DISK choice for media, and check the docker-compose.production.yaml file for the services your deployment actually needs.
Frequently asked questions
How do I use Shoutrrr?
Run the Docker image, generate an APP_KEY with the artisan key:generate command the README gives, then open the app on port 8080. Inside, connect your accounts, write a post in the composer, and either publish immediately or drop it into the queue with recurring posting slots.
What is a self-hosted alternative to Buffer and Hootsuite?
Shoutrrr describes itself as an open-source, self-hostable alternative to Buffer, Typefully and Hootsuite. It schedules posts to X, Bluesky, LinkedIn, Facebook, Instagram, Threads and Discord from one calendar, and runs on your own server under the Apache-2.0 licence.
What is the difference between Shoutrrr and Apprise?
Shoutrrr is a scheduling application with a composer, queue, calendar, workspaces and analytics for seven social networks. Apprise is a notification library that delivers a message to a service when your own code calls it. The two share a self-hosting audience but not a purpose.
Does Shoutrrr need Postgres or Redis?
No. The README states the image defaults to SQLite with no external services, and that you can switch to Postgres or Redis later if you need to scale out. The quick start mounts a separate volume for the SQLite database.
Which social networks can Shoutrrr publish to?
X, Bluesky, LinkedIn, Facebook Pages, Instagram, Threads and Discord. Threads are supported on X, Bluesky, Threads and Discord; LinkedIn, Facebook and Instagram are listed as single post only, and Instagram publishing requires media.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/coollabsio-shoutrrr)