📅 技術調査 - Postiz
目次

📅 技術調査 - Postiz

■概要

Postiz は、オープンソースの AI 駆動型 SNS スケジューリングツールです。AGPL-3.0 ライセンスで公開しており、セルフホストとクラウドホストの両方で利用できます。

Buffer や Hootsuite はプロプライエタリなクラウドサービスです。Postiz はソースコードを自社インフラに展開できる点が異なります。ホスト版とセルフホスト版は基本機能が共通ですが、クラウド版にはプラン別の機能制限があります(後述)。

比較軸 Postiz Buffer Hootsuite
ライセンス AGPL-3.0(オープンソース) プロプライエタリ プロプライエタリ
セルフホスト 可能 不可 不可
AI 機能 OpenAI / CopilotKit 統合 AI アシスタント(限定) 限定的
マルチテナント 対応 未対応 未対応
対応プラットフォーム数 15 以上 主要 4〜6 20 以上
月額料金(最低) $29(クラウド版) $6 $49

料金・機能情報は 2026 年 2 月時点の各公式サイト情報に基づきます。最新情報は各サービスの公式サイトを確認してください。

対応 SNS プラットフォーム

プラットフォーム カテゴリ
X(旧 Twitter) SNS
LinkedIn ビジネス SNS
Instagram 写真・動画
Facebook Pages SNS
YouTube 動画
TikTok 短尺動画
Threads SNS
Pinterest 画像共有
Reddit コミュニティ
Discord コミュニティ
Slack ビジネスチャット
Mastodon 分散型 SNS
Bluesky 分散型 SNS
Google My Business ローカルビジネス
Dribbble デザイナー向け

■特徴

  • オープンソース: AGPL-3.0 ライセンスで公開。ソースコードの閲覧・改変・自社展開が可能
  • セルフホスト対応: Docker Compose、Kubernetes(Helm)、PM2 での展開をサポート
  • AI コンテンツ生成: OpenAI および CopilotKit を通じた投稿文の自動生成
  • マルチプラットフォーム: 15 以上の SNS プラットフォームへの同時投稿・スケジューリング
  • マルチテナント: 複数組織に独立した環境を提供する Postiz-as-a-Service 機能を搭載
  • チーム協業: ロールベースアクセス制御(SUPERADMIN / ADMIN / USER)と組織ワークスペースでの複数メンバー管理
  • 自動化連携: N8N、Make.com、Zapier との統合に対応
  • マーケットプレイス: ユーザー間での投稿の交換・売買機能を内蔵
  • 分析機能: 投稿パフォーマンスの計測・分析ダッシュボードを提供
  • ストレージ選択: ローカルストレージと Cloudflare R2 の両方に対応
  • REST API: 完全な REST API を公開。外部システムとの統合が可能

■構造

●システムコンテキスト図

一般ユーザー 管理者 Postiz SNS プラットフォーム AI サービス ストレージサービス メール配信サービス 決済サービス
要素名 説明
一般ユーザー SNS 投稿の作成・スケジュール・分析を行う利用者
管理者 システム設定・ユーザー管理を行う運営者
Postiz SNS スケジューリングおよびコンテンツ管理システム
SNS プラットフォーム 投稿先となる外部 SNS(15 以上のプラットフォーム)
AI サービス コンテンツ生成・補助に使用する外部 AI
ストレージサービス メディアファイルの保存先
メール配信サービス 通知メール送信に使用する外部サービス
決済サービス サブスクリプション課金を処理する外部サービス

●コンテナ図

ブラウザ フロントエンド バックエンド API ワーカー Cron サービス Redis キュー SQL データベース ファイルストレージ
要素名 説明
ブラウザ ユーザーが操作するクライアント環境
フロントエンド Next.js 製の UI サービス(ポート 4200)
バックエンド API NestJS 製の REST API サービス(ポート 3000)
ワーカー Temporal ベースのバックグラウンド処理サービス
Cron サービス 定期処理のスケジュール管理サービス
Redis キュー ワーカーへのジョブ配信キュー
SQL データベース PostgreSQL による永続化ストア
ファイルストレージ メディアファイルの保存領域(ローカルまたはクラウド)

●コンポーネント図

フロントエンド - apps-frontend バックエンド API - apps-backend ワーカー - apps-orchestrator 共有ライブラリ - libraries nestjs-libraries Next.js App 投稿エディタ - TipTap カレンダービュー メディアマネージャ - Uppy プロバイダー追加 UI チャンネル一覧 UI Auth モジュール Posts モジュール Integrations モジュール Analytics モジュール Billing モジュール Upload モジュール Public API モジュール Temporal ワーカー Publish アクティビティ Token Refresh アクティビティ nestjs-libraries react-shared-libraries helpers Database モジュール Integration Manager Social Providers External サービス群
要素名 説明
Next.js App フロントエンドのルートアプリケーション
投稿エディタ - TipTap リッチテキスト形式の投稿作成コンポーネント
カレンダービュー スケジュール済み投稿を時系列で表示するコンポーネント
メディアマネージャ - Uppy ファイルアップロードを管理するコンポーネント
プロバイダー追加 UI SNS チャンネルの OAuth 接続を開始するコンポーネント
チャンネル一覧 UI 接続済みチャンネルの状態一覧を表示するコンポーネント
Auth モジュール JWT 認証・認可を処理する NestJS モジュール
Posts モジュール 投稿の CRUD・スケジュール管理を担当する NestJS モジュール
Integrations モジュール SNS 連携の OAuth フローと統合管理を担当する NestJS モジュール
Analytics モジュール 投稿パフォーマンスデータの収集・提供を担当する NestJS モジュール
Billing モジュール サブスクリプション課金処理を担当する NestJS モジュール
Upload モジュール メディアファイルのアップロード処理を担当する NestJS モジュール
Public API モジュール 外部連携向けの公開 REST API を提供する NestJS モジュール
Temporal ワーカー Temporal ワークフローエンジン上で動作するワーカープロセス
Publish アクティビティ 予定時刻に SNS へ投稿を実行する Temporal アクティビティ
Token Refresh アクティビティ OAuth トークンの有効期限前に更新を実行する Temporal アクティビティ
nestjs-libraries バックエンドとワーカーが共有するサーバーサイドロジックライブラリ
react-shared-libraries フロントエンドが使用する共有 React コンポーネントライブラリ
helpers 暗号化・バリデーション・設定管理の共通ユーティリティライブラリ
Database モジュール Prisma ORM を使用した型安全なデータアクセス層
Integration Manager 各 SNS プロバイダーの生成・管理を行うファクトリーコンポーネント
Social Providers SocialAbstract を実装した各 SNS プラットフォーム固有のクラス群
External サービス群 Stripe・OpenAI・メール送信などの外部サービスクライアント

