第3回まで無料

サービス公開と運用入門コース

置き場所の選び方から、サーバーの要塞化・Docker Compose・Caddy による TLS・初回デプロイ・バックアップと復元・ロールバック・メンテナンス画面・CI からの更新まで。全50レッスンで「自分のサービスを 1 つ、月数百円の VPS で動かし続ける」ところまで進みます。Docker と Caddy は本物を手元で動かし、出力はすべて実測したものを載せています。

カリキュラム

全50レッスンを7つの章に分けています。第1章から順に進めるのがおすすめですが、 気になるところだけ拾い読みしてもかまいません。 ※ コマンドはブラウザ内で実行できないため、Docker と Caddy を入れた手元の環境で試してください。サーバーの設定は捨ててよい VPS で試し、動いている本番のサーバーでいきなり試さないこと。ドメイン・IP・ユーザー名は例示用の値(deploy.example.com など)に置き換えてあります。

Chapter 1 — どこに置くか(第1〜6回)

VPS・PaaS・コンテナサービスのどれに置くかを決め、月いくらで回せるかを見積もり、ドメインを取って DNS をサーバーに向けます。最後は Caddy→app→db の三層を compose でどう束ねるかを確かめます。

Chapter 2 — サーバーを立ち上げる(第7〜14回)

SSH 鍵でのログイン、作業用ユーザーと最小の sudo、sshd の要塞化、ファイアウォール、自動更新、fail2ban を順に入れます。最後はそれらの抜けを機械で点検するチェックリストを作ります。

7

SSH 鍵でログインする

ed25519 の鍵ペアを作り、公開鍵をサーバーの authorized_keys に置く。秘密鍵を手元に留める理由と、~/.ssh/config でサーバーに名前を付ける方法。

🔒 ベーシック
8

作業用ユーザーと最小の sudo

root で作業せず、作業用ユーザーに必要なコマンドだけ sudo を許す。sudoers を visudo -cf で検査してから置く手順。

🔒 ベーシック
9

sshd の要塞化

SSH の入口を sshd_config で固める。root ログインの禁止・鍵のみ・試行回数の制限と、締め出されずに反映する手順。

🔒 ベーシック
10

パスワード認証を止める

鍵でログインできることを確かめてから、パスワード認証を閉じる。順番を守る理由と、AllowUsers で入れるユーザーを絞る設定。

🔒 ベーシック
11

ファイアウォールは既定 deny

ufw で受信を既定で塞ぎ、SSH・HTTP・HTTPS の 3 つだけを開ける。DB のポートを開けない理由と、事業者側のパケットフィルタとの二重の確認。

🔒 ベーシック
12

自動セキュリティ更新

unattended-upgrades でセキュリティ更新を自動で当てる。設定の 3 行の意味と、再起動が要る更新の扱い。

🔒 ベーシック
13

fail2ban で総当たりを遮断する

SSH への連続失敗を数え、閾値を超えた IP を一定時間 ban する。jail.local の maxretry・findtime・bantime の決め方と、鍵認証との多層防御。

🔒 ベーシック
14

要塞化のチェックリスト

sshd・自動更新・fail2ban・ファイアウォールの設定を、1 つの関数でまとめて点検する。「入れたつもり」の抜けを機械で拾って第2章を締める。

🔒 ベーシック

Chapter 3 — アプリをコンテナで動かす(第15〜22回)

Django アプリを Dockerfile で固め、docker compose で PostgreSQL と束ねます。healthcheck・.env・永続ボリューム・秘密情報の生成まで、本番で事故になりやすいところを実測で確かめます。

15

Dockerfile でアプリを固める

Django アプリを python:3.13-slim のイメージに固める。collectstatic はビルド時、migrate は起動時に振り分ける Dockerfile の組み立て。

🔒 ベーシック
16

レイヤキャッシュと非 root

requirements.txt を先に COPY してビルドを速くし、useradd と USER app で非 root で動かす。速く、安全なイメージを作る Dockerfile の定石。

🔒 ベーシック
17

docker compose で app と db を束ねる

アプリと PostgreSQL を 1 つの compose にまとめ、depends_on の service_healthy で起動順を宣言する。DB が受け付ける前にアプリが落ちる事故の防ぎ方。

