AI

OSSのGitホスティング比較:GitLab vs Gitea vs Forgejo でGitHub代替をセルフホストする

オープンソースラボ編集部2026年6月13日

OSSのGitホスティング比較:GitLab vs Gitea vs Forgejo でGitHub代替をセルフホストする

GitHub(月$4/ユーザー〜)・Bitbucket(月$3/ユーザー〜)に対して、GitLab(最も機能が豊富なOSSDevOpsプラットフォーム)・Gitea(軽量・最速起動のセルフホストGit)・Forgejo(Gitea公式フォーク・コミュニティ主導)はOSSのGitリポジトリホスティングサービスです。

セルフホストGitを選ぶ理由

  • コスト: GitHubは100人で月$400〜。Gitea/Forgejoセルフホストなら$0(サーバー代のみ)
  • データ主権: ソースコードを自社サーバーに保管・外部流出リスクなし
  • CI/CD統合: GitLabは組み込みのCI/CDパイプラインを持つため外部サービス不要
  • カスタマイズ: セルフホストでブランドドメイン・LDAP認証・カスタムフック設定が自由

主要ツールの概要

GitLab CE

2011年に公開されたRuby/Go製のOSS DevOpsプラットフォームです。GitHubスター23k+。GitリポジトリからCI/CD・コンテナレジストリ・セキュリティスキャン・プロジェクト管理まで1つに統合したオールインワンプラットフォームです。Enterprise Edition(有料)も存在しますが、Community Editionは無料でほぼ全ての機能が使えます。

# GitLab CE を Docker Compose でセルフホスト
mkdir gitlab && cd gitlab

cat > docker-compose.yml << 'EOF'
version: '3.8'

services:
  gitlab:
    image: gitlab/gitlab-ce:latest
    restart: unless-stopped
    hostname: gitlab.yourcompany.com
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://gitlab.yourcompany.com'
        gitlab_rails['gitlab_email_from'] = 'noreply@yourcompany.com'
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['smtp_address'] = 'smtp.yourcompany.com'
        gitlab_rails['smtp_port'] = 587
        nginx['redirect_http_to_https'] = true
        letsencrypt['enable'] = true
        letsencrypt['contact_emails'] = ['admin@yourcompany.com']
        # パフォーマンスチューニング(4GB RAM環境)
        puma['worker_processes'] = 2
        sidekiq['concurrency'] = 10
        postgresql['shared_buffers'] = '256MB'
    ports:
      - "80:80"
      - "443:443"
      - "22:22"
    volumes:
      - gitlab_config:/etc/gitlab
      - gitlab_logs:/var/log/gitlab
      - gitlab_data:/var/opt/gitlab
    shm_size: '256m'

volumes:
  gitlab_config:
  gitlab_logs:
  gitlab_data:
EOF

docker compose up -d
# 初期化に5〜10分かかる
# 初期rootパスワード確認:
docker exec -it gitlab_gitlab_1 grep 'Password:' /etc/gitlab/initial_root_password
# .gitlab-ci.yml - GitLabのCI/CDパイプライン(Next.jsアプリのビルド・テスト・デプロイ)
stages:
  - install
  - test
  - build
  - deploy

variables:
  NODE_VERSION: "20"
  VERCEL_ORG_ID: $VERCEL_ORG_ID
  VERCEL_PROJECT_ID: $VERCEL_PROJECT_ID

cache:
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/

install:
  stage: install
  image: node:${NODE_VERSION}-alpine
  script:
    - npm ci

type-check:
  stage: test
  image: node:${NODE_VERSION}-alpine
  script:
    - npm run type-check
  needs: [install]

lint:
  stage: test
  image: node:${NODE_VERSION}-alpine
  script:
    - npm run lint
  needs: [install]

build:
  stage: build
  image: node:${NODE_VERSION}-alpine
  script:
    - npm run build
  artifacts:
    paths:
      - .next/
    expire_in: 1 hour
  needs: [install]

deploy-production:
  stage: deploy
  image: node:${NODE_VERSION}-alpine
  script:
    - npm install -g vercel
    - vercel pull --yes --environment=production --token=$VERCEL_TOKEN
    - vercel build --prod --token=$VERCEL_TOKEN
    - vercel deploy --prebuilt --prod --token=$VERCEL_TOKEN
  needs: [build]
  only:
    - main
  environment:
    name: production
    url: https://opensourcelab.vercel.app
