[{"data":1,"prerenderedAt":3132},["ShallowReactive",2],{"content-doc:article:/articles/raspi-immich-home-photos":3,"content-surroundings:article:/articles/raspi-immich-home-photos":3121},{"id":4,"title":5,"body":6,"date":3106,"description":3107,"extension":3108,"kind":3109,"meta":3110,"navigation":162,"ogImage":3109,"path":3111,"seo":3112,"sitemap":3113,"stem":3114,"tags":3115,"updatedAt":3109,"__hash__":3120},"article/articles/raspi-immich-home-photos.md","ラズパイで写真管理をして1年経った",{"type":7,"value":8,"toc":3084},"minimark",[9,16,23,26,33,36,40,53,56,75,78,113,116,119,127,130,133,139,312,315,334,338,428,432,435,439,442,451,454,457,483,492,495,498,514,517,520,524,627,631,641,645,648,654,657,691,700,703,714,717,735,739,749,759,762,765,771,777,787,798,801,805,903,907,915,926,943,947,960,966,969,972,980,987,994,1000,1003,1006,1010,1166,1172,1175,1195,1198,1209,1212,1215,1218,1221,1252,1255,1258,1261,1267,1273,1284,1290,1293,1297,1304,1311,1317,1322,1328,1331,1337,1340,1346,1349,1353,1363,1366,1386,1392,1395,1401,1407,1416,1422,1425,1428,1431,1529,1538,1544,1550,1553,1559,1568,1577,1580,1586,1590,1593,1699,1717,1728,1739,1743,1746,1777,1791,1794,1797,1801,1807,1810,1816,1819,1826,1830,1841,1850,1857,1860,1864,2027,2031,2044,2047,2050,2052,2083,2089,2106,2112,2118,2124,2127,2133,2136,2150,2156,2159,2163,2166,2170,2319,2322,2325,2342,2348,2351,2365,2371,2374,2380,2383,2398,2404,2407,2419,2425,2428,2445,2451,2459,2465,2468,2474,2477,2483,2486,2632,2635,2646,2651,2658,2662,2665,2686,2692,2703,2709,2719,2725,2728,2734,2737,2755,2761,2764,2788,2794,2797,2801,2804,2826,2832,2835,2841,2844,2861,2865,2868,2877,2880,2883,2971,3010,3013,3016,3027,3030,3041,3044,3052,3080],[10,11,12],"note",{},[13,14,15],"p",{},"まだmermaid記法に未対応のため、コードのまま掲載しています",[13,17,18],{},[19,20],"img",{"alt":21,"src":22},"自宅サーバの様子（ラズパイ・HDD・ルータ）","/images/articles/raspi-immich-home-photos/introduction/server.webp",[13,24,25],{},"2024年6月から自宅サーバで「おうちGoogleフォト」を運用している。\nスマホで撮影した写真・動画を事実上無制限に保存して快適に閲覧ができる。",[13,27,28,32],{},[19,29],{"alt":30,"src":31},"Immichタイムラインの様子","/images/articles/raspi-immich-home-photos/introduction/immich_timeline.webp","\n遠方の両親にはアルバムを共有。モバイルアプリがあるのでスマホから見てもらえる。",[13,34,35],{},"運用開始から約1年、安定稼働しているため、構築手順やハマりどころなどを振り返っておく。",[37,38,39],"h2",{"id":39},"モチベ",[13,41,42,43,46],{},"2024年に第一子が生まれ、写真・動画が一気に増えた。\nそれまで Google フォト のフリープランで運用していたが、無制限が終了したことで容量が 16GB ほどに制限されており、さすがに限界を迎えた。",[44,45],"br",{},[47,48,52],"a",{"href":49,"rel":50},"https://www.itmedia.co.jp/news/articles/2011/12/news057.html",[51],"nofollow","Googleフォトの容量無制限無料バックアップ、2021年5月末で終了",[13,54,55],{},"容量を気にせずバンバン撮りたいので、👇の目標を立てた。",[57,58,59,63,66,69,72],"ol",{},[60,61,62],"li",{},"事実上、無限に保存できること",[60,64,65],{},"スマホから保存・閲覧できること",[60,67,68],{},"サブスクしないこと",[60,70,71],{},"Google フォトからデータ移行できること",[60,73,74],{},"遠方の両親にもシェアできること",[13,76,77],{},"現在（2025/08）のデータは合計265.6GBあるため、もしサブスクで運用すると...",[79,80,81,89,97,105],"ul",{},[60,82,83,88],{},[47,84,87],{"href":85,"rel":86},"https://www.apple.com/jp/icloud/",[51],"iCloud"," 2TB ¥1,500/月",[60,90,91,96],{},[47,92,95],{"href":93,"rel":94},"https://one.google.com/about/plans?hl=ja&g1_landing_page=0",[51],"Google"," 2TB ¥1,450/月",[60,98,99,104],{},[47,100,103],{"href":101,"rel":102},"https://www.amazon.co.jp/b?ie=UTF8&node=5262648051",[51],"Amazonフォト"," は動画が5GBまでなので却下",[60,106,107,112],{},[47,108,111],{"href":109,"rel":110},"https://mitene.us/",[51],"みてね"," は動画一本の長さが2分までに制限されるようなので却下",[13,114,115],{},"Googleでも ¥17,400/年 かかる模様",[13,117,118],{},"この記事では、",[57,120,121,124],{},[60,122,123],{},"フォトストレージの構築（1.2.3.4.）",[60,125,126],{},"遠隔地の写真をシェアする(5.)",[13,128,129],{},"という2つのゴールに分けて解説。",[37,131,132],{"id":132},"完成図",[13,134,135],{},[19,136],{"alt":137,"src":138},"左から、ラズパイ・ルータ・HDD・ONU","/images/articles/raspi-immich-home-photos/overview/server2.webp",[140,141,146],"pre",{"className":142,"code":143,"language":144,"meta":145,"style":145},"language-mermaid shiki shiki-themes github-light","graph LR\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\n    cloudflared\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    cloudflared \u003C--> immich-server\n    cloudflared \u003C--> |\"Cloudflare Tunnel\"|cloudflare[\"Cloudflare\"]\n\n    cloudflare \u003C--> |\"サービストークン\"|mobile[\"Mobile App\"]\n    cloudflare \u003C--> |\"ワンタイムパスワード / SSO認証\"|web[\"Web App\"]\n","mermaid","",[147,148,149,157,164,170,176,182,188,194,199,205,211,217,222,227,233,239,244,249,255,261,266,272,278,283,289,295,300,306],"code",{"__ignoreMap":145},[150,151,154],"span",{"class":152,"line":153},"line",1,[150,155,156],{},"graph LR\n",[150,158,160],{"class":152,"line":159},2,[150,161,163],{"emptyLinePlaceholder":162},true,"\n",[150,165,167],{"class":152,"line":166},3,[150,168,169],{},"subgraph lan[\"LAN\"]\n",[150,171,173],{"class":152,"line":172},4,[150,174,175],{},"subgraph rapy[\"Raspberry Pi 4\"]\n",[150,177,179],{"class":152,"line":178},5,[150,180,181],{},"    immich-server\n",[150,183,185],{"class":152,"line":184},6,[150,186,187],{},"    cloudflared\n",[150,189,191],{"class":152,"line":190},7,[150,192,193],{},"end\n",[150,195,197],{"class":152,"line":196},8,[150,198,163],{"emptyLinePlaceholder":162},[150,200,202],{"class":152,"line":201},9,[150,203,204],{},"subgraph hdds[\"HDDケース\"]\n",[150,206,208],{"class":152,"line":207},10,[150,209,210],{},"    hdd1\n",[150,212,214],{"class":152,"line":213},11,[150,215,216],{},"    hdd2\n",[150,218,220],{"class":152,"line":219},12,[150,221,193],{},[150,223,225],{"class":152,"line":224},13,[150,226,163],{"emptyLinePlaceholder":162},[150,228,230],{"class":152,"line":229},14,[150,231,232],{},"web_in_lan\n",[150,234,236],{"class":152,"line":235},15,[150,237,238],{},"mobile_in_lan\n",[150,240,242],{"class":152,"line":241},16,[150,243,193],{},[150,245,247],{"class":152,"line":246},17,[150,248,163],{"emptyLinePlaceholder":162},[150,250,252],{"class":152,"line":251},18,[150,253,254],{},"    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n",[150,256,258],{"class":152,"line":257},19,[150,259,260],{},"    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n",[150,262,264],{"class":152,"line":263},20,[150,265,163],{"emptyLinePlaceholder":162},[150,267,269],{"class":152,"line":268},21,[150,270,271],{},"    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n",[150,273,275],{"class":152,"line":274},22,[150,276,277],{},"    web_in_lan[\"Web App\"] \u003C--> immich-server\n",[150,279,281],{"class":152,"line":280},23,[150,282,163],{"emptyLinePlaceholder":162},[150,284,286],{"class":152,"line":285},24,[150,287,288],{},"    cloudflared \u003C--> immich-server\n",[150,290,292],{"class":152,"line":291},25,[150,293,294],{},"    cloudflared \u003C--> |\"Cloudflare Tunnel\"|cloudflare[\"Cloudflare\"]\n",[150,296,298],{"class":152,"line":297},26,[150,299,163],{"emptyLinePlaceholder":162},[150,301,303],{"class":152,"line":302},27,[150,304,305],{},"    cloudflare \u003C--> |\"サービストークン\"|mobile[\"Mobile App\"]\n",[150,307,309],{"class":152,"line":308},28,[150,310,311],{},"    cloudflare \u003C--> |\"ワンタイムパスワード / SSO認証\"|web[\"Web App\"]\n",[13,313,314],{},"LAN 内の Immich サーバが Cloudflare を通じて外部公開される様子。モバイルアプリからはトークン、WebアプリからはSSO認証を通じてアクセスする。",[79,316,317],{},[60,318,319,320],{},"登場人物\n",[57,321,322,325,328,331],{},[60,323,324],{},"Immich: 写真・動画管理用のOSSアプリケーション",[60,326,327],{},"Raspberry Pi: Immichをホストするサーバ",[60,329,330],{},"HDD・ケース: DB,写真の保存領域",[60,332,333],{},"Cloudflare: LAN外との通信用のドメイン、トンネリング",[37,335,337],{"id":336},"ゴール1-フォトストレージの構築","ゴール1: フォトストレージの構築",[140,339,341],{"className":142,"code":340,"language":144,"meta":145,"style":145},"graph\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n",[147,342,343,348,352,356,360,364,368,372,376,380,384,388,392,396,400,404,408,412,416,420,424],{"__ignoreMap":145},[150,344,345],{"class":152,"line":153},[150,346,347],{},"graph\n",[150,349,350],{"class":152,"line":159},[150,351,163],{"emptyLinePlaceholder":162},[150,353,354],{"class":152,"line":166},[150,355,169],{},[150,357,358],{"class":152,"line":172},[150,359,175],{},[150,361,362],{"class":152,"line":178},[150,363,181],{},[150,365,366],{"class":152,"line":184},[150,367,193],{},[150,369,370],{"class":152,"line":190},[150,371,163],{"emptyLinePlaceholder":162},[150,373,374],{"class":152,"line":196},[150,375,204],{},[150,377,378],{"class":152,"line":201},[150,379,210],{},[150,381,382],{"class":152,"line":207},[150,383,216],{},[150,385,386],{"class":152,"line":213},[150,387,193],{},[150,389,390],{"class":152,"line":219},[150,391,163],{"emptyLinePlaceholder":162},[150,393,394],{"class":152,"line":224},[150,395,232],{},[150,397,398],{"class":152,"line":229},[150,399,238],{},[150,401,402],{"class":152,"line":235},[150,403,193],{},[150,405,406],{"class":152,"line":241},[150,407,163],{"emptyLinePlaceholder":162},[150,409,410],{"class":152,"line":246},[150,411,254],{},[150,413,414],{"class":152,"line":251},[150,415,260],{},[150,417,418],{"class":152,"line":257},[150,419,163],{"emptyLinePlaceholder":162},[150,421,422],{"class":152,"line":263},[150,423,271],{},[150,425,426],{"class":152,"line":268},[150,427,277],{},[429,430,431],"h3",{"id":431},"必要なもの",[13,433,434],{},"写真管理用のアプリケーションとそれをホストするサーバ、そして保存領域。",[436,437,438],"h4",{"id":438},"アプリケーション",[13,440,441],{},"OSSのフォトアプリケーションはたくさんある。我が家はスマホだけで写真を撮るのでモバイルアプリが必須。",[13,443,444,445,450],{},"👇️の比較表から見たときにモバイルアプリとアルバム機能がある ",[47,446,449],{"href":447,"rel":448},"https://immich.app/",[51],"Immich"," を採用。Googleフォトライクなアプリで、別のツールを使用することでGoogle フォトからのデータ移行（後述）もサポートしている。",[436,452,453],{"id":453},"サーバ",[13,455,456],{},"Raspberry Pi 4 にした。好みです。アクセサリとともに。",[79,458,459,466,473],{},[60,460,461],{},[47,462,465],{"href":463,"rel":464},"https://amzn.to/4fJMDiX",[51],"ラズベリーパイ 4 コンピューターモデルB 8GB",[60,467,468],{},[47,469,472],{"href":470,"rel":471},"https://amzn.to/4mJ9zBl",[51],"Miuzei 最新 Raspberry Pi 4 ケース",[60,474,475,480,482],{},[47,476,479],{"href":477,"rel":478},"https://amzn.to/46Zbo8y",[51],"KIOXIA(キオクシア) 旧東芝メモリ microSD 64GB",[44,481],{},"\nSDはOSのインストール用に必要",[13,484,485,486,491],{},"Immichの ",[47,487,490],{"href":488,"rel":489},"https://immich.app/docs/install/requirements/",[51],"必須要件"," をクリアしている必要はあるので注意。",[436,493,494],{"id":494},"保存領域",[13,496,497],{},"容量については物理HDDを2つ（1つはバックアップ用）用意。",[79,499,500,507],{},[60,501,502],{},[47,503,506],{"href":504,"rel":505},"https://amzn.to/4fTmU7W",[51],"WESTERN DIGITAL 3.5インチ内蔵HDD",[60,508,509],{},[47,510,513],{"href":511,"rel":512},"https://amzn.to/4fFb29p",[51],"LHR-2BDPU3ES",[13,515,516],{},"HDDを裸て使ってみたかった",[13,518,519],{},"さて、必要なものが揃ったら次にラズパイをセットアップします",[429,521,523],{"id":522},"ラズパイとhddのセットアップ","ラズパイとHDDのセットアップ",[140,525,527],{"className":142,"code":526,"language":144,"meta":145,"style":145},"graph\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    style rapy fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n    style hdds fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[147,528,529,533,537,541,545,549,553,557,561,565,569,573,577,581,585,589,593,597,601,605,609,613,617,622],{"__ignoreMap":145},[150,530,531],{"class":152,"line":153},[150,532,347],{},[150,534,535],{"class":152,"line":159},[150,536,163],{"emptyLinePlaceholder":162},[150,538,539],{"class":152,"line":166},[150,540,169],{},[150,542,543],{"class":152,"line":172},[150,544,175],{},[150,546,547],{"class":152,"line":178},[150,548,181],{},[150,550,551],{"class":152,"line":184},[150,552,193],{},[150,554,555],{"class":152,"line":190},[150,556,163],{"emptyLinePlaceholder":162},[150,558,559],{"class":152,"line":196},[150,560,204],{},[150,562,563],{"class":152,"line":201},[150,564,210],{},[150,566,567],{"class":152,"line":207},[150,568,216],{},[150,570,571],{"class":152,"line":213},[150,572,193],{},[150,574,575],{"class":152,"line":219},[150,576,163],{"emptyLinePlaceholder":162},[150,578,579],{"class":152,"line":224},[150,580,232],{},[150,582,583],{"class":152,"line":229},[150,584,238],{},[150,586,587],{"class":152,"line":235},[150,588,193],{},[150,590,591],{"class":152,"line":241},[150,592,163],{"emptyLinePlaceholder":162},[150,594,595],{"class":152,"line":246},[150,596,254],{},[150,598,599],{"class":152,"line":251},[150,600,260],{},[150,602,603],{"class":152,"line":257},[150,604,163],{"emptyLinePlaceholder":162},[150,606,607],{"class":152,"line":263},[150,608,271],{},[150,610,611],{"class":152,"line":268},[150,612,277],{},[150,614,615],{"class":152,"line":274},[150,616,163],{"emptyLinePlaceholder":162},[150,618,619],{"class":152,"line":280},[150,620,621],{},"    style rapy fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[150,623,624],{"class":152,"line":285},[150,625,626],{},"    style hdds fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[436,628,630],{"id":629},"osのインストール","OSのインストール",[13,632,633,634,636],{},"公式に従います。OSを入れたSDカードをラズパイに指してbootする。",[44,635],{},[47,637,640],{"href":638,"rel":639},"https://www.raspberrypi.com/documentation/computers/getting-started.html#sd-cards",[51],"Getting started - Raspberry Pi Documentation",[436,642,644],{"id":643},"ローカルip固定化","ローカルIP固定化",[13,646,647],{},"ラズパイが起動したらローカルIPを固定する。DHCPによる自動割り当てでIPが変わってしまうので、固定化しておくと楽。",[13,649,650],{},[19,651],{"alt":652,"src":653},"バッファローのルータ管理画面","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/DHCP_Settings.webp",[13,655,656],{},"ルータのDHCP設定で、ラズパイの有線LANのMACアドレスに対して任意のIPアドレスを紐づけている（画像の一番下の行）。\nMACアドレスは以下で調べる。",[57,658,659,662,677],{},[60,660,661],{},"ラズパイでをシェルを開く",[60,663,664,676],{},[147,665,668,672],{"className":666,"language":667,"style":145},"language-bash shiki shiki-themes github-light","bash",[150,669,671],{"class":670},"s7eDp","ip",[150,673,675],{"class":674},"sYBdl"," a"," を実行する",[60,678,679,684,685,690],{},[147,680,681],{"className":666,"language":667,"style":145},[150,682,683],{"class":670},"eth0:"," の ",[147,686,687],{"className":666,"language":667,"style":145},[150,688,689],{"class":670},"link/ether"," の後に書いてある",[13,692,693,694,699],{},"wifiを使うなら ",[147,695,696],{"className":666,"language":667,"style":145},[150,697,698],{"class":670},"wlan0"," を探すと良いが、速度を考えると有線がいいでしょう（今回は画像系なので特に）。",[13,701,702],{},"なお、使いたいIPアドレスが別の機器に設定されている場合、そのままでは手動割り当てができない。どうしても特定のIPアドレス（今回の例では 11.14）を使いたい場合は、以下の手順に従う。",[57,704,705,708,711],{},[60,706,707],{},"使いたいIPアドレスを使っている機器を、ネットワークから切断",[60,709,710],{},"ルータを再起動してIPアドレスの割り当てをリセット",[60,712,713],{},"手動設定",[13,715,716],{},"一般的に利用可能な番号から順に割り当てることが多く、結果として若い番号から埋まっていく傾向がある模様（機種や設定で変わる）。",[13,718,719,720,723,724,727,728,730],{},"また、『ラズパイ ip 固定』で検索すると、 ",[147,721,722],{},"/etc/dhcpcd.conf"," を編集したり ",[147,725,726],{},"NetworkManager"," を設定するような記事がでてくるが、私の環境ではどれもうまくいかず...。ラズパイ公式も、ルーターでアドレス指定してねと言っている。",[44,729],{},[47,731,734],{"href":732,"rel":733},"https://www.raspberrypi.com/documentation/computers/configuration.html#assign-a-static-ip-address",[51],"Assign a static IP address",[436,736,738],{"id":737},"vncやsshによる遠隔操作","VNCやSSHによる遠隔操作",[13,740,741,742,744],{},"ラズパイのセットアップが終わったら、毎度モニタにつなぐのも面倒なので遠隔でリモートデスクトップできるようにする。",[44,743],{},[47,745,748],{"href":746,"rel":747},"https://www.indoorcorgielec.com/resources/raspberry-pi/raspberry-pi-vnc/",[51],"VNCでRaspberry Piにリモートデスクトップ接続",[13,750,751,752,754],{},"sshしたときにパスワードを打つのも面倒なので、公開鍵認証しておくと楽ちん",[44,753],{},[47,755,758],{"href":756,"rel":757},"https://raspi-school.com/ssh/",[51],"ラズベリーパイをリモート操作（SSHコマンド）",[436,760,761],{"id":761},"ハードディスクのフォーマットとパーティション設定",[13,763,764],{},"次に、HDDケースにHDDを設置して、ラズパイとHDDケースをつなげる。",[13,766,767],{},[19,768],{"alt":769,"src":770},"床で作業している様子","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/raspy.webp",[13,772,773],{},[19,774],{"alt":775,"src":776},"2台目を接続","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/hdd2.webp",[13,778,779,780,782],{},"その後、以下を参考に2つのHDDをマウント。",[44,781],{},[47,783,786],{"href":784,"rel":785},"https://qiita.com/shimanuki-yu/items/cddf7e1d490ad66743f3",[51],"Raspberry PiでHDDをマウントする",[13,788,789,790,793,794,797],{},"_私の場合、メインは ",[147,791,792],{},"/mnt/hdd1"," 、バックアップ用は ",[147,795,796],{},"/mnt/hdd2"," にマウントした。",[13,799,800],{},"これで、ラズパイにOSを入れ、ローカルIPを固定し、HDDをマウントできた。次はImmichの導入。",[429,802,804],{"id":803},"immichのセットアップ","Immichのセットアップ",[140,806,808],{"className":142,"code":807,"language":144,"meta":145,"style":145},"graph\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    style immich-server fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[147,809,810,814,818,822,826,830,834,838,842,846,850,854,858,862,866,870,874,878,882,886,890,894,898],{"__ignoreMap":145},[150,811,812],{"class":152,"line":153},[150,813,347],{},[150,815,816],{"class":152,"line":159},[150,817,163],{"emptyLinePlaceholder":162},[150,819,820],{"class":152,"line":166},[150,821,169],{},[150,823,824],{"class":152,"line":172},[150,825,175],{},[150,827,828],{"class":152,"line":178},[150,829,181],{},[150,831,832],{"class":152,"line":184},[150,833,193],{},[150,835,836],{"class":152,"line":190},[150,837,163],{"emptyLinePlaceholder":162},[150,839,840],{"class":152,"line":196},[150,841,204],{},[150,843,844],{"class":152,"line":201},[150,845,210],{},[150,847,848],{"class":152,"line":207},[150,849,216],{},[150,851,852],{"class":152,"line":213},[150,853,193],{},[150,855,856],{"class":152,"line":219},[150,857,163],{"emptyLinePlaceholder":162},[150,859,860],{"class":152,"line":224},[150,861,232],{},[150,863,864],{"class":152,"line":229},[150,865,238],{},[150,867,868],{"class":152,"line":235},[150,869,193],{},[150,871,872],{"class":152,"line":241},[150,873,163],{"emptyLinePlaceholder":162},[150,875,876],{"class":152,"line":246},[150,877,254],{},[150,879,880],{"class":152,"line":251},[150,881,260],{},[150,883,884],{"class":152,"line":257},[150,885,163],{"emptyLinePlaceholder":162},[150,887,888],{"class":152,"line":263},[150,889,271],{},[150,891,892],{"class":152,"line":268},[150,893,277],{},[150,895,896],{"class":152,"line":274},[150,897,163],{"emptyLinePlaceholder":162},[150,899,900],{"class":152,"line":280},[150,901,902],{},"    style immich-server fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[436,904,906],{"id":905},"dockerでのセットアップと設定ファイルの用意","Dockerでのセットアップと設定ファイルの用意",[13,908,909,914],{},[47,910,913],{"href":911,"rel":912},"https://immich.app/docs/overview/quick-start",[51],"公式のクイックスタート","と同じくDockerで立ち上げるのが楽。",[13,916,917,918,921,922,925],{},"なお ",[147,919,920],{},".env"," ファイルのうち写真アップロード先とDB保存先は、先程マウントした ",[147,923,924],{},"hdd1"," にしておく。",[140,927,931],{"className":928,"code":929,"language":930,"meta":145,"style":145},"language-env shiki shiki-themes github-light","UPLOAD_LOCATION=/mnt/hdd1/immich/images\nDB_DATA_LOCATION=/mnt/hdd1/immich/postgres\n","env",[147,932,933,938],{"__ignoreMap":145},[150,934,935],{"class":152,"line":153},[150,936,937],{},"UPLOAD_LOCATION=/mnt/hdd1/immich/images\n",[150,939,940],{"class":152,"line":159},[150,941,942],{},"DB_DATA_LOCATION=/mnt/hdd1/immich/postgres\n",[436,944,946],{"id":945},"immich管理アカウント作成","Immich管理アカウント作成",[13,948,949,950,953,954,959],{},"コンテナ立ち上げが成功すると、 ",[147,951,952],{},"http://\u003Cmachine-ip-address>:2283"," でImmichにアクセスできる。アクセス後は",[47,955,958],{"href":956,"rel":957},"https://immich.app/docs/administration/user-management#register-the-admin-user",[51],"adminユーザの作成","をする",[13,961,962],{},[19,963],{"alt":964,"src":965},"アクセス後の画面","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/create_admin.webp",[13,967,968],{},"一般ユーザアカウントも作成できるので、そのまま私・妻用のアカウントを作った。",[13,970,971],{},"また、ここでStorageTemplateの設定を確認しておくといい👇️",[436,973,975],{"id":974},"storagetemplate",[47,976,979],{"href":977,"rel":978},"https://immich.app/docs/administration/storage-template/",[51],"StorageTemplate",[13,981,982,983,986],{},"写真や動画の保存先・フォルダ構造やファイル名の付け方の設定のこと。私は ",[147,984,985],{},"UPLOAD_LOCATION/library/ユーザ名/2022/2022-02-03/IMAGE_56437.jpg"," のような形式で保存されるようにしている。",[13,988,989,990,993],{},"設定変更以降に追加した写真から反映され、変更前に追加済であったものは、 ",[147,991,992],{},"ジョブ → ストレージテンプレートの移行"," ボタンを押すことで反映可能。",[13,995,996],{},[19,997],{"alt":998,"src":999},"Immich ストレージテンプレートの移行","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/storage_template.png",[13,1001,1002],{},"私の場合、Google フォト から大量の写真を移動してきたあとに設定をしたため、反映にかなりの時間がかかった。好みがあれば予め設定しておけると嬉しい。",[13,1004,1005],{},"ここまでで、ラズパイ・HDD・Immich のセットアップが完了。次は Googleフォト にある写真・動画を Immich に移行する。",[429,1007,1009],{"id":1008},"googleフォトからの移行","Googleフォトからの移行",[140,1011,1013],{"className":142,"code":1012,"language":144,"meta":145,"style":145},"graph\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\nend\n\nGoogleTakeout -->|\"immich-go\"| immich-server\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    %% ノードスタイル\n    style immich-server fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n    style GoogleTakeout fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n    style hdd1 fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n\n    %% 矢印スタイル (index は上から数えた順)\n    %% GoogleTakeout --> immich-server が最初のエッジ (0)\n    %% immich-server --> hdd1 が次のエッジ (1)\n    linkStyle 0 stroke:#008080,stroke-width:4px,color:008080\n    linkStyle 1 stroke:#008080,stroke-width:4px,color:008080\n",[147,1014,1015,1019,1023,1027,1031,1035,1039,1043,1048,1052,1056,1060,1064,1068,1072,1076,1080,1084,1088,1092,1096,1100,1104,1108,1112,1117,1121,1126,1131,1136,1142,1148,1154,1160],{"__ignoreMap":145},[150,1016,1017],{"class":152,"line":153},[150,1018,347],{},[150,1020,1021],{"class":152,"line":159},[150,1022,163],{"emptyLinePlaceholder":162},[150,1024,1025],{"class":152,"line":166},[150,1026,169],{},[150,1028,1029],{"class":152,"line":172},[150,1030,175],{},[150,1032,1033],{"class":152,"line":178},[150,1034,181],{},[150,1036,1037],{"class":152,"line":184},[150,1038,193],{},[150,1040,1041],{"class":152,"line":190},[150,1042,163],{"emptyLinePlaceholder":162},[150,1044,1045],{"class":152,"line":196},[150,1046,1047],{},"GoogleTakeout -->|\"immich-go\"| immich-server\n",[150,1049,1050],{"class":152,"line":201},[150,1051,163],{"emptyLinePlaceholder":162},[150,1053,1054],{"class":152,"line":207},[150,1055,204],{},[150,1057,1058],{"class":152,"line":213},[150,1059,210],{},[150,1061,1062],{"class":152,"line":219},[150,1063,216],{},[150,1065,1066],{"class":152,"line":224},[150,1067,193],{},[150,1069,1070],{"class":152,"line":229},[150,1071,163],{"emptyLinePlaceholder":162},[150,1073,1074],{"class":152,"line":235},[150,1075,232],{},[150,1077,1078],{"class":152,"line":241},[150,1079,238],{},[150,1081,1082],{"class":152,"line":246},[150,1083,193],{},[150,1085,1086],{"class":152,"line":251},[150,1087,163],{"emptyLinePlaceholder":162},[150,1089,1090],{"class":152,"line":257},[150,1091,254],{},[150,1093,1094],{"class":152,"line":263},[150,1095,260],{},[150,1097,1098],{"class":152,"line":268},[150,1099,163],{"emptyLinePlaceholder":162},[150,1101,1102],{"class":152,"line":274},[150,1103,271],{},[150,1105,1106],{"class":152,"line":280},[150,1107,277],{},[150,1109,1110],{"class":152,"line":285},[150,1111,163],{"emptyLinePlaceholder":162},[150,1113,1114],{"class":152,"line":291},[150,1115,1116],{},"    %% ノードスタイル\n",[150,1118,1119],{"class":152,"line":297},[150,1120,902],{},[150,1122,1123],{"class":152,"line":302},[150,1124,1125],{},"    style GoogleTakeout fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[150,1127,1128],{"class":152,"line":308},[150,1129,1130],{},"    style hdd1 fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[150,1132,1134],{"class":152,"line":1133},29,[150,1135,163],{"emptyLinePlaceholder":162},[150,1137,1139],{"class":152,"line":1138},30,[150,1140,1141],{},"    %% 矢印スタイル (index は上から数えた順)\n",[150,1143,1145],{"class":152,"line":1144},31,[150,1146,1147],{},"    %% GoogleTakeout --> immich-server が最初のエッジ (0)\n",[150,1149,1151],{"class":152,"line":1150},32,[150,1152,1153],{},"    %% immich-server --> hdd1 が次のエッジ (1)\n",[150,1155,1157],{"class":152,"line":1156},33,[150,1158,1159],{},"    linkStyle 0 stroke:#008080,stroke-width:4px,color:008080\n",[150,1161,1163],{"class":152,"line":1162},34,[150,1164,1165],{},"    linkStyle 1 stroke:#008080,stroke-width:4px,color:008080\n",[13,1167,1168,1171],{},[147,1169,1170],{},"immich-go"," を使う。Google フォトの 写真をImmichで管理する保存領域に移行できるコマンドラインツールです。",[13,1173,1174],{},"必要な材料👇️",[57,1176,1177,1179,1187],{},[60,1178,1170],{},[60,1180,1181,1182],{},"Google Takeout\n",[79,1183,1184],{},[60,1185,1186],{},"Google アカウントに保存されているデータをエクスポートしたもの",[60,1188,1189,1190],{},"ユーザアカウントごとのImmich API キー\n",[79,1191,1192],{},[60,1193,1194],{},"Immichに対してアプリケーション外から操作をする際に必要な鍵",[13,1196,1197],{},"具体的には、",[140,1199,1203],{"className":1200,"code":1201,"language":1202,"meta":145,"style":145},"language-sh shiki shiki-themes github-light","./immich-go -server=http://\u003Cmachine-ip-address>:2283 -key=\u003CImmichで作成したAPI キー> upload -create-albums -google-photos \u003CダウンロードしたGoogle Photo Takeout のパス>\n","sh",[147,1204,1205],{"__ignoreMap":145},[150,1206,1207],{"class":152,"line":153},[150,1208,1201],{},[13,1210,1211],{},"とすることで、Googleから落としてきたコンテンツをImmichの任意ユーザのコンテンツとして取り込むことができる。",[436,1213,1214],{"id":1214},"写真の重複",[13,1216,1217],{},"バックアップ前に“写真がどこにあるか”を整理しておく必要がある。過去のすべての写真がスマホに入っていれば Immich のモバイルアプリを起動して、スマホからバックアップするだけでOK。",[13,1219,1220],{},"しかし実際には「Googleフォトだけにある写真」「スマホだけにある写真」「両方にある写真」が混在している。",[140,1222,1226],{"className":1223,"code":1224,"language":1225,"meta":145,"style":145},"language-ascii shiki shiki-themes github-light","// Google フォトに保存された写真と、スマホに保存された写真が一部重なってるイメージ\n時系列:      2008 ------2017-------2023----------> 新しい\n\nGoogleフォト: [===========++++++++++]\nスマホ       :           [++++++++++==========]\n","ascii",[147,1227,1228,1233,1238,1242,1247],{"__ignoreMap":145},[150,1229,1230],{"class":152,"line":153},[150,1231,1232],{},"// Google フォトに保存された写真と、スマホに保存された写真が一部重なってるイメージ\n",[150,1234,1235],{"class":152,"line":159},[150,1236,1237],{},"時系列:      2008 ------2017-------2023----------> 新しい\n",[150,1239,1240],{"class":152,"line":166},[150,1241,163],{"emptyLinePlaceholder":162},[150,1243,1244],{"class":152,"line":172},[150,1245,1246],{},"Googleフォト: [===========++++++++++]\n",[150,1248,1249],{"class":152,"line":178},[150,1250,1251],{},"スマホ       :           [++++++++++==========]\n",[13,1253,1254],{},"同じ写真がバックアップされてしまうと、容量がもったいない。",[13,1256,1257],{},"今回は、2008〜2023年は Google フォトから移行し、それ以降はスマホから直接バックアップすることにした。",[13,1259,1260],{},"厳密に分けることは難しく2024年前後に重複が発生するが、Immich には重複検出・削除機能があるため、多少は許容範囲。",[13,1262,1263],{},[19,1264],{"alt":1265,"src":1266},"Immichの重複検出・削除機能","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/duplicate_delete.gif",[436,1268,1269],{"id":1170},[47,1270,1170],{"href":1271,"rel":1272},"https://github.com/simulot/immich-go",[51],[13,1274,1275,1276,1279,1280,1283],{},"immich-go をダウンロードする。 ",[147,1277,1278],{},"\u003C> Code"," 押下 > ",[147,1281,1282],{},"Download ZIP"," でOK。",[13,1285,1286],{},[19,1287],{"alt":1288,"src":1289},"immich-goのリポジトリ","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/immich-go.webp",[13,1291,1292],{},"PC内の好きな場所においておく。",[436,1294,1296],{"id":1295},"google-takeout","Google Takeout",[13,1298,1299,1300],{},"以下のリンクから Google Takeout にアクセスして、エクスポートする。\n",[47,1301,1302],{"href":1302,"rel":1303},"https://takeout.google.com/",[51],[13,1305,1306,1307,1310],{},"Google フォトのみチェックボックスをONにして ",[147,1308,1309],{},"次のステップ"," を押下",[13,1312,1313],{},[19,1314],{"alt":1315,"src":1316},"Google データ エクスポート","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/takeout_export.webp",[13,1318,1319,1310],{},[147,1320,1321],{},"エクスポートを作成",[13,1323,1324],{},[19,1325],{"alt":1326,"src":1327},"export.png","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/export.webp",[13,1329,1330],{},"しばらく待つとGoogleからメールが届く",[13,1332,1333],{},[19,1334],{"alt":1335,"src":1336},"Googleから届くメール","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/mail.webp",[13,1338,1339],{},"メール内リンクに飛ぶと、件数ごとにダウンロードボタンが設置されている。順次押下してダウンロードしていけばOK。zipファイルがダウンロードされるはず。",[13,1341,1342],{},[19,1343],{"alt":1344,"src":1345},"download.png","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/download.webp",[13,1347,1348],{},"件数が多すぎて面倒であれば、エクスポート前にファイルサイズを大きめに設定しておくといい。",[436,1350,1352],{"id":1351},"immich-api-キー","Immich API キー",[13,1354,1355,1356,1359,1360,1362],{},"お次に ",[147,1357,1358],{},"API キー"," を発行する。",[147,1361,1170],{}," から Immich のユーザアカウントに対して操作する際に必要な鍵。ユーザアカウント事に発行する。",[13,1364,1365],{},"手順",[57,1367,1368,1371,1374,1377,1380,1383],{},[60,1369,1370],{},"Immichにログイン",[60,1372,1373],{},"アカウント設定",[60,1375,1376],{},"APIキー",[60,1378,1379],{},"新しいAPIキー",[60,1381,1382],{},"任意の名前をつけて作成押下",[60,1384,1385],{},"新しいキーが発行されるのでコピーしておく",[13,1387,1388],{},[19,1389],{"alt":1390,"src":1391},"apiキーの作成","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/api-key.webp",[436,1393,1394],{"id":1394},"immich-goで移行",[13,1396,1397,1398,1400],{},"コマンドを実行する前に、",[147,1399,1296],{}," の zip を解凍して中身を確認する。今回は 2024年以降の写真はスマホからバックアップする方針のため、その期間を含む zip は不要。使用しないファイルはどこかに移動しておく",[13,1402,1403,1404,1406],{},"必要な zip ファイルを準備ができたら、 ",[147,1405,1170],{}," をダウンロードしたディレクトリへ移動して、次のコマンドを実行。",[140,1408,1410],{"className":1200,"code":1409,"language":1202,"meta":145,"style":145},"./immich-go -server=http://\u003Cmachine-ip-address>:2283 -key=\u003CImmichで作成したAPI キー> upload -create-albums -google-photos /takeoutがあるディレクトリ名/takeout-*.zip\n",[147,1411,1412],{"__ignoreMap":145},[150,1413,1414],{"class":152,"line":153},[150,1415,1409],{},[13,1417,917,1418,1421],{},[147,1419,1420],{},"--dry-run"," オプションをつけることで、実行される処理を事前に確認できる。",[13,1423,1424],{},"コマンド実行後、しばらく待てば Immich に画像や動画が取り込まれている。私のアカウントは写真が多かったためコマンドを実行して寝た🛌。翌朝には終わっていた。",[429,1426,1427],{"id":1427},"モバイルアプリの設定",[13,1429,1430],{},"次に Immich モバイルアプリをダウンロードしてセッティング。",[140,1432,1434],{"className":142,"code":1433,"language":144,"meta":145,"style":145},"graph\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    style mobile_in_lan fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[147,1435,1436,1440,1444,1448,1452,1456,1460,1464,1468,1472,1476,1480,1484,1488,1492,1496,1500,1504,1508,1512,1516,1520,1524],{"__ignoreMap":145},[150,1437,1438],{"class":152,"line":153},[150,1439,347],{},[150,1441,1442],{"class":152,"line":159},[150,1443,163],{"emptyLinePlaceholder":162},[150,1445,1446],{"class":152,"line":166},[150,1447,169],{},[150,1449,1450],{"class":152,"line":172},[150,1451,175],{},[150,1453,1454],{"class":152,"line":178},[150,1455,181],{},[150,1457,1458],{"class":152,"line":184},[150,1459,193],{},[150,1461,1462],{"class":152,"line":190},[150,1463,163],{"emptyLinePlaceholder":162},[150,1465,1466],{"class":152,"line":196},[150,1467,204],{},[150,1469,1470],{"class":152,"line":201},[150,1471,210],{},[150,1473,1474],{"class":152,"line":207},[150,1475,216],{},[150,1477,1478],{"class":152,"line":213},[150,1479,193],{},[150,1481,1482],{"class":152,"line":219},[150,1483,163],{"emptyLinePlaceholder":162},[150,1485,1486],{"class":152,"line":224},[150,1487,232],{},[150,1489,1490],{"class":152,"line":229},[150,1491,238],{},[150,1493,1494],{"class":152,"line":235},[150,1495,193],{},[150,1497,1498],{"class":152,"line":241},[150,1499,163],{"emptyLinePlaceholder":162},[150,1501,1502],{"class":152,"line":246},[150,1503,254],{},[150,1505,1506],{"class":152,"line":251},[150,1507,260],{},[150,1509,1510],{"class":152,"line":257},[150,1511,163],{"emptyLinePlaceholder":162},[150,1513,1514],{"class":152,"line":263},[150,1515,271],{},[150,1517,1518],{"class":152,"line":268},[150,1519,277],{},[150,1521,1522],{"class":152,"line":274},[150,1523,163],{"emptyLinePlaceholder":162},[150,1525,1526],{"class":152,"line":280},[150,1527,1528],{},"    style mobile_in_lan fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[13,1530,1531,1532,1534],{},"ダウンロード・ログイン・バックアップ、すべて以下のドキュメントに従えば無問題️",[44,1533],{},[47,1535,1536],{"href":1536,"rel":1537},"https://immich.app/docs/features/mobile-app/",[51],[13,1539,1540,1541,1543],{},"アプリ起動直後は、 ",[147,1542,952],{}," でアクセス",[13,1545,1546],{},[19,1547],{"alt":1548,"src":1549},"Immichモバイルアプリ起動直後","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/mobile_app_boot.webp",[13,1551,1552],{},"作成したユーザのメールアドレスとパスワードを打ち込めばログイン可能",[13,1554,1555],{},[19,1556],{"alt":1557,"src":1558},"ログイン画面","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/mobile_app_login.png",[13,1560,1561,1562,1564],{},"次にスマホのローカルに入っている写真・動画のバックアップ設定を行う",[44,1563],{},[47,1565,1566],{"href":1566,"rel":1567},"https://immich.app/docs/features/mobile-app/#backup",[51],[13,1569,1570,1571,1573],{},"自動バックアップ設定もしておくと良い",[44,1572],{},[47,1574,1575],{"href":1575,"rel":1576},"https://immich.app/docs/features/automatic-backup",[51],[13,1578,1579],{},"これで、スマホで取った写真をImmich経由でHDDに保存し、そのまま閲覧できるようになる。",[13,1581,1582],{},[19,1583],{"alt":1584,"src":1585},"Immichモバイルアプリ タイムラインの様子","/images/articles/raspi-immich-home-photos/goal1-unlimited-storage/mobile_app_timeline.png",[429,1587,1589],{"id":1588},"hdd1をバックアップする","HDD1をバックアップする",[13,1591,1592],{},"最後にHDD1のデータをHDD2にバックアップするよう設定したい。HDD1がだめになったらすべての資産が消えてしまうので",[140,1594,1596],{"className":142,"code":1595,"language":144,"meta":145,"style":145},"graph\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    %% ノードスタイル\n    style hdd1 fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n    style hdd2 fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[147,1597,1598,1602,1606,1610,1614,1618,1622,1626,1630,1634,1638,1642,1646,1650,1654,1658,1662,1666,1670,1674,1678,1682,1686,1690,1694],{"__ignoreMap":145},[150,1599,1600],{"class":152,"line":153},[150,1601,347],{},[150,1603,1604],{"class":152,"line":159},[150,1605,163],{"emptyLinePlaceholder":162},[150,1607,1608],{"class":152,"line":166},[150,1609,169],{},[150,1611,1612],{"class":152,"line":172},[150,1613,175],{},[150,1615,1616],{"class":152,"line":178},[150,1617,181],{},[150,1619,1620],{"class":152,"line":184},[150,1621,193],{},[150,1623,1624],{"class":152,"line":190},[150,1625,163],{"emptyLinePlaceholder":162},[150,1627,1628],{"class":152,"line":196},[150,1629,204],{},[150,1631,1632],{"class":152,"line":201},[150,1633,210],{},[150,1635,1636],{"class":152,"line":207},[150,1637,216],{},[150,1639,1640],{"class":152,"line":213},[150,1641,193],{},[150,1643,1644],{"class":152,"line":219},[150,1645,163],{"emptyLinePlaceholder":162},[150,1647,1648],{"class":152,"line":224},[150,1649,232],{},[150,1651,1652],{"class":152,"line":229},[150,1653,238],{},[150,1655,1656],{"class":152,"line":235},[150,1657,193],{},[150,1659,1660],{"class":152,"line":241},[150,1661,163],{"emptyLinePlaceholder":162},[150,1663,1664],{"class":152,"line":246},[150,1665,254],{},[150,1667,1668],{"class":152,"line":251},[150,1669,260],{},[150,1671,1672],{"class":152,"line":257},[150,1673,163],{"emptyLinePlaceholder":162},[150,1675,1676],{"class":152,"line":263},[150,1677,271],{},[150,1679,1680],{"class":152,"line":268},[150,1681,277],{},[150,1683,1684],{"class":152,"line":274},[150,1685,163],{"emptyLinePlaceholder":162},[150,1687,1688],{"class":152,"line":280},[150,1689,1116],{},[150,1691,1692],{"class":152,"line":285},[150,1693,1130],{},[150,1695,1696],{"class":152,"line":291},[150,1697,1698],{},"    style hdd2 fill:#E6FFFA,stroke:#008080,stroke-width:3px,color:black\n",[13,1700,1701,1706,1707,1710,1711,1716],{},[47,1702,1705],{"href":1703,"rel":1704},"https://www.borgbackup.org",[51],"Borg"," を使う。差分バックアップツール。\nImmich公式でも ",[147,1708,1709],{},"borg"," による",[47,1712,1715],{"href":1713,"rel":1714},"https://immich.app/docs/guides/template-backup-script/",[51],"バックアップ方法","が紹介されているため採用。",[13,1718,1719,1720,1723,1724,1727],{},"手順は公式ドキュメントに従う。ドキュメント中の “Borg backup template” をベースにしたスクリプトを",[147,1721,1722],{},"immich-borg.sh","として保存し、毎週土曜の午前1:00に実行されるよう",[147,1725,1726],{},"crontab","を設定。",[140,1729,1733],{"className":1730,"code":1731,"language":1732,"meta":145,"style":145},"language-cron shiki shiki-themes github-light","0 1 * * 6 /immich-borg.sh\n","cron",[147,1734,1735],{"__ignoreMap":145},[150,1736,1737],{"class":152,"line":153},[150,1738,1731],{},[429,1740,1742],{"id":1741},"done","Done",[13,1744,1745],{},"これで、スマホから Immich にログインして、撮影した写真や動画をそのまま HDD にバックアップできる環境が整った。\n当初の条件もクリア",[79,1747,1750,1759,1765,1771],{"className":1748},[1749],"contains-task-list",[60,1751,1754,1758],{"className":1752},[1753],"task-list-item",[1755,1756],"input",{"checked":162,"disabled":162,"type":1757},"checkbox"," 1. 事実上、無限に写真と動画が保存できること",[60,1760,1762,1764],{"className":1761},[1753],[1755,1763],{"checked":162,"disabled":162,"type":1757}," 2. スマホから保存・閲覧できること",[60,1766,1768,1770],{"className":1767},[1753],[1755,1769],{"checked":162,"disabled":162,"type":1757}," 3. サブスクはしないこと",[60,1772,1774,1776],{"className":1773},[1753],[1755,1775],{"checked":162,"disabled":162,"type":1757}," 4. Google フォトに保存した大量のコンテンツを引き継げること",[13,1778,1779,1780,1790],{},"週に一度は別のHDDにもバックアップを行う",[1781,1782,1783],"sup",{},[47,1784,1789],{"href":1785,"ariaDescribedBy":1786,"dataFootnoteRef":145,"id":1788},"#user-content-fn-fn:1",[1787],"footnote-label","user-content-fnref-fn:1","1","。",[13,1792,1793],{},"加えて Immich のアルバム機能を使えば、「息子用アルバム」や「旅行用アルバム」を作成し、私と妻がそれぞれ写真を追加できる。これまで Google フォトや LINE で行っていたスタイルも実現できる。",[13,1795,1796],{},"これにて、フォトストレージの構築はクリア。家庭内の写真管理は解決した。",[37,1798,1800],{"id":1799},"ゴール2-遠隔地の家族に安全に写真をシェアする","ゴール2: 遠隔地の家族に安全に写真をシェアする",[13,1802,1803,1804,1806],{},"次の課題は両親への共有。",[44,1805],{},"\nいままで私は LINE で親に写真を送っていた。が、結構面倒...😇\n『一箇所にまとめておけば、好きなときに見てもらえる仕組み』がほしい。",[13,1808,1809],{},"幸いImmichであれば複数アカウントが作成できる。アルバム機能もあり、アルバム事に権限管理も可。\n親用のアカウントを作り、両親はアプリを開いてアルバムをタップすれば、愛孫のかわいい〜👶写真を眺めることができるのでは🤔",[13,1811,1812],{},[19,1813],{"alt":1814,"src":1815},"アルバム機能","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/album.webp",[13,1817,1818],{},"しかし、自宅ホストのサーバである以上、外部からの安全なアクセス手段が必要。",[13,1820,1821,1822,1825],{},"この課題を解決するために、 ",[147,1823,1824],{},"Cloudflare Tunnel"," を使う。",[429,1827,1829],{"id":1828},"cloudflare-tunnel-cloudflare-access","Cloudflare Tunnel × Cloudflare Access",[13,1831,1832,1836,1837,1840],{},[47,1833,1824],{"href":1834,"rel":1835},"https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/",[51],"は、軽量ツール（",[147,1838,1839],{},"cloudflared","）をサーバに入れることで公開IPやポート開放なしに外部公開できるもの。通信はCloudflareを経由する。",[13,1842,1843,1844,1849],{},"2023年6月ごろに ",[47,1845,1848],{"href":1846,"rel":1847},"https://discord.com/channels/979116623879368755/1122615710846308484",[51],"Immich公式Discord"," に「どうやってインターネットに公開するのがよいか？」という議論があり、一定数のユーザーが Cloudflare Tunnel を採用していると述べている。",[13,1851,1852,1853,1856],{},"更に、",[147,1854,1855],{},"Cloudflare Access"," による認証を組み合わせれば限定公開も容易。",[13,1858,1859],{},"なお、100MB以上のファイルをアップロードする際には制限があるので注意が必要（今回は読み込みオンリーなので問題はなし）",[429,1861,1863],{"id":1862},"完成図cloudflare","完成図（Cloudflare）",[140,1865,1867],{"className":142,"code":1866,"language":144,"meta":145,"style":145},"graph LR\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\n    cloudflared\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    cloudflared \u003C--> immich-server\n    cloudflared \u003C--> |\"Cloudflare Tunnel\"|cloudflare[\"Cloudflare\"]\n\n    cloudflare \u003C--> |\"サービストークン\"|mobile[\"Mobile App\"]\n    cloudflare \u003C--> |\"ワンタイムパスワード / SSO認証\"|web[\"Web App\"]\n\n    style cloudflared stroke:#008080,stroke-width:3px\n    style cloudflare stroke:#008080,stroke-width:3px\n    style mobile stroke:#008080,stroke-width:3px\n    style web stroke:#008080,stroke-width:3px\n\n    linkStyle 5 stroke:#008080,stroke-width:3px\n    linkStyle 6 stroke:#008080,stroke-width:3px\n    linkStyle 7 stroke:#008080,stroke-width:3px\n",[147,1868,1869,1873,1877,1881,1885,1889,1893,1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957,1961,1965,1969,1973,1977,1981,1985,1990,1995,2000,2005,2009,2015,2021],{"__ignoreMap":145},[150,1870,1871],{"class":152,"line":153},[150,1872,156],{},[150,1874,1875],{"class":152,"line":159},[150,1876,163],{"emptyLinePlaceholder":162},[150,1878,1879],{"class":152,"line":166},[150,1880,169],{},[150,1882,1883],{"class":152,"line":172},[150,1884,175],{},[150,1886,1887],{"class":152,"line":178},[150,1888,181],{},[150,1890,1891],{"class":152,"line":184},[150,1892,187],{},[150,1894,1895],{"class":152,"line":190},[150,1896,193],{},[150,1898,1899],{"class":152,"line":196},[150,1900,163],{"emptyLinePlaceholder":162},[150,1902,1903],{"class":152,"line":201},[150,1904,204],{},[150,1906,1907],{"class":152,"line":207},[150,1908,210],{},[150,1910,1911],{"class":152,"line":213},[150,1912,216],{},[150,1914,1915],{"class":152,"line":219},[150,1916,193],{},[150,1918,1919],{"class":152,"line":224},[150,1920,163],{"emptyLinePlaceholder":162},[150,1922,1923],{"class":152,"line":229},[150,1924,232],{},[150,1926,1927],{"class":152,"line":235},[150,1928,238],{},[150,1930,1931],{"class":152,"line":241},[150,1932,193],{},[150,1934,1935],{"class":152,"line":246},[150,1936,163],{"emptyLinePlaceholder":162},[150,1938,1939],{"class":152,"line":251},[150,1940,254],{},[150,1942,1943],{"class":152,"line":257},[150,1944,260],{},[150,1946,1947],{"class":152,"line":263},[150,1948,163],{"emptyLinePlaceholder":162},[150,1950,1951],{"class":152,"line":268},[150,1952,271],{},[150,1954,1955],{"class":152,"line":274},[150,1956,277],{},[150,1958,1959],{"class":152,"line":280},[150,1960,163],{"emptyLinePlaceholder":162},[150,1962,1963],{"class":152,"line":285},[150,1964,288],{},[150,1966,1967],{"class":152,"line":291},[150,1968,294],{},[150,1970,1971],{"class":152,"line":297},[150,1972,163],{"emptyLinePlaceholder":162},[150,1974,1975],{"class":152,"line":302},[150,1976,305],{},[150,1978,1979],{"class":152,"line":308},[150,1980,311],{},[150,1982,1983],{"class":152,"line":1133},[150,1984,163],{"emptyLinePlaceholder":162},[150,1986,1987],{"class":152,"line":1138},[150,1988,1989],{},"    style cloudflared stroke:#008080,stroke-width:3px\n",[150,1991,1992],{"class":152,"line":1144},[150,1993,1994],{},"    style cloudflare stroke:#008080,stroke-width:3px\n",[150,1996,1997],{"class":152,"line":1150},[150,1998,1999],{},"    style mobile stroke:#008080,stroke-width:3px\n",[150,2001,2002],{"class":152,"line":1156},[150,2003,2004],{},"    style web stroke:#008080,stroke-width:3px\n",[150,2006,2007],{"class":152,"line":1162},[150,2008,163],{"emptyLinePlaceholder":162},[150,2010,2012],{"class":152,"line":2011},35,[150,2013,2014],{},"    linkStyle 5 stroke:#008080,stroke-width:3px\n",[150,2016,2018],{"class":152,"line":2017},36,[150,2019,2020],{},"    linkStyle 6 stroke:#008080,stroke-width:3px\n",[150,2022,2024],{"class":152,"line":2023},37,[150,2025,2026],{},"    linkStyle 7 stroke:#008080,stroke-width:3px\n",[429,2028,2030],{"id":2029},"cloudflare-registry-でドメインを取得する","Cloudflare Registry でドメインを取得する",[13,2032,2033,2034,2039,2040,2043],{},"Cloudflareにサインアップし、",[47,2035,2038],{"href":2036,"rel":2037},"https://dash.cloudflare.com/login",[51],"ダッシュボード","から ",[147,2041,2042],{},"ドメインの登録 > ドメイン登録"," に遷移して任意のドメインを取得。\n（取得しなくてもいい）",[429,2045,2046],{"id":2046},"tunnelの作成",[13,2048,2049],{},"ドメインの購入が完了したらトンネルを作成。",[436,2051,1365],{"id":1365},[57,2053,2054,2058,2063,2068,2073,2078],{},[60,2055,2056],{},[147,2057,2038],{},[60,2059,2060],{},[147,2061,2062],{},"サイドメニュー",[60,2064,2065],{},[147,2066,2067],{},"Zero Trust",[60,2069,2070],{},[147,2071,2072],{},"ネットワーク",[60,2074,2075],{},[147,2076,2077],{},"Tunnels",[60,2079,2080],{},[147,2081,2082],{},"トンネルを作成する",[13,2084,2085],{},[19,2086],{"alt":2087,"src":2088},"Cloudflare Zero Trustの管理画面","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/cloudflare_zero.webp",[57,2090,2091,2096,2101],{},[60,2092,2093],{},[147,2094,2095],{},"Cloudflaredを選択する",[60,2097,2098],{},[147,2099,2100],{},"任意の名前をつけて保存",[60,2102,2103],{},[147,2104,2105],{},"次へ",[13,2107,2108],{},[19,2109],{"alt":2110,"src":2111},"トンネルの作成","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/create_tunnel.webp",[13,2113,2114,2117],{},[147,2115,2116],{},"Debian"," を選択して、表示されるコマンドをサーバで実行。",[13,2119,2120],{},[19,2121],{"alt":2122,"src":2123},"Cloudflare Tunnel コネクタのインストール・実行","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/connector.webp",[13,2125,2126],{},"サーバ側でのコマンドが成功すると、このようにコネクタIDと接続済みステータスが表示されるので次へ押下",[13,2128,2129],{},[19,2130],{"alt":2131,"src":2132},"コネクタ接続完了","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/connector_created.png",[13,2134,2135],{},"以下を入力して保存を押下",[79,2137,2138,2141,2144,2147],{},[60,2139,2140],{},"サブドメイン: 任意の名前",[60,2142,2143],{},"ドメイン: Cloudflareで購入したドメインがプルダウンで表示されるため選択",[60,2145,2146],{},"サービス: HTTP",[60,2148,2149],{},"URL: localhost:2283",[13,2151,2152],{},[19,2153],{"alt":2154,"src":2155},"トンネルのパブリックホスト名を入力","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/public_host.png",[13,2157,2158],{},"これで、Cloudflare経由で外部公開できた。設定したURLを打ち込むことで、アクセス可能となっているはず。",[429,2160,2162],{"id":2161},"cloudflare-accessで認証機能を追加する","Cloudflare Accessで認証機能を追加する",[13,2164,2165],{},"しかし、アクセス制限がついてなくて危険なので設定していく。",[436,2167,2169],{"id":2168},"webブラウザからの認証","Webブラウザからの認証",[140,2171,2173],{"className":142,"code":2172,"language":144,"meta":145,"style":145},"  graph LR\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\n    cloudflared\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    cloudflared \u003C--> immich-server\n    cloudflared \u003C--> |\"Cloudflare Tunnel\"|cloudflare[\"Cloudflare\"]\n\n    cloudflare \u003C--> |\"サービストークン\"|mobile[\"Mobile App\"]\n    cloudflare \u003C--> |\"ワンタイムパスワード / SSO認証\"|web[\"Web App\"]\n\n    style cloudflared fill:#008080,stroke:#008080,stroke-width:3px,color:white\n    style cloudflare fill:#008080,stroke:#008080,stroke-width:3px,color:white\n    style web fill:#008080,stroke:#008080,stroke-width:3px,color:white\n\n    linkStyle 5 stroke:#008080,stroke-width:3px\n    linkStyle 7 stroke:#008080,stroke-width:3px\n",[147,2174,2175,2180,2184,2188,2192,2196,2200,2204,2208,2212,2216,2220,2224,2228,2232,2236,2240,2244,2248,2252,2256,2260,2264,2268,2272,2276,2280,2284,2288,2292,2297,2302,2307,2311,2315],{"__ignoreMap":145},[150,2176,2177],{"class":152,"line":153},[150,2178,2179],{},"  graph LR\n",[150,2181,2182],{"class":152,"line":159},[150,2183,163],{"emptyLinePlaceholder":162},[150,2185,2186],{"class":152,"line":166},[150,2187,169],{},[150,2189,2190],{"class":152,"line":172},[150,2191,175],{},[150,2193,2194],{"class":152,"line":178},[150,2195,181],{},[150,2197,2198],{"class":152,"line":184},[150,2199,187],{},[150,2201,2202],{"class":152,"line":190},[150,2203,193],{},[150,2205,2206],{"class":152,"line":196},[150,2207,163],{"emptyLinePlaceholder":162},[150,2209,2210],{"class":152,"line":201},[150,2211,204],{},[150,2213,2214],{"class":152,"line":207},[150,2215,210],{},[150,2217,2218],{"class":152,"line":213},[150,2219,216],{},[150,2221,2222],{"class":152,"line":219},[150,2223,193],{},[150,2225,2226],{"class":152,"line":224},[150,2227,163],{"emptyLinePlaceholder":162},[150,2229,2230],{"class":152,"line":229},[150,2231,232],{},[150,2233,2234],{"class":152,"line":235},[150,2235,238],{},[150,2237,2238],{"class":152,"line":241},[150,2239,193],{},[150,2241,2242],{"class":152,"line":246},[150,2243,163],{"emptyLinePlaceholder":162},[150,2245,2246],{"class":152,"line":251},[150,2247,254],{},[150,2249,2250],{"class":152,"line":257},[150,2251,260],{},[150,2253,2254],{"class":152,"line":263},[150,2255,163],{"emptyLinePlaceholder":162},[150,2257,2258],{"class":152,"line":268},[150,2259,271],{},[150,2261,2262],{"class":152,"line":274},[150,2263,277],{},[150,2265,2266],{"class":152,"line":280},[150,2267,163],{"emptyLinePlaceholder":162},[150,2269,2270],{"class":152,"line":285},[150,2271,288],{},[150,2273,2274],{"class":152,"line":291},[150,2275,294],{},[150,2277,2278],{"class":152,"line":297},[150,2279,163],{"emptyLinePlaceholder":162},[150,2281,2282],{"class":152,"line":302},[150,2283,305],{},[150,2285,2286],{"class":152,"line":308},[150,2287,311],{},[150,2289,2290],{"class":152,"line":1133},[150,2291,163],{"emptyLinePlaceholder":162},[150,2293,2294],{"class":152,"line":1138},[150,2295,2296],{},"    style cloudflared fill:#008080,stroke:#008080,stroke-width:3px,color:white\n",[150,2298,2299],{"class":152,"line":1144},[150,2300,2301],{},"    style cloudflare fill:#008080,stroke:#008080,stroke-width:3px,color:white\n",[150,2303,2304],{"class":152,"line":1150},[150,2305,2306],{},"    style web fill:#008080,stroke:#008080,stroke-width:3px,color:white\n",[150,2308,2309],{"class":152,"line":1156},[150,2310,163],{"emptyLinePlaceholder":162},[150,2312,2313],{"class":152,"line":1162},[150,2314,2014],{},[150,2316,2317],{"class":152,"line":2011},[150,2318,2026],{},[13,2320,2321],{},"まずはLAN外からブラウザで Immich へアクセスしたときに、Email認証ができるようにを設定。",[13,2323,2324],{},"ポリシーの追加画面に移動",[57,2326,2327,2332,2337],{},[60,2328,2329],{},[147,2330,2331],{},"Access",[60,2333,2334],{},[147,2335,2336],{},"ポリシー",[60,2338,2339],{},[147,2340,2341],{},"ポリシーを追加する",[13,2343,2344],{},[19,2345],{"alt":2346,"src":2347},"ポリシーの追加","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/policy.webp",[13,2349,2350],{},"お次にポリシーを設定",[57,2352,2353,2356,2359,2362],{},[60,2354,2355],{},"ポリシー名に任意の名前を設定",[60,2357,2358],{},"セレクターで Emails を選択",[60,2360,2361],{},"認証時にSSO対象となるメールアドレスを追加する",[60,2363,2364],{},"保存",[13,2366,2367],{},[19,2368],{"alt":2369,"src":2370},"ポリシーを追加","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_policy.png",[13,2372,2373],{},"以下のように追加される",[13,2375,2376],{},[19,2377],{"alt":2378,"src":2379},"作成されたポリシー","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/created_policy.png",[13,2381,2382],{},"続いて、作成したポリシーをアプリケーションに設定する。",[57,2384,2385,2389,2393],{},[60,2386,2387],{},[147,2388,2331],{},[60,2390,2391],{},[147,2392,438],{},[60,2394,2395],{},[147,2396,2397],{},"アプリケーションを追加する",[13,2399,2400],{},[19,2401],{"alt":2402,"src":2403},"アプリケーションの追加","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_app.png",[13,2405,2406],{},"次にアプリケーションの種類を選ぶ",[57,2408,2409,2414],{},[60,2410,2411],{},[147,2412,2413],{},"セルフホスト",[60,2415,2416],{},[147,2417,2418],{},"選択する",[13,2420,2421],{},[19,2422],{"alt":2423,"src":2424},"アプリケーションの種類を選択","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/app_self_host.png",[13,2426,2427],{},"アプリケーションの情報を入力",[57,2429,2430,2433,2436,2439],{},[60,2431,2432],{},"任意のアプリケーション名を追加",[60,2434,2435],{},"パブリックホスト名を追加をクリック > パブリックホストの入力欄が出てくる",[60,2437,2438],{},"サブドメイン・ドメインは先程のTunnelと同様のものを入力",[60,2440,2441,2442,1310],{},"Access ポリシー欄で、 ",[147,2443,2444],{},"既存のポリシーを選択",[13,2446,2447],{},[19,2448],{"alt":2449,"src":2450},"アプリケーション情報の入力画面","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_app_info.webp",[57,2452,2453,2456],{},[60,2454,2455],{},"先ほど作成したポリシーがでてくるのでチェックして確認",[60,2457,2458],{},"次へ で進んでいくと、保存ボタンが出てくるので保存",[13,2460,2461],{},[19,2462],{"alt":2463,"src":2464},"作済みのポリシーが表示される","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_app_policy.png",[13,2466,2467],{},"以上。再び、設定したURLにブラウザでアクセスしてみると、SSO認証画面が表示されるはず",[13,2469,2470],{},[19,2471],{"alt":2472,"src":2473},"Cloudflareの認証画面","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/web_auth.png",[13,2475,2476],{},"ポリシーに追加した Email を入力すればメールが届き、メールに書いてあるパスコードを入力することで認証を突破できる。突破後はImmichのログイン画面に遷移する。（画像ではGoogle のOAuthでも認証できるようにしている）",[13,2478,2479],{},[19,2480],{"alt":2481,"src":2482},"パスコード入力画面","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/web_one_time_code.png",[436,2484,2485],{"id":2485},"モバイルアプリからの認証",[140,2487,2489],{"className":142,"code":2488,"language":144,"meta":145,"style":145},"graph LR\n\nsubgraph lan[\"LAN\"]\nsubgraph rapy[\"Raspberry Pi 4\"]\n    immich-server\n    cloudflared\nend\n\nsubgraph hdds[\"HDDケース\"]\n    hdd1\n    hdd2\nend\n\nweb_in_lan\nmobile_in_lan\nend\n\n    immich-server -->|\"DB / 写真\"| hdd1[\"HDD 1\"]\n    hdd1 -->|\"バックアップ\"| hdd2[\"HDD 2\"]\n\n    mobile_in_lan[\"Mobile App\"] \u003C--> immich-server\n    web_in_lan[\"Web App\"] \u003C--> immich-server\n\n    cloudflared \u003C--> immich-server\n    cloudflared \u003C--> |\"Cloudflare Tunnel\"|cloudflare[\"Cloudflare\"]\n\n    cloudflare \u003C--> |\"サービストークン\"|mobile[\"Mobile App\"]\n    cloudflare \u003C--> |\"ワンタイムパスワード / SSO認証\"|web[\"Web App\"]\n\n    style cloudflared fill:#008080,stroke:#008080,stroke-width:3px,color:white\n    style cloudflare fill:#008080,stroke:#008080,stroke-width:3px,color:white\n    style mobile fill:#008080,stroke:#008080,stroke-width:3px,color:white\n\n    linkStyle 5 stroke:#008080,stroke-width:3px\n    linkStyle 6 stroke:#008080,stroke-width:3px\n",[147,2490,2491,2495,2499,2503,2507,2511,2515,2519,2523,2527,2531,2535,2539,2543,2547,2551,2555,2559,2563,2567,2571,2575,2579,2583,2587,2591,2595,2599,2603,2607,2611,2615,2620,2624,2628],{"__ignoreMap":145},[150,2492,2493],{"class":152,"line":153},[150,2494,156],{},[150,2496,2497],{"class":152,"line":159},[150,2498,163],{"emptyLinePlaceholder":162},[150,2500,2501],{"class":152,"line":166},[150,2502,169],{},[150,2504,2505],{"class":152,"line":172},[150,2506,175],{},[150,2508,2509],{"class":152,"line":178},[150,2510,181],{},[150,2512,2513],{"class":152,"line":184},[150,2514,187],{},[150,2516,2517],{"class":152,"line":190},[150,2518,193],{},[150,2520,2521],{"class":152,"line":196},[150,2522,163],{"emptyLinePlaceholder":162},[150,2524,2525],{"class":152,"line":201},[150,2526,204],{},[150,2528,2529],{"class":152,"line":207},[150,2530,210],{},[150,2532,2533],{"class":152,"line":213},[150,2534,216],{},[150,2536,2537],{"class":152,"line":219},[150,2538,193],{},[150,2540,2541],{"class":152,"line":224},[150,2542,163],{"emptyLinePlaceholder":162},[150,2544,2545],{"class":152,"line":229},[150,2546,232],{},[150,2548,2549],{"class":152,"line":235},[150,2550,238],{},[150,2552,2553],{"class":152,"line":241},[150,2554,193],{},[150,2556,2557],{"class":152,"line":246},[150,2558,163],{"emptyLinePlaceholder":162},[150,2560,2561],{"class":152,"line":251},[150,2562,254],{},[150,2564,2565],{"class":152,"line":257},[150,2566,260],{},[150,2568,2569],{"class":152,"line":263},[150,2570,163],{"emptyLinePlaceholder":162},[150,2572,2573],{"class":152,"line":268},[150,2574,271],{},[150,2576,2577],{"class":152,"line":274},[150,2578,277],{},[150,2580,2581],{"class":152,"line":280},[150,2582,163],{"emptyLinePlaceholder":162},[150,2584,2585],{"class":152,"line":285},[150,2586,288],{},[150,2588,2589],{"class":152,"line":291},[150,2590,294],{},[150,2592,2593],{"class":152,"line":297},[150,2594,163],{"emptyLinePlaceholder":162},[150,2596,2597],{"class":152,"line":302},[150,2598,305],{},[150,2600,2601],{"class":152,"line":308},[150,2602,311],{},[150,2604,2605],{"class":152,"line":1133},[150,2606,163],{"emptyLinePlaceholder":162},[150,2608,2609],{"class":152,"line":1138},[150,2610,2296],{},[150,2612,2613],{"class":152,"line":1144},[150,2614,2301],{},[150,2616,2617],{"class":152,"line":1150},[150,2618,2619],{},"    style mobile fill:#008080,stroke:#008080,stroke-width:3px,color:white\n",[150,2621,2622],{"class":152,"line":1156},[150,2623,163],{"emptyLinePlaceholder":162},[150,2625,2626],{"class":152,"line":1162},[150,2627,2014],{},[150,2629,2630],{"class":152,"line":2011},[150,2631,2020],{},[13,2633,2634],{},"次に、Immichモバイルアプリからアクセスする方法。モバイルアプリではブラウザのように認証画面に遷移できないため、そのままではログインできない。",[13,2636,2637,2638,2641,2642,2645],{},"そこで Cloudflareの ",[147,2639,2640],{},"Service Token"," と、Immichモバイルアプリの設定 ",[147,2643,2644],{},"カスタムプロキシヘッダ設定"," を活用する。",[13,2647,2648,2650],{},[147,2649,2640],{}," は、アプリやプログラムから Cloudflare の制限されたリソースへとアクセスするための鍵。",[13,2652,2653,2654,2657],{},"Immich モバイルアプリには、サーバへアクセスする際のリクエストに任意の値を含めることができる ",[147,2655,2656],{},"カスタムプロキシヘッダ"," 設定があるため、こちらにトークンを設定することで認証を突破できる。",[436,2659,2661],{"id":2660},"cloudflare上の設定","Cloudflare上の設定",[13,2663,2664],{},"Service Token を作成する",[57,2666,2667,2672,2676,2681],{},[60,2668,2669],{},[147,2670,2671],{},"Cloudflare Zero Trustホーム",[60,2673,2674],{},[147,2675,2331],{},[60,2677,2678],{},[147,2679,2680],{},"サービス認証",[60,2682,2683],{},[147,2684,2685],{},"サービストークンを作成する",[13,2687,2688],{},[19,2689],{"alt":2690,"src":2691},"Service認証画面","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/service_auth.png",[57,2693,2694,2697,2700],{},[60,2695,2696],{},"任意のトークン名を入力",[60,2698,2699],{},"任意の期限を入力",[60,2701,2702],{},"トークンを生成する",[13,2704,2705],{},[19,2706],{"alt":2707,"src":2708},"サービストークン作成画面","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_service_token.png",[13,2710,2711,2714,2715,2718],{},[147,2712,2713],{},"クライアントID"," と ",[147,2716,2717],{},"クライアントシークレット"," が表示されるのでコピーしておく。",[13,2720,2721],{},[19,2722],{"alt":2723,"src":2724},"生成されたトークン","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/created_service_token.png",[13,2726,2727],{},"次に、再びポリシーを作成。セレクターから Service Token を選び、先ほど作成したトークンをプルダウンから選択。",[13,2729,2730],{},[19,2731],{"alt":2732,"src":2733},"セレクターでService Tokenを選択肢、値のフォームをクリックするとプルダウンで作成済みのサービス認証が表示される","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_service_policy.webp",[13,2735,2736],{},"ポリシーを保存し、先ほど作成したアプリケーションにこのポリシーを設定。",[57,2738,2739,2743,2747,2750],{},[60,2740,2741],{},[147,2742,2331],{},[60,2744,2745],{},[147,2746,438],{},[60,2748,2749],{},"作成したアプリケーション名の三点ドット",[60,2751,2752],{},[147,2753,2754],{},"編集",[13,2756,2757],{},[19,2758],{"alt":2759,"src":2760},"add_app_policy_service.png","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_app_policy_service.webp",[13,2762,2763],{},"アプリケーションにポリシーを追加",[57,2765,2766,2771,2775,2778,2783],{},[60,2767,2768],{},[147,2769,2770],{},"タグ: ポリシー",[60,2772,2773],{},[147,2774,2444],{},[60,2776,2777],{},"作成した Service Tokenのポリシーを選択",[60,2779,2780],{},[147,2781,2782],{},"確認",[60,2784,2785],{},[147,2786,2787],{},"アプリケーションを保存",[13,2789,2790],{},[19,2791],{"alt":2792,"src":2793},"作成したポリシーが選択できる","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/select_policy.webp",[13,2795,2796],{},"これでCloudflare側の設定は完了。",[436,2798,2800],{"id":2799},"immich-モバイルアプリ上の設定","Immich モバイルアプリ上の設定",[13,2802,2803],{},"お次はImmichのモバイルアプリで、アクセス時にトークンを含めるように設定する。",[57,2805,2806,2809,2812,2815],{},[60,2807,2808],{},"Immichモバイルアプリのログイン画面を開く",[60,2810,2811],{},"歯車マークをタップ",[60,2813,2814],{},"カスタムプロキシヘッダをタップ",[60,2816,2817,2818],{},"プロキシヘッダに以下を入力します\n",[57,2819,2820,2823],{},[60,2821,2822],{},"生成したクライアントIDのヘッダーと値",[60,2824,2825],{},"クライアントシークレットのヘッダーと値",[13,2827,2828],{},[19,2829],{"alt":2830,"src":2831},"カスタムプロキシヘッダの設定","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/add_custom_proxy.webp",[13,2833,2834],{},"以上。これで、Immichモバイルアプリから外部向けURLにアクセスしても認証を通過でき、作成済みアカウントでログインすれば写真を閲覧できる。",[13,2836,2837],{},[19,2838],{"alt":2839,"src":2840},"ドメインを打ち込めば、ログイン画面に遷移できる","/images/articles/raspi-immich-home-photos/goal2-secure-sharing/login_immich_mobile.webp",[13,2842,2843],{},"つまり、以下の手順を4人分実施すれば、両親も自分のスマホから孫の写真を見られるようになる。",[57,2845,2846,2849,2852,2855,2858],{},[60,2847,2848],{},"Immichで両親のアカウントを作成する",[60,2850,2851],{},"両親のアカウントに、息子のアルバムへの閲覧権限を付与する",[60,2853,2854],{},"両親のスマホにモバイルアプリをダウンロードする",[60,2856,2857],{},"モバイルアプリでカスタムプロキシヘッダを設定",[60,2859,2860],{},"各自のアカウントでログイン",[429,2862,2864],{"id":2863},"done️","Done👍️",[13,2866,2867],{},"これにて、",[79,2869,2871],{"className":2870},[1749],[60,2872,2874,2876],{"className":2873},[1753],[1755,2875],{"checked":162,"disabled":162,"type":1757}," 遠隔地の家族に安全に写真をシェアする",[13,2878,2879],{},"クリア。",[436,2881,2882],{"id":2882},"費用",[2884,2885,2886,2905],"table",{},[2887,2888,2889],"thead",{},[2890,2891,2892,2896,2899,2902],"tr",{},[2893,2894,2895],"th",{},"項目",[2893,2897,2898],{},"単価",[2893,2900,2901],{},"数量",[2893,2903,2904],{},"小計",[2906,2907,2908,2921,2935,2947,2959],"tbody",{},[2890,2909,2910,2914,2917,2919],{},[2911,2912,2913],"td",{},"Raspberry Pi 4 (8GB)",[2911,2915,2916],{},"¥12,000",[2911,2918,1789],{},[2911,2920,2916],{},[2890,2922,2923,2926,2929,2932],{},[2911,2924,2925],{},"HDD 1TB",[2911,2927,2928],{},"¥7,000",[2911,2930,2931],{},"2",[2911,2933,2934],{},"¥14,000",[2890,2936,2937,2940,2943,2945],{},[2911,2938,2939],{},"HDDケース（スタンド）",[2911,2941,2942],{},"¥4,000",[2911,2944,1789],{},[2911,2946,2942],{},[2890,2948,2949,2952,2955,2957],{},[2911,2950,2951],{},"雑費（SD・ケーブル）",[2911,2953,2954],{},"¥600",[2911,2956,1789],{},[2911,2958,2954],{},[2890,2960,2961,2964,2966,2968],{},[2911,2962,2963],{},"合計",[2911,2965],{},[2911,2967],{},[2911,2969,2970],{},"¥30,600",[2884,2972,2973,2985],{},[2887,2974,2975],{},[2890,2976,2977,2979,2981,2983],{},[2893,2978,2895],{},[2893,2980,2898],{},[2893,2982,2901],{},[2893,2984,2904],{},[2906,2986,2987,2999],{},[2890,2988,2989,2992,2995,2997],{},[2911,2990,2991],{},"ドメイン代",[2911,2993,2994],{},"¥1,000",[2911,2996,1789],{},[2911,2998,2994],{},[2890,3000,3001,3004,3006,3008],{},[2911,3002,3003],{},"年額合計",[2911,3005],{},[2911,3007],{},[2911,3009,2994],{},[13,3011,3012],{},"Google One (2TB) は ¥17,400/年。\n初期費用はかかるものの、2年弱運用できればおとく...?",[436,3014,3015],{"id":3015},"メリット",[79,3017,3018,3021,3024],{},[60,3019,3020],{},"サブスク費用が不要（",[60,3022,3023],{},"HDD増設すれば容量は実質無限",[60,3025,3026],{},"おもしろい",[436,3028,3029],{"id":3029},"デメリット",[79,3031,3032,3035,3038],{},[60,3033,3034],{},"初期構築の手間",[60,3036,3037],{},"HDDが壊れたときのリスクが大きい。クラウドと比べてリスク分散も難しい",[60,3039,3040],{},"Immich のアップデートが頻繁にある、破壊的な変更がたまにあるため、しっかり調べて対応しないといけない",[436,3042,3043],{"id":3043},"今後の課題",[79,3045,3046,3049],{},[60,3047,3048],{},"もう一箇所バックアップを用意したい",[60,3050,3051],{},"週1のバックアップ用にもかかわらず、HDD2が常時接続＆回転しっぱなし。",[3053,3054,3057,3062],"section",{"className":3055,"dataFootnotes":145},[3056],"footnotes",[37,3058,3061],{"className":3059,"id":1787},[3060],"sr-only","Footnotes",[57,3063,3064],{},[60,3065,3067,3072,3073],{"id":3066},"user-content-fn-fn:1",[47,3068,3071],{"href":3069,"rel":3070},"https://www.backblaze.com/blog/the-3-2-1-backup-strategy/",[51],"3-2-1 backup strategy"," に従うと、別の場所にもう1つバックアップを用意すべきでしょうね。 ",[47,3074,3079],{"href":3075,"ariaLabel":3076,"className":3077,"dataFootnoteBackref":145},"#user-content-fnref-fn:1","Back to reference 1",[3078],"data-footnote-backref","↩",[3081,3082,3083],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}",{"title":145,"searchDepth":159,"depth":159,"links":3085},[3086,3087,3088,3097,3105],{"id":39,"depth":159,"text":39},{"id":132,"depth":159,"text":132},{"id":336,"depth":159,"text":337,"children":3089},[3090,3091,3092,3093,3094,3095,3096],{"id":431,"depth":166,"text":431},{"id":522,"depth":166,"text":523},{"id":803,"depth":166,"text":804},{"id":1008,"depth":166,"text":1009},{"id":1427,"depth":166,"text":1427},{"id":1588,"depth":166,"text":1589},{"id":1741,"depth":166,"text":1742},{"id":1799,"depth":159,"text":1800,"children":3098},[3099,3100,3101,3102,3103,3104],{"id":1828,"depth":166,"text":1829},{"id":1862,"depth":166,"text":1863},{"id":2029,"depth":166,"text":2030},{"id":2046,"depth":166,"text":2046},{"id":2161,"depth":166,"text":2162},{"id":2863,"depth":166,"text":2864},{"id":1787,"depth":159,"text":3061},"2025-08-20T00:00:00.000Z","Immich はいいぞ","md",null,{},"/articles/raspi-immich-home-photos",{"title":5,"description":3107},{"loc":3111},"articles/raspi-immich-home-photos",[3116,449,3117,3118,3119],"RaspberryPi","自宅サーバー","Cloudflare","Googleフォト移行","GTsW-uFqYFCjepVOttXNNMU87CMQr56gW-beYbpcj3I",[3122,3127],{"title":3123,"path":3124,"stem":3125,"date":3126,"children":-1},"target='_blank'なリンクが開かない","/articles/target-blank-not-working-with-disqus","articles/target-blank-not-working-with-disqus","2025-08-24T00:00:00.000Z",{"title":3128,"path":3129,"stem":3130,"date":3131,"children":-1},"Chromeでリロードをしてもコンソール・ネットワークログを保持する方法","/articles/chrome-log-setting","articles/chrome-log-setting","2025-08-07T00:00:00.000Z",1772952405473]