🔒 ベーシック
18

healthcheck で「使える」を判定する

起動したことと使えることは別物。db は pg_isready、app は DB に触れる /api/health で healthy を判定し、デプロイはそれを待ってから進む。

🔒 ベーシック
19

環境変数と .env に秘密を集める

鍵やパスワードをコードに書かず、サーバー上の .env に集めて env_file で渡す。.env.example をひな形にし、整合チェッカで抜けを拾う。

🔒 ベーシック
20

.env の落とし穴:パスワード不一致と DEBUG

最頻出の事故は DATABASE_URL のパスワードと POSTGRES_PASSWORD の食い違い。本番での DJANGO_DEBUG=1 とあわせて、起動前にチェッカで拾う。

🔒 ベーシック
21

永続ボリュームでデータを残す

コンテナは使い捨て、データは名前付きボリュームに置く。db を再起動してもデータが残ることを実測し、down -v でデータごと消える落とし穴を避ける。

🔒 ベーシック
22

秘密情報を安全に生成する

DJANGO_SECRET_KEY や DB のパスワードを secrets.token_urlsafe で作る。推測できず、DATABASE_URL に埋めても壊れない値の条件。

🔒 ベーシック

Chapter 4 — リバースプロキシとTLS(第23〜30回)

前段に Caddy を置き、443 で受けてアプリへ渡します。証明書の自動取得と更新、静的ファイル、HTTPS リダイレクト、複数サービスの同居、edge ネットワークまでを Caddyfile と compose で組みます。

23

Caddy を前段に置く

前段の Caddy に TLS の終端とリバースプロキシを任せる。ドメインと reverse_proxy の数行で済む Caddyfile と、本物の caddy validate での検証。

🔒 ベーシック
24

reverse_proxy の中身を caddy adapt で見る

443 で受けて app:8000 へ渡す reverse_proxy を、caddy adapt で JSON に変換して確かめる。app というサービス名で後段が見つかる仕組み。

🔒 ベーシック
25

TLS 証明書の自動取得

ドメインを書くだけで、Caddy が Let's Encrypt から証明書を取って 443 で待ち受ける。自動 HTTPS が動く前提と、取れないときに疑う場所。

🔒 ベーシック
26

証明書の自動更新

証明書の期限切れは個人サービスでありがちな事故。Caddy が期限前に自動で更新する仕組みと、並べたホスト名がすべて対象になることの確認。

🔒 ベーシック
27

静的ファイルは whitenoise で配る

CSS や JS を Caddy に置かず、whitenoise で Django 側から配る。ミドルウェアと圧縮・ハッシュ付きのストレージ、ビルド時の collectstatic でコンテナ 1 つに閉じる構成。

🔒 ベーシック
28

HTTPS リダイレクトと health の除外

http を https へ転送しつつ、healthcheck の /api/health だけは除外する。プロキシ配下で https を認識させる SECURE_PROXY_SSL_HEADER と、除外を忘れたときに起きること。

🔒 ベーシック
29

複数サービスを 1 台に同居させる

1 台の VPS に複数のサイトを載せ、Caddyfile にブロックを並べる。片方を消しても validate が通ってしまう危険と、現物を読んでから編集する手順。

🔒 ベーシック
30

edge と backend でネットワークを分ける

前段の Caddy とアプリを繋ぐ edge と、アプリと DB を繋ぐ backend を分ける。app は両方、db は backend だけ、edge は external の共有ネットワークという構成の点検。

🔒 ベーシック

Chapter 5 — 初回デプロイと確認(第31〜38回)

検査→転送→ビルド→確認の流れを deploy スクリプトにまとめ、初回デプロイを通します。マイグレーション・管理者アカウント・SMTP の疎通を確かめ、最後は公開前チェックリストで抜けを拾います。

31

deploy スクリプトの流れ

ローカル検査・rsync での転送・メンテナンス画面・ビルドと再起動・healthy 待ち・疎通確認を 1 本のスクリプトにまとめる。set -euo pipefail と shellcheck で、壊れたまま進めない。

