作ったアプリケーションをGitHubへ公開してみた

自作のToDoアプリ(FastAPI + React)を、.env やデータベースなどの秘密情報を除外して安全な形でGitHubに公開した手順です。


今回の環境

項目内容
OSWindows 11 Home
ターミナルGit Bash(Gitのコマンド)/PowerShell
Git2.51.0.windows.2
公開したものFastAPI + React のToDoアプリ(バックエンド・フロントエンド一式)
公開先GitHub(Publicリポジトリ)

公開してはいけないファイル

プロジェクトのフォルダを点検したところ、次のファイルが見つかりました。どれもGitHubに上げてはいけないものです。

ファイル中身
backend/.envJWT署名用の SECRET_KEY などの設定値
backend/.secret_key開発時に自動生成された秘密鍵
backend/todo.dbSQLiteのデータベース(ユーザー情報・自分のタスク)
backend.zip / frontend.zip作成した覚えのないZIP。backend.zip の中に .env、.secret_key、todo.db が入っていた
chat-summary.md非公開ページへのリンクを含むメモ
ToDoアプリ_仕様書.docx公開不要の仕様書

ZIPの中身は、次のコマンドで確認できます(Git Bashで実行)。

python -c "
import zipfile
for f in ['backend.zip','frontend.zip']:
    n=zipfile.ZipFile(f).namelist(); print(f, len(n),'entries')
    print([x for x in n if any(k in x.lower() for k in ('.env','secret','.db','.key','node_modules','.venv'))][:15])
"

.gitignore とは?
Gitに「このファイルは管理しない(GitHubにも上げない)」と伝えるための設定ファイルです。プロジェクトのフォルダ直下に置きます。


GitHubに公開する手順

手順1:.gitignore を書く

プロジェクト直下に .gitignore を作り、次の内容にしました。秘密情報とデータベースに加えて、ZIPや出所のわからないファイルも除外しています。

# --- 秘密情報(公開しない) ---
.env
.env.*
!.env.example
.secret_key
*.pem
*.key

# --- データベース(ユーザー情報・個人のタスクを含む) ---
*.db
*.sqlite
*.sqlite3

# --- 生成物・依存 ---
__pycache__/
*.pyc
.venv/
node_modules/
dist/
.pytest_cache/

# --- 公開不要・秘密が混入しているファイル ---
*.zip
*.docx
chat-summary.md

!.env.example は「.env.example だけは除外しない」という意味です。.env.example は設定項目の雛形で、値は空にしてあります。

# このファイルを .env にコピーして値を設定する(.env はGit管理外)

# PostgreSQL 接続先。未設定の場合は backend/todo.db(SQLite)を使う
DATABASE_URL=postgresql://todo:your-password@localhost:5432/todo

# JWT署名用の秘密鍵(本番は必須)
#   python -c "import secrets;print(secrets.token_urlsafe(48))"
SECRET_KEY=

# フロントエンドのオリジン(カンマ区切り)
CORS_ORIGINS=http://localhost:5173

手順2:ローカルリポジトリを作り、追加されるファイルを確認する

Git Bashでプロジェクトのフォルダに移動し、リポジトリを作って全ファイルを追加します。git ls-files で、コミットされる予定のファイルを一覧にします。

cd "プロジェクトのフォルダ"
git init -b main
git add -A
git ls-files

一覧を目で見るだけでなく、危ないファイル名が含まれていないかを grep で検索します。何も表示されなければOKです。

git ls-files | grep -Ei '(^|/)\.env$|secret_key|\.db$|\.zip$|\.docx$|chat-summary|\.venv|node_modules|dist/'

git add のときに LF will be replaced by CRLF という警告が大量に出ましたが、Windowsの改行コードに関する警告で、問題はありません。

手順3:ファイルの中身に秘密の値がないか検索する

ファイル名だけでなく、中身も検索します。git grep --cached は、git add したファイルの中身を検索するコマンドです。.env に書いてある実際の鍵の一部や、自分の名前・IDで検索しました。

git grep --cached -n "実際の鍵の一部"
echo $?
git grep --cached -nEi "自分の名前|自分のID|非公開ページのURL"
echo $?

echo $? は直前のコマンドの終了コードを表示します。git grep は、見つからなければ 1、見つかれば 0 を返します。私の場合はどちらも 1(該当なし)でした。

「|| echo 問題なし」の確認は危ない
最初は git grep -n "鍵" --cached || echo "含まれていません" のように書いていました。ところがオプションの位置が間違っていて、fatal: option '--cached' must come before non-option arguments で失敗していたのに、「含まれていません」と表示されていました。|| の後ろは、検索で見つからなかったときだけでなく、コマンド自体が失敗したときにも実行されます。確認用のコマンドは、終了コードまで見るようにしてください。

手順4:GitHubアカウントを作り、メールアドレスを非公開にする

  1. GitHubのサイトで「Sign up」からアカウントを作る
  2. 右上のアイコン →「Settings」→「Emails」を開く
  3. 「Keep my email addresses private」にチェックを入れる
  4. 表示される身代わりのアドレス(<ID>+<ユーザー名>@users.noreply.github.com)をメモする