●アーキテクチャの特徴

Postiz のアーキテクチャには、SNS スケジューリングツール特有の設計判断が見られます。

NX モノレポによる共有ライブラリ戦略:

フロントエンド(Next.js)とバックエンド(NestJS)で nestjs-librariesreact-shared-libraries を共有しています。特に SocialProviders は IntegrationManager を介してバックエンドとワーカーの両方から利用されます。この設計により、SNS プロバイダーの追加がライブラリへのクラス追加のみで完結します。

Temporal 移行の背景:

v2.12.0 で BullMQ から Temporal に移行した理由は、スケジュール投稿に必要な「長時間待機 + 確実な実行」の要件です。BullMQ の delayed job は Redis の揮発性に依存しますが、Temporal はワークフロー状態を永続化します。投稿の予約から数日後の実行まで、サーバー再起動をまたいで保証できます。

SocialAbstract による拡張パターン:

新しい SNS プラットフォームを追加する場合、SocialAbstract を継承し、@Rules@Plug@Tool デコレーターでプラットフォーム固有の制約を宣言します。各プロバイダーの実装は独立しており、既存プロバイダーとの分離を維持します。プラグインアーキテクチャとして、Open-Closed Principle に沿った設計です。

■データ

●概念モデル

Organization Post 管理 SNS 連携 メディア メディア メディア メディア メディア Webhook User 管理 Post Tags TagsPosts Comments AutoPost Integration Media Notifications Subscription Credits Plugs MessagesGroup Messages Webhooks User UserOrganization
要素名 説明
Organization ワークスペース単位のテナント。投稿・連携・課金・メディアを所有
User 認証ユーザー。複数の Organization に所属可能
UserOrganization User と Organization の中間テーブル。ロールを保持
Post SNS 投稿。状態管理とスケジューリング情報を保持
Tags 投稿分類用のタグ
TagsPosts Post と Tags の多対多中間テーブル
Comments 投稿へのコメント。ソフトデリート対応
AutoPost 自動投稿ルールの定義
Integration 接続済み SNS アカウント。OAuth トークンと設定を保持
Media アップロードされた画像・動画ファイル
Notifications システム通知。ソフトデリート対応
Subscription Stripe 連携の課金プラン
Credits AI 機能等の消費リソース
Plugs Integration に紐づくプラグイン機能
MessagesGroup ユーザー間メッセージのグループ
Messages メッセージ本体
Webhooks 外部システムへの通知設定

●情報モデル

Organization + id: String + name: String + description: String + apiKey: String + paymentId: String + allowTrial: Boolean + isTrialing: Boolean + shortlink: String User + id: String + email: String + password: String + name: String + lastName: String + providerName: String + providerId: String + activated: Boolean + timezone: String + bio: String UserOrganization + id: String + userId: String + organizationId: String + role: String + disabled: Boolean Integration + id: String + internalId: String + name: String + picture: String + providerIdentifier: String + type: String + token: String + tokenExpiration: DateTime + refreshToken: String + refreshNeeded: Boolean + disabled: Boolean + inBetweenSteps: Boolean + postingTimes: String + additionalSettings: String + customInstanceDetails: String + organizationId: String Post + id: String + content: String + title: String + publishDate: DateTime + actualDate: DateTime + state: String + group: String + parentPostId: String + intervalInDays: Int + delay: Int + error: String + approvedSubmitForOrder: String + organizationId: String + integrationId: String Media + id: String + name: String + path: String + type: String + fileSize: Int + originalName: String + thumbnail: String + alt: String + organizationId: String Comments + id: String + content: String + createdAt: DateTime + deletedAt: DateTime + postId: String + userId: String + organizationId: String Notifications + id: String + content: String + link: String + createdAt: DateTime + deletedAt: DateTime + organizationId: String Subscription + id: String + subscriptionTier: String + period: String + totalChannels: Int + isLifetime: Boolean + cancelAt: DateTime + organizationId: String Tags + id: String + name: String + organizationId: String TagsPosts + id: String + tagId: String + postId: String 1 0..* 1 0..* 1 0..* 1 0..* 1 0..* 1 1 1 0..* 1 0..* 1 0..* 0..* 1 1 0..* 1 0..* 1 0..*
要素名 説明
Organization.id テナント識別子
Organization.apiKey 外部 API 認証キー
Organization.paymentId Stripe の支払い顧客 ID
Organization.shortlink ショートリンク機能の設定値。ASK / YES / NO
User.providerName 認証プロバイダー種別。LOCAL / GITHUB / GOOGLE 等
User.activated メール認証完了フラグ
UserOrganization.role ユーザーの組織内ロール。SUPERADMIN / ADMIN / USER
Integration.internalId 連携先プラットフォーム固有のアカウント ID
Integration.providerIdentifier プラットフォーム識別子。x / linkedin / facebook 等
Integration.type 連携種別。social または article
Integration.token OAuth アクセストークン
Integration.refreshNeeded トークン期限切れによる再認証フラグ
Integration.postingTimes 推奨投稿時刻。JSON 形式で格納
Integration.additionalSettings プロバイダー固有の追加設定。JSON 形式
Integration.customInstanceDetails セルフホスト型プラットフォームのインスタンス URL
Post.state 投稿状態。DRAFT / QUEUE / PUBLISHED / ERROR
Post.group スレッド内の全投稿を束ねる UUID
Post.parentPostId スレッド返信先の親投稿 ID
Post.intervalInDays 定期投稿の繰り返し間隔(日数)
Post.approvedSubmitForOrder 承認フロー状態。NO / WAITING_CONFIRMATION / YES
Media.type ファイル種別。image / video 等
Media.thumbnail サムネイル画像の URL
Comments.deletedAt ソフトデリート用の削除日時
Notifications.deletedAt ソフトデリート用の削除日時
Subscription.subscriptionTier プランレベル。STANDARD / PRO / TEAM / ULTIMATE
Subscription.period 課金周期。MONTHLY / YEARLY
Subscription.isLifetime 買い切りプランフラグ