# GitLab APIを使ってリポジトリ情報を取得・管理
import httpx

GITLAB_URL = "https://gitlab.yourcompany.com"
PRIVATE_TOKEN = "glpat-xxxxxxxxxxxxxxxx"

headers = {"PRIVATE-TOKEN": PRIVATE_TOKEN}

# プロジェクト一覧を取得
def list_projects(page: int = 1):
    response = httpx.get(
        f"{GITLAB_URL}/api/v4/projects",
        headers=headers,
        params={
            "page": page,
            "per_page": 50,
            "order_by": "last_activity_at",
            "sort": "desc",
            "membership": True,
        }
    )
    return response.json(), int(response.headers.get("X-Total-Pages", 1))

# マージリクエストの一覧を取得
def list_merge_requests(project_id: int, state: str = "opened"):
    response = httpx.get(
        f"{GITLAB_URL}/api/v4/projects/{project_id}/merge_requests",
        headers=headers,
        params={"state": state, "per_page": 100},
    )
    return response.json()

# パイプラインのステータスを確認
def get_pipeline_status(project_id: int, ref: str = "main"):
    response = httpx.get(
        f"{GITLAB_URL}/api/v4/projects/{project_id}/pipelines",
        headers=headers,
        params={"ref": ref, "per_page": 1, "status": "running"},
    )
    pipelines = response.json()
    if not pipelines:
        return "idle"
    return pipelines[0]["status"]

# Webhookの設定(GitLabイベントをSlackに転送)
def create_webhook(project_id: int, webhook_url: str):
    response = httpx.post(
        f"{GITLAB_URL}/api/v4/projects/{project_id}/hooks",
        headers=headers,
        json={
            "url": webhook_url,
            "push_events": True,
            "merge_requests_events": True,
            "pipeline_events": True,
            "note_events": True,
            "token": "secret-webhook-token",
        },
    )
    return response.json()

Gitea / Forgejo

Giteaは2016年に公開されたGo製の軽量OSSGitサービスです。GitHubスター45k+。シングルバイナリで動作・256MB RAMでも起動できる最軽量のGitホスティングです。ForgejoはGiteaから2022年にフォークしたコミュニティ主導のプロジェクトで、Codeberg.orgが使用する実績があります。GiteaよりForgejoの方がコミュニティの透明性が高く、現在多くのユーザーが移行中です。

# Forgejoをシングルバイナリで起動(最軽量構成)
# Linux
wget https://codeberg.org/forgejo/forgejo/releases/download/v9.0.0/forgejo-9.0.0-linux-amd64
chmod +x forgejo-9.0.0-linux-amd64
./forgejo-9.0.0-linux-amd64 web --port 3000

# または Docker Compose(PostgreSQL付き本番構成)
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
  forgejo:
    image: codeberg.org/forgejo/forgejo:9
    restart: unless-stopped
    ports:
      - "3000:3000"
      - "222:22"
    environment:
      USER_UID: 1000
      USER_GID: 1000
      FORGEJO__database__DB_TYPE: postgres
      FORGEJO__database__HOST: db:5432
      FORGEJO__database__NAME: forgejo
      FORGEJO__database__USER: forgejo
      FORGEJO__database__PASSWD: forgejo_password
      FORGEJO__server__DOMAIN: git.yourcompany.com
      FORGEJO__server__ROOT_URL: https://git.yourcompany.com
      FORGEJO__server__SSH_DOMAIN: git.yourcompany.com
    volumes:
      - forgejo_data:/data
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_DB: forgejo
      POSTGRES_USER: forgejo
      POSTGRES_PASSWORD: forgejo_password
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  forgejo_data:
  postgres_data:
EOF

docker compose up -d
# WebUI: https://git.yourcompany.com
# 初回アクセス時にセットアップウィザードが表示される
# Gitea/Forgejo CLI(tea)でリポジトリ操作
# Gitea/Forgejoは「tea」というCLIツールを提供
brew install tea    # macOS
# または go install code.gitea.io/tea@latest

# ログイン設定
tea login add --url https://git.yourcompany.com --token your-access-token

# リポジトリ作成
tea repo create --name my-new-repo --description "My awesome project" --private

# Issueを作成
tea issues create --title "バグ修正: ログイン後にセッションが切れる"   --body "再現手順: 1. ログイン 2. 10分放置 3. ページ操作 → 強制ログアウト"   --label "bug"   --assignee "yamada-taro"

