Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ワンバイナリWebサービスのススメ
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
mackee
May 31, 2025
Programming
9k
10
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
ワンバイナリWebサービスのススメ
Houtou.pm #1
https://houtoupm.connpass.com/event/348282/
mackee
May 31, 2025
More Decks by mackee
See All by mackee
Go1.27で導入されるジェネリクスメソッドでできること
mackee
0
630
perlをWebAssembly上で動かすと何が嬉しいの??? / Where does Perl-on-Wasm actually make sense?
mackee
0
1.1k
Agentに至る道 〜なぜLLMは自動でコードを書けるようになったのか〜
mackee
6
6.1k
今!ソフトウェアエンジニアがハードウェアに手を出すには
mackee
14
7.3k
tanukistack ライブコーディング / tanukistack live-coding
mackee
0
760
range over funcの使い道と非同期N+1リゾルバーの夢 / about a range over func
mackee
0
1.2k
perl for shell, awk and sed programmers
mackee
3
2.9k
今更GoのWebフレームワークを作ろうとしているワケ / Why am I trying to create a Go web framework now?
mackee
1
1.1k
database/sqlでNullを扱う歴史とsql.Null[T]の登場 / sql.Null[T] history
mackee
0
1k
Other Decks in Programming
See All in Programming
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
270
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
550
What's New in Android 2026
veronikapj
0
260
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
450
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
340
AIが無かった頃の素敵な出会いの話
codmoninc
1
440
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
12
18k
Built Our Own Background Agent at LayerX
layerx
PRO
10
5.6k
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
560
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
500
「人を評価する AI」の設計と実装
ryoyanara
0
210
Go 1.27 における memory allocation の高速化
andpad
0
190
Featured
See All Featured
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
The World Runs on Bad Software
bkeepers
PRO
72
12k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
360
30k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.8k
Principles of Awesome APIs and How to Build Them.
keavy
128
18k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
770
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
610
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
250
Optimizing for Happiness
mojombo
378
71k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Transcript
ϫϯόΠφϦWebαʔϏεͷ εεϝ @mackee_w a.k.a macopy Houtou.pm #1
୭ʁ macopy GitHub: mackee X: mackee_w, mixi2: macopy ໘ന๏ਓΧϠοΫ άϧʔϓใ෦
όοΫΤϯυ, SRE, ΞʔΩςΫτ ද࡞: sqlla(ORM), tanukirpc(WAF)
Kamakura.goͬͯ·͢ʂʂʂ • લճ12݄ • ࣍7݄͔ͳ͋ͱͳͬͯ·͢
͓Βͤ: JRRF2025ʹग़ల͠·͢
ԿͷΛ͢Δͷʁ • αʔϏεΛ1ͭͷόΠφϦʹ·ͱΊͯ1ͭͷαʔόʔʹσϓϩΠ͢Δͷ Ͳ͏͔ͱݴ͏ఏҊ • ରൺ͢ΔͷෳͷΫϥυαʔϏεͰͷߏ(αʔόʔϨε) • ͦΕͧΕϝϦοτɾσϝϦοτ͕͋ΔͷͰ·ͣͦͷհ • ͳͥࠓʮϫϯόΠφϦʯͳͷ͔
͜ͷτʔΫΛ͠Α͏ͱࢥͬͨܦҢ • ීஈαʔόʔϨεߏͰࣄΛ͓ͯ͠Γେมศརʹײ͍ͯ͡Δ • ͔͠͠ؾ͔ͮͳ͍͏ͪʹࣄͷେ͕͍͔ʹखݩͰಈ͍͍ͯΔΞϓϦ έʔγϣϯΛͲ͏αʔόʔϨεߏʹద༻͢Δ͔ͷʹͳ͖ͬͯͨ • ͕࣌ؒͳͯ͘EC2Ͱͦͷ··ཱͯͨΒී௨ʹಈ͍ͨͷͰ͜ΕͰ͍͍ ͡ΌΜͱͳͬͨ
͜ͷηογϣϯͰͷ αʔόʔϨεͱʁ
αʔόʔϨεͷߏཁૉ(1) • FaaS ྫ: AWS Lambda, Cloud fl are Workers,
Cloud Run Functions • αʔόʔཧ͕͍Βͳ͍ • FaaSͷ߹ϦΫΤετॲཧ࣌ؒʹΑΔ՝͕ۚଟ͍ • ϑϧϚωʔδυ or αʔόʔϨεͳDB • RDBMS ͷ߹ϑϧϚωʔδυ͕ଟ͍ ྫ: Amazon RDS, Cloud SQL etc… • NoSQLҰ෦ͷRDBMSαʔόʔϨεత՝ۚϞσϧ ྫ: DynamoDB, Firestore
αʔόʔϨεͷߏཁૉ(2) • ΦϒδΣΫτετϨʔδ ྫ: Amazon S3, Cloud fl are R2,
Cloud Storage • ϑΝΠϧΞοϓϩʔυཁૉ͕͋ΔͱབྷΜͰ͘Δ • KVSͱͯ͠༻͢Δྫ͋Δ • CDN ྫ: Amazon CloudFront, Cloud fl are, Cloud CDN • WebϑϩϯτΤϯυ͕͋ΔαʔϏεͳΒཉ͍͠ • ΤοδͰॲཧͰ͖ͯخ͍͠έʔε͋Δ(CloudFront Functions
αʔόʔϨεͷߏཁૉ(3) • ϝοηʔδΩϡʔ ྫ: Amazon SQS, Cloud fl are Queues,
Cloud Tasks… • ඇಉظͰδϣϒΛΩοΫ͍ͨ͠έʔε͕͋Δ࣌ʹͬͨΓ͢Δ • FaaSͰϨεϙϯεΛฦ͞ͳͯ͘ྑ͍͕͍ॲཧΛΓ͍ͨέʔ εͳͲͰར༻͢Δ • ࣦഊͯ͠ϦτϥΠ͢ΔػߏͳͲ͕ೖͬͯͯخ͍͠
࠷ۙࣄͰ࡞ͬͨߏ
࠷ۙࣄͰ࡞ͬͨߏͦͷ2
झຯͰΔ࣌ͷߏ
ͳͥαʔόʔϨεͰ࡞Δͷ͔ʁ • ѹతʹ͍҆ • ୯७ͳWebαΠτ+গ͔͠Γͷॻ͖ࠐΈΛ͢ΔαΠτΛCDN/FaaS/NoSQL Ͱ࡞͕ͬͨɺͦͦ͜͜ར༻͕͋Δͷʹݸਓͷ͓খݣ͍ఔͰ͍͑ͯΔ • ӡ༻ίετݮ • αʔόʔͷΞοϓσʔτཧ੬ऑੑରԠͳͲͷൣғ͕ڱ͘ͳΔ
• εέʔϧΞτੑೳ • ʮαʔόʔʯ͕མͪΔͱ͍͏͜ͱཧతɾݱ࣮తʹͳ͍
͔͠͠ αʔόʔϨεͩͱࠔΔ͜ͱ͕͋Δ
1. ϩʔΧϧͰ։ൃͨ͠ͷΛͦͷ··͑ͳ͍ • ϩʔΧϧͱαʔόʔϨεڥಉҰͰͳ͍ • ΤϛϡϨʔτखஈ: AWS SAM Local, LocalStack
• ྆ରԠؔϋϯυϥ: fujiwara/ridge • ͦΕͰϓϩηεϞσϧͷҧ͍͔Β͘Δࡉ͔͍ڍಈͷҧ͍, ͦͦ ࣮ݱ͕͍͜͠ͱͳͲ͕͋Δ • ޓϨΠϠʔΛ͍ͭ͘ॻ͘͜ͱʹͳΔ
1. ϩʔΧϧͰ։ൃͨ͠ͷΛͦͷ··͑ͳ͍ • ϩʔΧϧͱαʔόʔϨεڥಉҰͰͳ͍ • ΤϛϡϨʔτखஈ: AWS SAM Local, LocalStack
• ྆ରԠؔϋϯυϥ: fujiwara/ridge • ͦΕͰϓϩηεϞσϧͷҧ͍͔Β͘Δࡉ͔͍ڍಈͷҧ͍, ͦͦ ࣮ݱ͕͍͜͠ͱͳͲ͕͋Δ • ޓϨΠϠʔΛ͍ͭ͘ॻ͘͜ͱʹͳΔ ͩͬͨΒϩʔΧϧͱಉ͡Α͏ͳ ී௨αʔόʔͰྑ͍ͷͰʁ
2. ࣗͷ৫֎Ͱͷӡ༻͕͍͠ • αʔόʔϨεͱ͍͏ΑΓΫϥυͷػೳʹґଘͨ͠αʔϏεͷσϝ Ϧοτ • ͓٬͞Μʮ͏ͪͷΦϯϓϨͰӡ༻͢Δ͔ΒιϑτΣΞΛചͬͯཉ͠ ͍ʯFaaS+αʔόʔϨεDBͰߏஙͨ͠΅͘ʮ…ʯ • 37signalsͷݴ͏ONCEϞσϧαʔόʔϨεલఏͷΞʔΩςΫνϟͩ
ͱࠔʹͳΔ
3. Ͱ͖ͳ͍͜ͱɾ͍͜͠ͱ͕͋Δ • ࠷࣮ۙࡍʹࣄͰͰ͘Θͨ͠՝ • PoCͷΞϓϦέʔγϣϯΛY.jsͱLocalStorageΛΈ߹ΘͤͯΫϥΠΞϯταΠυ͚ͩͰಈ࡞͢ ΔΑ͏ʹ࡞ͬͨ • ࣾͰෳਓͰ͓ࢼ͍͕ͨ͠͠ɺY.jsΛͪΌΜͱωοτϫʔΫܨ͛ͨΓLocalStorageͷσʔλ ຊαʔόʔʹஔ͖͍ͨ
• LambdaͩͱWebSocketΊΜͲ͍͘͞͠ɺ͕࣌ؒͳ͍ͷͰY.jsͷWebSocketαʔόʔΛͦͷ·· ಈ͔͍ͨ͠… • ͍͑ʂ͏EC2ཱͯͯͦ͜ͰWebSocketͷαʔόʔஔ͖·͢ɻAPIαʔόʔαΫοͱॻ͍ͯͦ ͜Ͱϗετ͠·͢ʂ => ͳΜͩ͜ΕͰ͍͍͡ΌΜ
݁ہαʔόʔϨεͰಘΒΕΔͷຊʹඞཁʁ • ίετ • ӡ༻ෛՙͷݮ • εέʔϧΞτੑೳ
• ίετ • (डୗͳͲͷ߹)ίετΑΓఱҪ͕ͳ͍ͱ͍͏ํ͕ྑ͍ͱݴ͏͓٬͞Μ͕͍Δ => ैྔ՝ۚͷ αʔόʔϨε͍ʹ͍͘ • ӡ༻ෛՙͷݮ •
ݱͷಓ۩(ίϯςφorϫϯόΠφϦͰు͘ݴޠ,tailscaleCloud fl are Tunnel, AWS Systems Manager etc…)Λ͑Ͳ͏ʹ͔ͳΔ͔ʁ • εέʔϧΞτੑೳ • ఘΊΔ😇 • CDNͰ͑Δʂαʔόʔ͕མͪͨΒఘΊΔ ݁ہαʔόʔϨεͰಘΒΕΔͷຊʹඞཁʁ
͡Ό͋Ͳ͜ʹσϓϩΠ͢Δʁ • ϩʔΧϧ…࣮༻తͰͳ͍ͷͰ • Cloud fl are TunnelngrokhttpsͰϩʔΧϧͷʹΕͯྑ͍ • https͡Όͳ͍ͱ͑ͳ͍Webٕज़͕͋Δ(ྫ:
Web Push) • ͦ͜ΒลͷదͳVPSʹσϓϩΠ͍ͨ͠ • fl y.ioCloud RunΈ͍ͨͳDocker PaaSͰྑ͍͔ͱࢥ͍·͢ • Ͱී௨ʹσΟεΫʹॻ͍ͯফ͑ͪΌ͏͔Βͳ… • ͱ͍͑ͳΜΒ͔ӬଓతͳσΟεΫΞλονͰ͖Δͱࢥ͍·͢
Ͳ͏ͬͯVPSͰӡ༻͢Δ͔
RailsʹֶͿ • ࠷ۙͷRailsONCEϞσϧ͕Ͱ͖ΔΑ͏ʹSQLiteʹد͍ͤͯΔ • Solid Queue, Solid Cable, Solid Cache
• σϓϩΠπʔϧKamalαʔόʔʹରͯ͠ͷϓϩϏδϣχϯάͱσϓ ϩΠΛߦ͏ • DockerίϯςφͰͷσϓϩΠ • kamal-proxy͕σϓϩΠ࣌ͷϦΫΤετܦ࿏ͷ͚ସ͑Λߦ͏
1ͰΑ͚ΕSQLiteͰྑ͍ • (ࢲSQLite͕ʹ͋ͬͨISUCON12༧બͷ࡞ऀͷҰਓͰ͢) • SQLite༧Ҏ্ͷྲྀྔΛࡹ͘͜ͱ͕Ͱ͖Δ • ϨϓϦέʔγϣϯ͍ͨ͠/ϦετΞ͍ͨ͠ => Litestream
εϥΠυॻ͍ͯͯࢥͬͨ: SQLiteͰGraceful RestartՄೳͳͷʁ • ࣮ݧ: Go + SQLiteͰॻ͍ͨΞϓϦέʔγϣϯʹabͰॻ͖ࠐΈΛܧଓ తʹߦ͍ͭͭɺGraceful Restart
• ͦͦෳͷॻ͖ࠐΈϦΫΤετ͕ಉ࣌ʹདྷΔͱ `database is locked (5) (SQLITE_BUSY)` ͷΑ͏ʹग़ΔͷͰ`sqlite3_busy_timeout` Λઃఆ • `sqlite3_busy_timeout `ͷޮՌͰͳͦ͞͏
࠷ۙͷRailsͰͷSQLiteͷΦϓγϣϯ • `IMMEDIATE` τϥϯβΫγϣϯͷΦϓγϣϯͰɺτϥϯβΫγϣϯΛ ։࢝ͨ࣌͠ʹσʔλϕʔεϩοΫΛऔΔ • WAL(Write Ahead Logging): τϥϯβΫγϣϯͷ୯ҐͰҰ࣌ϑΝΠϧ
Λ࡞ͬͯίϛοτ࣌ʹຊମʹॻ͖ࠐΉ • `sqlite3_busy_timeout` ଞͷεϨου/ϓϩηε͕ϩοΫ͍ͯ͠Δ࣌ʹ ॻ͖ࠐ͏ͱͨ࣌͠ʹԿඵ͔ͭ
GoͰRailsతʹ։ൃ͢Δ • ࠷ۙࣄͰΔ࣌ʹ࠾༻͢ΔελοΫ tanukirpc + sqlla • ϑϩϯτΤϯυTanStack Router +
React + Vite • tanukirpcͱsqllaboilerplateͳίʔυΛgenericsͱίʔυੜͰݮ͢ΔΞ ϓϩʔν • RailsgemͱDSLͰݮ͍ͯ͠Δ • ݸਓతʹ͜ͷΈ߹Θ͕ͤܕ͖ͰϫϯόΠφϦͰు͚ΔRailsͱͯ͠ೝࣝ͠ ͍ͯΔ
͍: ຊʹDocker͕ඞཁͳͷ͔ʁ • RailsͷΑ͏ͳRubyͱଟͷgemͰಈ࡞͢ΔͳΒ͋ͬͨํ͕ྑͦ͞͏ • σϓϩΠͷύοέʔδϯά͕DockerͰ୲͑Δ • gem͕OSଆͷڞ༗ϥΠϒϥϦʹґଘ͍ͯ͠Δέʔε • ෳͷϓϩηεͰಈ͘ͳΒ͋ͬͨํ͕ྑͦ͞͏
GoͷΑ͏ͳϫϯόΠφϦͳΒͲ͏͔ʁ • ϫʔΧʔͱ͔1ͭͷϓϩηεʹ·ͱΊͯgoroutineͰಈ͔ͪ͠Ό͏ • Graceful ShutdownႈੑؤுΖ͏ • σϓϩΠγϯϓϧʹखݩorCIͰϏϧυ => rsync
=> ࠶ىಈͰྑ͍ • ઌ΄ͲͷGraceful RestartͷσϞͰࣔͨ͠server_starterͷྫ
ϑϩϯτΤϯυͲ͏ͬͯΔʁ • `//go:embed` Λ༻͢Δ • ϑΝΠϧσΟϨΫτϦΛؙ͝ͱϓϩάϥϜͷόΠφϦʹ֨ೲ͢Δ • io/fs.FSΠϯλʔϑΣΠεΛ࣮͍ͯ͠ΔͷͰͦͷ··ϑΝΠϧγες ϜͷΑ͏ʹϓϩάϥϜ෦Ͱѻ͑Δ •
embedͰϏϧυͨ͠ϑϩϯτΤϯυΛ֨ೲ͢Δ
ະղܾͷ: σϓϩΠͨ͠Βݹ͍ΞηοτʹΞ ΫηεͰ͖ͳ͘ͳͬͨ • σϓϩΠޙʹϒϥβ͕อ͍࣋ͯ͠Δݹ͍index.htmlͳͲ͕ಡ͏ͱ͍ͯ͠Δݹ͍JSCSSΛಡ ͏ͱͯ͠404ʹͳΔ݅ • kamal-proxyͰղܾͰ͖͍ͯΔ • υΩϡϝϯτΛಡΉͱ྆ํอ͍࣋ͯ͠ΔͬΆ͍ʁ
• ͠Β͘ݹ͍ͭ࣋ͭͷ͕͍͍ΜͰ͠ΐ͏͔ • CloudFront + S3ͰΑ͍ͬͯͨ͘खஈͰ͋Δ͕… • `window.addEventListener(‘error’, …)`Ͱ`location.reload()`͢Δํ๏Ͱ͖ͦ͏ʁ • ͘͠Service Worker?
ͦͷଞͷ: ingress௨৴ • ϙʔτ22൪Λ։͚Δͷ͔ͳΓݏ • tailscaleಥͬࠐΜͰຊsshdΘͣʹTailscaleܦ༝ͰϩάΠϯ͍ͯ͠Δ • ͋ͱufwͰtailscaleҎ֎͔Βͷ֎͔Βͷ௨৴Λશ෦࠹͙ • 443൪։͚ͨ͘ͳ͍
• ͦΜͳ࣌ʹ͑Δͷ͕Cloud fl are Tunnel • cloud fl aredΛཱͯͯɺCloud fl areͰड͚ͨϦΫΤετΛτϯωϧܦ༝Ͱड͚Δ • cloud fl aredegressͷ௨৴͔͠͠ͳ͍ͷͰϙʔτ։͚Δඞཁ͕ͳ͍
͞Βʹͦͷଞ • daemonize • ੲsupervisordͱ͔daemontoolsͱ͔͚͋ͬͨΕͲࠓsystemdͰ͍͍ͱࢥ͏Α • cron • systemdͰ͍͍ͱࢥ͏Α •
ٖࣅcronϫʔΧʔΛgoroutineͰཱͯΔͷ͋Γ • ϩά • systemdͰ͍͍ͱࢥ͏Α • ݕࡧͰू͕ཉ͔ͬͨ͠ΒS3ͱ͔ʹͳΜΒ͔ϩάίϨΫλͰඈ͢ͷ͕͍͍ΜͰ͔͢Ͷ͑ • ࢹ • Mackerelͱ͔NewRelicͱ͔ • ࣗલmisskeyαʔόʔNewRelicೖΕͯΔ • ϓϩϏδϣχϯά • mitamae͔ͳ͋ systemdͷunitϑΝΠϧΛಥͬࠐΉͷࣗ࡞͔ͯ͑͑͠͠ΕΜ
Ҏ্ GoͰϫϯόΠφϦ+SQLiteͰαʔϏε ߏஙͷͰͨ͠