🔒 ベーシック
32

ローカル検査:壊れたコードを転送しない

rsync で送る前に、手元の .venv の python で manage.py check を流す。サーバーで気づく前に手元で弾く理由と、システムの python では駄目な理由。

🔒 ベーシック
33

初回デプロイ:health 200 まで

docker compose up -d --build でビルドから起動まで進め、起動時に migrate が当たり、/api/health が 200 を返せば成功。サーバーに置くものと、初回の順番。

🔒 ベーシック
34

マイグレーションは起動時に当てる

DB のスキーマ変更を起動時の CMD で自動的に当て、未適用を残さない。migrate --check と showmigrations での確認と、makemigrations をサーバーで実行してはいけない理由。

🔒 ベーシック
35

管理者アカウントをコンテナの中で作る

公開後に最初にやる管理者アカウントの作成を、docker compose exec でコンテナの中から行う。本番の対話的な作り方と、-T を付ける場面、作ったあとの初期設定。

🔒 ベーシック
36

SMTP の疎通確認

登録確認・パスワード再設定・ログインコードを支えるメールの設定。EMAIL_HOST で SMTP に切り替わる仕組みと、失敗の種類を直すべき環境変数へ対応づける確かめ方。

🔒 ベーシック
37

rsync の除外で .env を守る

rsync --delete は受け側の余分なファイルを消す。.env・var・staticfiles・.venv を除外して、コードだけを最新にし、サーバー側の秘密と生成物を残す。

🔒 ベーシック
38

公開前チェックリスト

TLS・health・管理者・SMTP・登録の経路・バックアップの 6 項目を一覧にし、抜けを関数で拾う。バックアップを公開前に確かめる理由と、第6章への橋渡し。

🔒 ベーシック

Chapter 6 — 壊れたときに戻す(第39〜45回)

pg_dump でバックアップを取り、データを消してから戻すところまで実測します。コードとイメージのロールバック、メンテナンス画面、ログからの切り分けで、公開して終わりにしない備えを作ります。

39

バックアップは pg_dump で取る

データは PostgreSQL の中だけにある。pg_dump を gzip で保存する backup.sh と、--clean --if-exists で復元しやすくする理由、取れたファイルが本物の SQL であることの確認。

🔒 ベーシック
40

復元:消してから戻して確かめる

バックアップは戻せて初めて意味がある。行を作り、バックアップし、全部消し、restore.sh で戻す round-trip を本物のスタックで実測する。

🔒 ベーシック
41

cron で毎日バックアップを取る

バックアップを cron で毎朝自動に取り、14 日より古いものを消す。crontab の 1 行の読み方と、別の場所にも送ってサーバーごとの喪失に備える考え方。

🔒 ベーシック
42

コードのロールバック

壊れたリリースは素早く戻すのが最優先。git で前のコミットに戻して deploy し直す手順と、マイグレーションを含む変更を戻すときは先に DB を戻す理由。

🔒 ベーシック
43

イメージのロールバック

デプロイの前に、いまの myapp:latest に日付入りのタグを付けて退避しておく。問題があれば退避したタグに差し替えて up -d するだけで、ビルドし直さずに前の版へ戻せる。

🔒 ベーシック
44

メンテナンス画面:エッジの Caddy で 503

前段の Caddy がフラグファイル 1 つで 503 とメンテナンス画面を返す。reload が要らない仕組み、アプリが落ちていても出る理由、Retry-After で一時的な停止を伝える方法。

🔒 ベーシック
45

ログの見方と症状からの切り分け

よくある症状には決まった原因がある。is restarting・unhealthy・DisallowedHost・password authentication failed を原因へ対応づけ、docker compose logs の末尾から例外を読む。

🔒 ベーシック

Chapter 7 — 続けて運用する(第46〜50回)

2 回目以降の更新と CI からの自動デプロイ、費用とメモリの上限、監視の最低限を扱います。最後に全50回を「作って、出して、動かし続ける」運用の型としてまとめます。

全50レッスンを終えたら、次は push からデプロイまでを自動にする GitHub Actions や、サーバーそのものをコードで用意する Terraform へ。メンバーシップで全コースが解放されます。