なぜメールアドレスを隠すのか
Gitのコミットには、作者のメールアドレスが記録されます。Publicリポジトリでは誰でも見られるので、普段使いのアドレスが公開されてしまいます。GitHubの設定だけでは不十分で、次の手順でGit側にも身代わりのアドレスを設定する必要があります。

手順5:Gitに名前とメールアドレスを設定する

git config --global user.name "<ユーザー名>"
git config --global user.email "<ID>+<ユーザー名>@users.noreply.github.com"

手順6:最初のコミットを作る

git commit -m "Initial commit"

手順7:GitHubに空のリポジトリを作る

GitHubの右上「+」→「New repository」から、リポジトリを作ります。

  • Repository name:todo-app
  • 公開範囲:Public
  • README・.gitignore・ライセンスは追加しない(空のリポジトリにする)

手順8:GitHubにpushする

git remote add origin https://github.com/<ユーザー名>/todo-app.git
git push -u origin main

初回の git push では、ブラウザに「Authorize git-ecosystem」という認証画面が開きました。これはGitに同梱されている公式の認証ツール(Git Credential Manager)の画面です。直前に自分で git push を実行したのであれば、承認して大丈夫です。


動作確認:公開された内容を確認する

コミットに記録されたメールアドレスが身代わりのアドレスになっているかを確認します。

git log --format='%h | %an | %ae | %cn | %ce | %s'

作者(%ae)とコミッター(%ce)の両方が …@users.noreply.github.com になっていればOKです。

次に、GitHub側に公開されたファイルの一覧と、公開範囲をAPIで確認します。ブラウザの画面だけで判断せず、ファイル名を一覧で見るのが確実です。

# 公開されたファイルの一覧
curl -s "https://api.github.com/repos/<ユーザー名>/todo-app/git/trees/main?recursive=1" | grep '"path"'

# 公開範囲(private と visibility)
curl -s https://api.github.com/repos/<ユーザー名>/todo-app | grep -E '"private"|"visibility"'

私の場合、公開されたファイルは62件で、名前で引っかかったのは backend/.env.example(中身は雛形)だけでした。公開範囲は "private": false、"visibility": "public" でした。


つまずいたところ

公開不要のメモ(SESSION_NOTES.md)までpushしていた

作業内容をまとめた SESSION_NOTES.md(設計メモ)を、そのまま公開してしまいました。秘密の値は入っていませんでしたが、公開する必要のないファイルです。
ほかのファイルから参照されていないことを確認してから、削除してpushしました。

git grep -n "SESSION_NOTES"
git rm SESSION_NOTES.md
git commit -m "Remove SESSION_NOTES.md"
git push

これで最新の状態からは消えますが、過去のコミット(Initial commit)にはファイルが残ったままです。

履歴を作り直して強制pushした

履歴からも消すために、コミット履歴を1から作り直して、GitHub側を強制的に上書きしました。

cd "プロジェクトのフォルダ"
git status
git checkout --orphan clean-main
git add -A
git commit -m "Initial commit"
git branch -D main
git branch -m main
git push -f origin main

実行後、ローカル・GitHubともにコミットは「Initial commit」の1件だけになり、SESSION_NOTES.md も一覧から消えました(ファイルは61件)。

強制pushしても、古いコミットは番号指定で見られた

念のため、古いコミットの番号を指定してアクセスしてみました。

curl -s -o /dev/null -w "%{http_code}\n" "https://api.github.com/repos/<ユーザー名>/todo-app/commits/<古いコミット番号>"
curl -s -o /dev/null -w "%{http_code}\n" "https://raw.githubusercontent.com/<ユーザー名>/todo-app/<古いコミット番号>/SESSION_NOTES.md"

結果は、どちらも 200(取得できる)でした。GitHubは、ブランチから外れたコミットをすぐには削除せず、後で自動的に整理する仕組みのようで、main の履歴から消えても、番号を知っていれば中身を見られる状態でした。

完全に消したい場合の選択肢は、次の3つです。

  • リポジトリを削除して同じ名前で作り直し、git push -u origin main する(確実)
  • GitHubサポートに、参照されないコミットの削除を依頼する(URLは変わらない)
  • GitHubが自動で整理するのを待つ(時期はわからない)

今回のファイルは設計メモで、セキュリティ上問題のある内容は含まれていなかったため、古いコミットはそのままにしました。もし鍵やパスワードをpushしてしまった場合は、履歴の削除に頼らず、鍵やパスワードそのものを新しく作り直す必要があります。


まとめ

  • .env、秘密鍵、データベースは .gitignore で除外する
  • ZIPや出所のわからないファイルは、公開前に中身を確認する
  • git add の後、git ls-files と git grep --cached で、ファイル名と中身の両方を点検する
  • 確認用のコマンドは、|| echo に頼らず終了コードまで見る
  • コミットのメールアドレスは、GitHubの設定と git config の両方で身代わりのアドレスにする
  • 公開後はAPIでファイル一覧と公開範囲を確認する
  • 強制pushしても、古いコミットはしばらくGitHubに残る。一度pushした鍵やパスワードは作り直す

今回公開したToDoアプリのGitHubリンクでs。
👉 【todo-app】(GitHub)

コメント

タイトルとURLをコピーしました