# プルリクエスト一覧
tea prs list --state open --repo myorg/myrepo

# GitHubからForgejoへのリポジトリ移行
tea repo migrate   --url https://github.com/myorg/myrepo   --name myrepo   --auth-token ghp_xxxxxxxx   --mirror    # ミラー同期(GitHub変更を自動反映)

機能比較表

比較項目GitLab CEGiteaForgejo
CI/CD内蔵✅(最高)✅(Gitea Actions)✅(Forgejo Actions)
コンテナレジストリ
セキュリティスキャン✅(SAST/DAST)
メモリ使用量2GB〜256MB〜256MB〜
LDAP/SSO
GitHub Actions互換
GitHub Stars23k+45k+9k+

GitLab CI/CDで生成したDockerイメージの管理にはDevOpsカテゴリ/categories/devopsのHarbor(コンテナレジストリ)と組み合わせます。GitLabのIssue管理・プロジェクト管理はMiscカテゴリ/categories/miscのPlane・Taigaと役割が重複するため、チームの規模と用途で使い分けます。

FAQ

Q. GitLab・Gitea・ForgejoのどれをGitHub代替に選ぶべきですか?

A. チームの規模と必要機能で判断します。10人以下のスタートアップ・軽量優先: Forgejo一択。シングルバイナリで256MBから動き、GitHub Actionsと互換のForgejoActionsが使える。50人以下・CI/CDも1つに統合したい: GitLab CEが最適。GitLab Runner・コンテナレジストリ・セキュリティスキャンを追加コストなしで使える。100人以上・エンタープライズ: GitLab EE(有料)または GitLab.comのSaaSプランを検討。セルフホストの運用コストを考慮するとGitLab.comの方が安い場合もある。Gitea/ForgejoはGitHub Actionsのyamlをほぼそのまま使えるため、GitHub→Forgejo移行が最もスムーズです。

Q. GitLab CEのCI/CDランナーをDockerで設定するには?

A. GitLab Runnerを別ホストで起動してGitLab CEに登録します。

# GitLab Runnerをインストール
curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | bash
apt-get install gitlab-runner

# GitLab CEのURLとRegistration Tokenで登録
# Registration Token: GitLab CE → Settings → CI/CD → Runners → Registration token
gitlab-runner register   --url https://gitlab.yourcompany.com   --registration-token YOUR-TOKEN   --executor docker   --docker-image alpine:latest   --description "My Docker Runner"   --tag-list "docker,linux"   --run-untagged=true   --locked=false

# Runnerを起動
gitlab-runner start

Q. GitHubからGitLabへのリポジトリ移行はどうやりますか?

A. GitLabのインポート機能を使います。①GitLab → New Project → Import project → GitHub②GitHubのPersonal Access Tokenを入力③移行するリポジトリを選択→Import。移行される内容: リポジトリ・Issues・Pull Requests(MRに変換)・Wiki・ラベル・マイルストーン。移行されない内容: GitHub Actionsのワークフロー(GitLab CI/CDに書き直しが必要)・GitHub Pagesの設定・GitHub Apps。GitHubからForgejoはGitHub Actions→Forgejo Actionsが互換のため.github/workflows/*.ymlをほぼそのまま使えます(runs-on: ubuntu-latest等は共通)。

Q. GiteaとForgejoはどちらを選ぶべきですか?

A. Forgejo推奨です。理由: ①2022年にGiteaの開発が特定企業(Gitea Ltd.)に集中し、コミュニティの意思決定の透明性が低下②ForgejoはLinux Foundation関連のSoftware Freedom Conservancyに参加するコミュニティ主導プロジェクト③Codeberg.orgという実績あるホスティングサービスがForgejoを採用④機能・API・UI・Actionsの互換性がほぼ100%で移行コストゼロ。既にGiteaを使っている場合でもForgejoはバイナリを差し替えるだけで移行できます(データベース互換)。

まとめ

ユースケース推奨ツール
CI/CD統合・コンテナレジストリ・フルDevOpsGitLab CE
軽量・GitHub Actions互換・小〜中規模チームForgejo
シンプル・最軽量・ラズパイでも動くGitea

関連外部リソース

他の記事も読む

Let's Build Together

OSS導入、自社だけで悩まない。

ツール選定から構築・運用・AI活用まで、オープンソースラボ運営元のClasslessが伴走します。初回のご相談は無料です。