■構築方法

Docker Compose によるセルフホスト構築

Docker Compose を使用した構築を推奨します。

手順:

  1. 専用リポジトリをクローンします。
git clone https://github.com/gitroomhq/postiz-docker-compose
cd postiz-docker-compose
  1. 環境変数を設定します(後述の「環境変数の設定」を参照)。

  2. コンテナを起動します。

docker compose up -d
  1. アクセスを確認します。
エンドポイント URL
フロントエンド http://localhost:5000
Temporal 監視 UI http://localhost:8080

環境変数を変更した場合は、コンテナを再作成します。

docker compose down && docker compose up -d

依存サービスの構成

Docker Compose には以下のサービスが含まれます。

サービス イメージ 用途
postiz ghcr.io/gitroomhq/postiz-app:latest メインアプリケーション
postiz-postgres postgres:17-alpine データベース(PostgreSQL)
postiz-redis redis:7.2 キャッシュ・キュー

docker-compose.yml サンプル:

services:
  postiz:
    image: ghcr.io/gitroomhq/postiz-app:latest
    container_name: postiz
    restart: always
    environment:
      MAIN_URL: "https://postiz.your-server.com"
      FRONTEND_URL: "https://postiz.your-server.com"
      NEXT_PUBLIC_BACKEND_URL: "https://postiz.your-server.com/api"
      JWT_SECRET: "ランダムな文字列(インストールごとに変更)"
      DATABASE_URL: "postgresql://postiz-user:postiz-password@postiz-postgres:5432/postiz-db-local"
      REDIS_URL: "redis://postiz-redis:6379"
      BACKEND_INTERNAL_URL: "http://localhost:3000"
      IS_GENERAL: "true"
      DISABLE_REGISTRATION: "false"
      STORAGE_PROVIDER: "local"
      UPLOAD_DIRECTORY: "/uploads"
      NEXT_PUBLIC_UPLOAD_DIRECTORY: "/uploads"
    volumes:
      - postiz-config:/config/
      - postiz-uploads:/uploads/
    ports:
      - 5000:5000
    networks:
      - postiz-network
    depends_on:
      postiz-postgres:
        condition: service_healthy
      postiz-redis:
        condition: service_healthy

  postiz-postgres:
    image: postgres:17-alpine
    container_name: postiz-postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: postiz-password
      POSTGRES_USER: postiz-user
      POSTGRES_DB: postiz-db-local
    volumes:
      - postgres-volume:/var/lib/postgresql/data
    networks:
      - postiz-network
    healthcheck:
      test: pg_isready -U postiz-user -d postiz-db-local
      interval: 10s
      timeout: 3s
      retries: 3

  postiz-redis:
    image: redis:7.2
    container_name: postiz-redis
    restart: always
    healthcheck:
      test: redis-cli ping
      interval: 10s
      timeout: 3s
      retries: 3
    volumes:
      - postiz-redis-data:/data
    networks:
      - postiz-network

volumes:
  postgres-volume:
  postiz-redis-data:
  postiz-config:
  postiz-uploads:

networks:
  postiz-network:

環境変数の設定 - .env ファイル

環境変数の設定方法は 3 通りあります。

方法 説明
docker-compose.yml 内 environment セクション 推奨方法
/config にマウントした postiz.env ファイル ファイル分離が必要な場合
.env ファイル .env の値が docker-compose.yml を上書き

必須環境変数:

変数 説明
MAIN_URL アプリケーションの公開 URL https://postiz.example.com
FRONTEND_URL フロントエンド URL https://postiz.example.com
NEXT_PUBLIC_BACKEND_URL バックエンド公開 URL https://postiz.example.com/api
JWT_SECRET セッション管理用ランダム文字列 (インストールごとにユニーク値)
DATABASE_URL PostgreSQL 接続文字列 postgresql://user:pass@host:5432/db
REDIS_URL Redis 接続 URL redis://postiz-redis:6379
BACKEND_INTERNAL_URL バックエンド内部 URL http://localhost:3000
IS_GENERAL 汎用モード(現在必須) true

任意環境変数:

変数 説明 デフォルト
DISABLE_REGISTRATION true で新規登録を無効化 false
STORAGE_PROVIDER ストレージプロバイダー(local / cloudflare local
UPLOAD_DIRECTORY ローカルアップロードディレクトリパス /uploads
DISABLE_IMAGE_COMPRESSION true で画像圧縮を無効化 未設定

メール設定(任意):

EMAIL_PROVIDER="resend|nodemailer"
RESEND_API_KEY="re_xxxxxxxxxxxx"       # Resend 利用時
EMAIL_HOST="smtp.gmail.com"            # Nodemailer 利用時
EMAIL_PORT="465"
EMAIL_SECURE="true"
EMAIL_USER="user@example.com"
EMAIL_PASS="password"

Cloudflare R2 ストレージ設定(任意):

CLOUDFLARE_ACCOUNT_ID="your-account-id"
CLOUDFLARE_ACCESS_KEY="your-access-key"
CLOUDFLARE_SECRET_ACCESS_KEY="your-secret-key"
CLOUDFLARE_BUCKETNAME="postiz"
CLOUDFLARE_BUCKET_URL="https://account-id.r2.cloudflarestorage.com/"
CLOUDFLARE_REGION="auto"

開発環境のセットアップ - NX モノレポ

前提条件:

  • Node.js 18 以上
  • pnpm
  • PostgreSQL
  • Redis

手順:

  1. リポジトリをクローンします。
git clone https://github.com/gitroomhq/postiz-app.git
cd postiz-app
  1. PostgreSQL と Redis をローカルで起動します。
docker run -e POSTGRES_USER=root -e POSTGRES_PASSWORD=your_password \
  --name postgres -p 5432:5432 -d postgres

docker run --name redis -p 6379:6379 -d redis
  1. .env ファイルを作成し、環境変数を設定します。
DATABASE_URL="postgresql://postiz-user:postiz-password@localhost:5432/postiz-db-local"
REDIS_URL="redis://localhost:6379"
JWT_SECRET="ランダムな長い文字列"
FRONTEND_URL="http://localhost:4200"
NEXT_PUBLIC_BACKEND_URL="http://localhost:3000"
BACKEND_INTERNAL_URL="http://localhost:3000"
IS_GENERAL="true"
NX_ADD_PLUGINS=false
  1. 依存関係をインストールします。
pnpm install
  1. データベーススキーマを初期化します。
pnpm run prisma-db-push
  1. 開発サーバーを起動します。
pnpm run dev

ブラウザで http://localhost:4200 にアクセスして動作を確認します。

macOS と Linux(Fedora 40)での動作確認済みです。Windows / WSL 環境はサポートが限定的です。

ビルドとデプロイ

本番ビルド:

pnpm install
pnpm run prisma-db-push
pnpm run pm2    # PM2 によるプロセス管理

Docker イメージのビルド(ソースから):

docker build -t postiz-app .

リバースプロキシの設定(本番環境):

OAuth 認証には HTTPS が必要なため、リバースプロキシを設定します。

プロキシ ドキュメント
Nginx docs.postiz.com/reverse-proxies/nginx
Caddy docs.postiz.com/reverse-proxies/caddy
Traefik docs.postiz.com/reverse-proxies/traefik

パブリック DNS 名の必要性

セルフホスト環境でも、パブリックにアクセス可能な HTTPS URL が必要です。

理由:

OAuth のコールバックフローは以下のように動作します。

  1. Postiz UI で「X を接続」をクリック
  2. ブラウザが X の OAuth 認可ページにリダイレクト
  3. ユーザーが認可
  4. X がブラウザを Postiz のコールバック URL にリダイレクト

ステップ 4 で、SNS プロバイダに登録したコールバック URL はブラウザから到達可能かつプロバイダが受け入れる形式である必要があります。多くの SNS プロバイダはパブリック URL のみをコールバック URL として受け入れます(X は開発時に localhost を許可)。

必要なもの:

  • パブリック DNS 名 + HTTPS(例: postiz.example.com
  • リバースプロキシ(Nginx / Caddy)で SSL 終端

プライベートネットワークでの回避策:

方法 概要
Cloudflare Tunnel 無料。パブリック IP 不要で外部からアクセス可能
ngrok トンネル経由で一時的なパブリック URL を発行
DuckDNS + ポート開放 無料 DDNS。自宅ルーターのポート開放が必要

この要件は OAuth の初回接続時とトークンリフレッシュ時の両方で必要になり得ます。

■利用方法

SNS アカウントの連携 - OAuth 設定

対応プラットフォームと認証方式:

プラットフォーム 認証方式 トークン有効期間 リフレッシュ
X(旧 Twitter) OAuth 1.0a 長期有効 不要
LinkedIn OAuth 2.0 標準 あり
Instagram OAuth 2.0 標準 あり(サーバーサイド管理)
Facebook Pages OAuth 2.0 60 日間 あり(長期トークン)
TikTok OAuth 2.0 24 時間 あり(高頻度)
YouTube OAuth 2.0 標準 あり
Threads OAuth 2.0 標準 あり
Pinterest OAuth 2.0 標準 あり
Reddit OAuth 2.0 標準 あり
Discord OAuth 2.0 標準 あり
Bluesky 独自認証 セッション単位 オンデマンド生成
Mastodon OAuth 2.0 標準 あり

Bluesky は OAuth を使用せず、serviceidentifierpassword を暗号化して保存する独自方式です。

SocialAbstract 設計パターン:

全プロバイダーは SocialAbstract 抽象クラスを継承します。プラットフォーム固有の制約はデコレーターで宣言します。

デコレーター 用途
@Rules コンテンツバリデーション Instagram: 添付必須
@Plug 定期実行の投稿後処理 自動リポスト
@Tool UI から呼び出し可能なツール Pinterest ボード選択

プラットフォーム別の同時実行制限: X=1(300 投稿/3 時間)、LinkedIn=2、Instagram=200、Facebook=100

連携手順(X/Twitter の例):

  1. Twitter Developer Portal でアプリを作成します。

  2. アプリ設定で以下を構成します。

    • アプリ権限: 「読み取りと書き込み」
    • アプリタイプ: 「Web App, Automated App or Bot」
    • コールバック URI: https://your-postiz-domain.com/integrations/social/x
  3. API キーと秘密鍵を取得し、.env に設定します。

X_API_KEY="Twitter API key(OAuth1 用)"
X_API_SECRET="Twitter API secret(OAuth1 用)"
  1. Postiz の「Integrations」画面から X アカウントを追加します。

LinkedIn の例:

LINKEDIN_CLIENT_ID="LinkedIn Client ID"
LINKEDIN_CLIENT_SECRET="LinkedIn Client Secret"

AI プロバイダーの設定:

OPENAI_API_KEY="OpenAI API キー"

投稿のスケジューリング

投稿作成フロー:

  1. 「Launches」画面で新規投稿を作成します。
  2. 投稿内容(テキスト・画像)を入力します。
  3. 投稿先のソーシャルアカウントを選択します。
  4. 投稿タイプを選択します。
タイプ 説明
now 即時投稿
schedule 指定日時にスケジュール投稿
draft 下書き保存
  1. スケジュール日時を設定して「Publish」を実行します。

内部処理フロー:

ユーザーの操作から SNS への投稿までの流れは以下のとおりです。

LaunchesComponent PostsController PostsService PostgreSQL Temporal Workflow publishActivity IntegrationManager SNS プラットフォーム
要素名 説明
LaunchesComponent フロントエンドから投稿データを送信
PostsController JWT 検証後にリクエストを受付
PostsService 投稿データを PostgreSQL に保存
Temporal Workflow スケジュール時刻までワークフローを待機
publishActivity 指定時刻に投稿処理を実行
IntegrationManager 各プラットフォーム固有のプロバイダーへ投稿を委譲

Temporal が自動リトライとスケジュール実行を管理します。失敗時は最大 3 回リトライし、全て失敗した場合は Post の state を ERROR に更新します。

AI コンテンツ生成の使い方

設定:

OpenAI API キーを .env に設定します。FAL AI を使用する場合は FAL_KEY も設定します。

OPENAI_API_KEY="sk-xxxxxxxxxxxx"
FAL_KEY="your-fal-api-key"        # FAL AI 画像・動画生成(任意)

AI 機能の内部アーキテクチャ:

Postiz の AI 機能は 3 層で構成されています。

コンポーネント 役割
フロントエンド CopilotKit 投稿エディタ内の AI テキストエリア・サジェスト
バックエンド OpenaiService GPT-4.1 によるテキスト生成、DALL-E 3 による画像生成
エージェント Mastra + LangChain マルチステップの自動コンテンツ生成ワークフロー

OpenaiService の主要メソッド:

メソッド 機能 モデル
generatePosts 投稿・スレッドの一括生成(5 件ずつ) GPT-4.1
separatePosts 長文を文字数制限付きに分割(最大 4 回リトライ) GPT-4.1
generateImage 画像生成(縦 1024x1792 / 横 標準) DALL-E 3
generateSlidesFromText テキストから 3〜5 枚のスライド生成 GPT-4.1
generateVoiceFromText 投稿を自然な音声テキストに変換 GPT-4.1
extractContentFromWebsite Web サイトからコンテンツ抽出・要約 GPT-4.1

構造化出力には Zod スキーマと zodResponseFormat を使用しています。

CopilotKit の統合:

投稿エディタはユーザーの AI ティアに応じて表示を切り替えます。

if (user?.tier?.ai) {
  return <CopilotTextarea
    autosuggestionsConfig={{
      textareaPurpose: "Assist me in writing social media posts"
    }}
  />;
} else {
  return <MDEditor />;
}

useCopilotReadable フックで投稿コンテンツを AI が読み取り可能にします。editPost_{order} アクションで AI が直接編集できます。

Mastra エージェントの役割:

Mastra は CopilotKit のフロントエンド UI と連携するアジェンティックバックエンドです。OpenAI・Anthropic・Gemini など複数の LLM プロバイダーへの統一インターフェースを提供します。LangGraph による複雑な状態管理を持つエージェントグラフを構築できます。

使い方:

  1. 投稿作成画面で「AI Generate」ボタンをクリックします。
  2. トピックやキーワードを入力します。
  3. 生成されたコンテンツを編集して投稿します。

チーム・組織管理

ロールと権限:

ロール 権限
SUPERADMIN 全機能へのアクセス
ADMIN 組織内の管理権限
USER 投稿作成・スケジュール

プラン別機能制限:

プラン チャネル上限 主な機能
FREE 制限あり 基本スケジューリング
STANDARD 拡張 AI 生成・分析
PRO 無制限 全機能

組織管理手順:

  1. 「Settings」→「Organization」でワークスペースを作成します。
  2. 「Invite Members」でメールアドレスを入力してメンバーを招待します。
  3. 各メンバーにロールを割り当てます。

DISABLE_REGISTRATION=true を設定すると、招待制のみに制限できます。

API の利用方法

認証:

Settings 画面から API キーを取得し、リクエストヘッダーに設定します。

Authorization: your-api-key

ベース URL:

環境 URL
クラウド版 https://api.postiz.com/public/v1
セルフホスト https://your-postiz-domain.com/api/public/v1NEXT_PUBLIC_BACKEND_URL で設定した URL に準拠)

レート制限: 1 時間あたり 30 リクエスト

主要エンドポイント:

エンドポイント メソッド 説明
/posts POST 投稿の作成・スケジュール
/posts GET 投稿一覧(フィルタ・ページネーション対応)
/posts/{postId} GET 特定投稿の取得
/posts/{id} DELETE 投稿の削除
/upload POST ファイルアップロード
/upload-from-url POST URL からのメディアアップロード
/integrations GET 連携アカウント一覧
/analytics/platform/{platform} GET プラットフォーム別分析データ
/team/members GET チームメンバー一覧

Webhook:

Webhook の CRUD エンドポイントが利用可能です。

エンドポイント メソッド 説明
/webhooks/ GET Webhook 一覧取得
/webhooks/ POST Webhook 作成
/webhooks/ PUT Webhook 設定更新
/webhooks/:id DELETE Webhook 削除
/webhooks/send POST Webhook 送信テスト

計画中のイベント: post.createdpost.publishedpost.failed 等のライフサイクルイベント

Webhook 活用例(N8N での自動通知):

{
  "url": "https://your-n8n.example.com/webhook/postiz",
  "event": "post.published",
  "secret": "webhook-signing-secret"
}

投稿が公開されるたびに N8N のワークフローがトリガーされ、Slack 通知やスプレッドシート記録を自動化できます。

MCP(Model Context Protocol)統合:

Cursor や Claude Desktop から直接ソーシャルメディア投稿を管理できます。

{
  "mcpServers": {
    "postiz": {
      "command": "npx",
      "args": ["@postiz/mcp"],
      "env": {
        "POSTIZ_API_KEY": "your-api-key"
      }
    }
  }
}

投稿作成リクエスト例:

{
  "type": "schedule",
  "date": "2026-02-20T10:00:00.000Z",
  "posts": [
    {
      "integration": {
        "id": "your-channel-id"
      },
      "value": [
        {
          "content": "投稿本文テキスト"
        }
      ]
    }
  ]
}

CLI の利用:

# CLI のインストール
npm install -g postiz

# API キーの設定
export POSTIZ_API_KEY=your-api-key

# セルフホスト環境の場合
export POSTIZ_API_URL=https://your-postiz-server.com

主要 CLI コマンド:

コマンド 説明
postiz integrations:list 連携アカウント一覧
postiz posts:create -c "テキスト" -s "日時" -i "ID" 投稿作成
postiz posts:list 投稿一覧
postiz posts:delete 投稿削除
postiz analytics:platform プラットフォーム分析
postiz upload メディアアップロード

Node.js SDK の利用:

npm install @postiz/node
import Postiz from '@postiz/node';

const postiz = new Postiz('your-api-key', 'https://your-instance.example.com');

// 投稿作成
await postiz.post({ content: "投稿テキスト", platforms: ["twitter"] });

// 投稿一覧
const posts = await postiz.postList({ limit: 10 });

// メディアアップロード
await postiz.upload(fileBuffer, "png");

// 連携アカウント一覧
const integrations = await postiz.integrations();

外部自動化サービスとの連携:

サービス 統合方法
N8N カスタムノード(@gitroomhq/postiz-n8n
Make.com 専用モジュール(Trigger + Action)
Zapier 公式連携

マーケットプレイス

マーケットプレイスは、ユーザー間で投稿やサービスを交換・売買する機能です。

主な機能:

機能 説明
投稿の出品 作成済み投稿をマーケットプレイスに出品
投稿の購入 他ユーザーの投稿を購入して自チャンネルに投稿
サービスの売買 SNS 運用代行やコンテンツ作成のサービスを提供

マーケットプレイスは Organization 単位で利用します。出品した投稿は購入者の Organization にコピーされ、元の投稿は出品者のもとに残ります。

分析ダッシュボード

投稿パフォーマンスをプラットフォーム別に計測・分析できます。

取得可能な指標:

指標 説明
インプレッション 投稿の表示回数
エンゲージメント いいね・リツイート・コメントの合計
クリック数 リンクのクリック回数
フォロワー増減 期間中のフォロワー変動

API での分析データ取得:

# プラットフォーム別の分析データ
curl -H "Authorization: your-api-key" \
  https://your-instance.com/public/v1/analytics/platform/x

各 SNS プラットフォームの API から定期的にデータを取得し、PostgreSQL に保存します。ダッシュボードはフロントエンドの Analytics モジュールで時系列グラフとして表示します。

■運用

バージョンアップ手順

  • v2.12.0 以降は新インフラ(Temporal)を採用しているため、docker-compose.yml の更新が必須
  • アップグレード前に必ずデータベースバックアップを取得
  • リリースノートを確認し、設定変更の要否を確認

手順:

# 1. 現在のバージョンを確認
docker inspect ghcr.io/gitroomhq/postiz-app:latest | grep -i version

# 2. バックアップを取得(後述の手順を参照)

# 3. 最新イメージを取得
docker compose pull

# 4. コンテナを再作成
docker compose down
docker compose up -d

# 5. ログで起動状態を確認
docker compose logs -f postiz

バージョン固定(安定運用が優先の場合):

# docker-compose.yml
services:
  postiz:
    image: ghcr.io/gitroomhq/postiz-app:v2.12.0

v2.12.0 の主な変更点:

項目 変更前 変更後
ジョブキュー BullMQ Temporal
ベースイメージ Alpine Linux bookworm-slim
デフォルトポート 5000 4007(docker-compose 公式サンプルは引き続き 5000 を使用)
スケジュール移行 - 自動(Cron で移行)

バックアップとリストア

バックアップ対象ボリューム:

ボリューム名 用途
postgres-volume PostgreSQL データ
postiz-uploads アップロードファイル
postiz-config 設定ファイル
postiz-redis-data Redis キャッシュ(任意)

PostgreSQL バックアップ:

# SQL ダンプ
docker exec postiz-postgres pg_dump \
  -U postiz-user postiz-db-local \
  > backup_$(date +%Y%m%d_%H%M%S).sql

# 圧縮ダンプ
docker exec postiz-postgres pg_dump \
  -U postiz-user postiz-db-local \
  | gzip -9 > backup_$(date +%Y%m%d_%H%M%S).sql.gz

アップロードファイルバックアップ:

# Docker ボリュームをアーカイブ
docker run --rm \
  -v postiz-uploads:/data \
  -v $(pwd):/backup \
  alpine tar czf /backup/uploads_$(date +%Y%m%d).tar.gz /data

PostgreSQL リストア:

# コンテナを停止してからリストア
docker compose stop postiz

# SQL ダンプからリストア
docker exec -i postiz-postgres psql \
  -U postiz-user postiz-db-local \
  < backup_20260219.sql

docker compose start postiz

自動バックアップ(cron 例):

# /etc/cron.d/postiz-backup
0 3 * * * root docker exec postiz-postgres pg_dump \
  -U postiz-user postiz-db-local \
  | gzip > /var/backups/postiz/db_$(date +\%Y\%m\%d).sql.gz

監視・ログ管理

コンテナログの確認:

# 全サービスのログ
docker compose logs -f

# 特定サービス(タイムスタンプ付き)
docker compose logs -f -t postiz

# 直近 100 行
docker compose logs --tail=100 postiz

ヘルスチェック状態の確認:

docker compose ps
# STATUS 列で healthy / unhealthy を確認

Temporal UI でジョブ監視:

  • http://localhost:8080 にアクセスしてスケジュール済み投稿の状態を確認できます。
  • ワークフローの失敗・リトライ状況を可視化できます。

Sentry エラートラッキング(オプション):

# .env に追加
SENTRY_DSN=https://xxx@sentry.io/xxx

セキュリティ設定

JWT シークレットの生成:

# 安全なランダム文字列を生成
openssl rand -hex 32

登録制限(セルフホスト時の必須設定):

# 最初のユーザー登録後にサインアップを無効化
DISABLE_REGISTRATION=true

DISABLE_REGISTRATION=true を設定すると OIDC / OAuth も無効になります。

Nginx リバースプロキシ(HTTPS 必須):

server {
    listen 443 ssl http2;
    server_name postiz.example.com;

    ssl_certificate     /etc/letsencrypt/live/postiz.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/postiz.example.com/privkey.pem;
    ssl_protocols       TLSv1.2 TLSv1.3;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
    add_header X-Frame-Options DENY;
    add_header X-Content-Type-Options nosniff;
    add_header Referrer-Policy no-referrer-when-downgrade;

    server_tokens off;

    location / {
        proxy_pass http://localhost:5000;
        proxy_set_header Host              $host;
        proxy_set_header X-Real-IP         $remote_addr;
        proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header Upgrade    $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Postiz はセキュアクッキーを使用するため、HTTPS 環境が必須です。外部に公開するポートは 5000(または 4007)のみに限定してください。

スケーリング

POSTIZ_APPS によるサービス分離:

# フロントエンドのみ
POSTIZ_APPS="frontend"

# バックエンドのみ
POSTIZ_APPS="backend"

# ワーカーとクーロンのみ
POSTIZ_APPS="worker cron"

推奨スペック:

用途 最小 RAM 推奨 RAM
単体起動 2 GB 4 GB
継続運用(他サービス併用) 4 GB 8 GB
Temporal 含む本番 4 GB 8 GB+

Temporal はメモリ消費が大きいため、RAM が不足する場合はスワップを設定してください。ワーカーを水平スケールする場合は Redis を共有インスタンスとして外部化してください。

■ベストプラクティス

本番環境の推奨構成

  • SSL 終端には Nginx リバースプロキシを使用
  • Postiz コンテナはポート 5000 または 4007 でリッスン
  • PostgreSQL、Redis、Temporal をバックエンドサービスとして配置

推奨 docker-compose.yml 設定:

services:
  postiz:
    image: ghcr.io/gitroomhq/postiz-app:latest
    container_name: postiz
    restart: always
    env_file:
      - /etc/postiz/postiz.env   # 機密情報は外部ファイルで管理
    volumes:
      - postiz-config:/config/
      - postiz-uploads:/uploads/
    ports:
      - "127.0.0.1:5000:5000"   # ローカルのみ公開(Nginx 経由で外部に出す)
    networks:
      - postiz-network
    depends_on:
      postiz-postgres:
        condition: service_healthy
      postiz-redis:
        condition: service_healthy

シークレット(JWT_SECRET、API キー)は環境変数ファイル(/config/postiz.env)で管理し、docker-compose.yml に直接記述しないでください。ポートを 127.0.0.1:5000:5000 とすることで、Nginx 経由以外のアクセスを防げます。

パフォーマンス最適化

Nginx gzip 圧縮:

gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript;

PostgreSQL 接続プール:

# DATABASE_URL にプール設定を追加
DATABASE_URL="postgresql://user:pass@host:5432/db?connection_limit=20&pool_timeout=10"

Redis 永続化を有効化(データ保護):

services:
  postiz-redis:
    image: redis:7.2
    command: redis-server --appendonly yes
    volumes:
      - postiz-redis-data:/data

アップロードを S3 互換ストレージ(Cloudflare R2 等)に外部化:

STORAGE_PROVIDER=cloudflare
CLOUDFLARE_ACCOUNT_ID=xxx
CLOUDFLARE_ACCESS_KEY=xxx
CLOUDFLARE_SECRET_ACCESS_KEY=xxx
CLOUDFLARE_BUCKETNAME=postiz-uploads
CLOUDFLARE_BUCKET_URL=https://pub-xxx.r2.dev

ローカルストレージよりも S3 互換ストレージを使うと、スケールアウト時のファイル共有問題を回避できます。

セキュリティ強化

設定項目 推奨値 説明
JWT_SECRET openssl rand -hex 32 で生成 インストールごとに一意の値を設定
DISABLE_REGISTRATION true 初回登録後に無効化
Nginx server_tokens off バージョン情報を秘匿
SSL プロトコル TLSv1.2, TLSv1.3 古いプロトコルを無効化
DB パスワード ランダム生成 デフォルト値から必ず変更
ポート公開 127.0.0.1:5000:5000 Nginx 経由のみ外部公開

SNS プラットフォーム連携のコツ

X(Twitter):

  • OAuth1 を使用(画像アップロードに v1 API が必要なため)
  • Developer Portal で App Permission を「Read and Write」、App Type を「Web App, Automated App or Bot」に設定
  • Callback URI は正確に設定
# 本番環境
https://postiz.example.com/integrations/social/x

# ローカル(Docker / X は開発時に localhost を許可)
http://localhost:5000/integrations/social/x

Instagram:

  • Instagram Standalone は Meta ビジネス認証が必要
  • NEXT_PUBLIC_BACKEND_URL の URL と Meta Developer コンソールの callback URL を一致させる

環境変数変更後の反映:

# 環境変数を変更した場合は必ず再起動
docker compose down
docker compose up -d

■トラブルシューティング

Prisma / Node.js バージョン不整合

症状:

Prisma only supports Node.js versions 20.19+, 22.12+, 24.0+.
Please upgrade your Node.js version.

原因: :latest タグが古いイメージを指している場合があります(Issue #1079)。

対処法:

# docker-compose.yml でバージョンを固定
image: ghcr.io/gitroomhq/postiz-app:v2.12.0

バックエンドが起動ループ - Transloadit authKey

症状:

Error: Please provide an authKey at new TransloaditClient

原因: アップデートで TRANSLOADIT_AUTH_KEY が必須になりました(Issue #858)。

対処法:

# 使用しない場合は空文字で設定
TRANSLOADIT_AUTH_KEY=""
TRANSLOADIT_AUTH_SECRET=""

または前のバージョンにロールバックしてください。

URL 設定ミスによる API 接続エラー

症状: ログインや登録が失敗する。API レスポンスエラーが発生。

原因: MAIN_URLFRONTEND_URLNEXT_PUBLIC_BACKEND_URL の不一致。

対処法: アクセスする URL と完全に一致させてください。

MAIN_URL="https://postiz.example.com"
FRONTEND_URL="https://postiz.example.com"
NEXT_PUBLIC_BACKEND_URL="https://postiz.example.com/api"

X(Twitter)認証エラー

症状:

credential access key has length 40, should be 32

原因: API Key(40 文字)を Access Token と誤って設定しています。

対処法: Developer Portal の「Keys and Tokens」タブで「Consumer Keys」の API KeyAPI Key Secret を使用してください(Access Token とは別です)。

X_API_KEY="your_api_key_here"         # Consumer API Key(短い方)
X_API_SECRET="your_api_secret_here"   # Consumer API Secret

Instagram「Invalid API key」エラー

症状: OAuth フローは完了するが 409 Conflict エラーが発生します(Issue #1122)。

対処法:

  1. Meta Developer コンソールの Redirect URI が NEXT_PUBLIC_BACKEND_URL と一致しているか確認してください。
  2. Instagram Standalone と Facebook Page の権限設定を確認してください。
  3. アプリが「ライブ」モードになっているか確認してください。

Facebook Page チャンネル追加エラー

症状: 「Could not add provider」エラーが発生します(Issue #918, #850)。

対処法:

  1. Facebook App が「ライブ」状態であることを確認してください。
  2. FACEBOOK_APP_IDFACEBOOK_APP_SECRET の値を確認してください。
  3. Callback URL が Meta コンソールに登録されているか確認してください。

コンテナが healthy にならない

診断:

# ヘルスチェック詳細を確認
docker inspect postiz-postgres | grep -A 20 "Health"

# ログで原因を確認
docker compose logs postiz-postgres

PostgreSQL が起動しない場合:

# ボリュームをリセット(データが消えるため注意)
docker compose down -v
docker compose up -d

環境変数が反映されない

原因: docker compose restart は環境変数の変更を無視してコンテナを再起動します。

対処法:

# 必ず down してから up する
docker compose down
docker compose up -d

ポート競合

症状: bind: address already in use

対処法:

# 使用中のポートを確認
lsof -i :5000

# docker-compose.yml でポートを変更
# ports:
#   - "5001:5000"

マイグレーション失敗

症状: 起動時に Prisma マイグレーションエラーが発生します。

診断:

# マイグレーション状態を確認
docker exec postiz npx prisma migrate status

# ログを確認
docker compose logs postiz | grep -i "migration\|prisma\|error"

手動マイグレーション実行:

docker exec postiz npx prisma migrate deploy

v2.12.0 移行後にスケジュール投稿が消えた

原因: BullMQ から Temporal への移行 Cron が未実行。

対処法:

  • 自動移行 Cron が実行されるまで待機してください(通常数分以内)
  • Temporal UI(http://localhost:8080)でワークフロー状態を確認してください
  • 問題が継続する場合は v2.11.3 にロールバックしてください

■まとめ

Postizは、オープンソースでセルフホスト可能なSNS運用管理プラットフォームとして、柔軟な機能とAI統合を備えています。
Docker Compose等で容易に構築でき、マルチプラットフォームでの効率的なコンテンツ展開と分析基盤を提供します。

この記事が少しでも参考になった、あるいは改善点などがあれば、ぜひリアクションやコメント、SNSでのシェアをいただけると励みになります!

■参考リンク