レガシーDjangoアプリケーションの現代化
DjangoCongress JP 2018 at Cybozu, Inc.
ϨΨγʔ Django ΞϓϦέʔγϣϯͷݱԽA Modernization of Legacy Django Based ApplicationsHayao SuzukiDjangoCongress JP 2018 at Cybozu, Inc.May 19, 2018
View Slide
Contents1 ֓ཁ2 ΞϓϦέʔγϣϯલ࢙3 Twelve-Factor App4 Django ͷΞοϓσʔτ5 ΞϓϦέʔγϣϯͷݱԽ6 ·ͱΊ2 / 29
Abstractൃදͷ֓ཁĹ Django 1.7 Ͱॻ͔ΕͨΞϓϦέʔγϣϯ͕ݱͩͬͨĹ ࣍ظϦϦʔεʹ͚ͯ Django 1.11 ʹόʔδϣϯΞοϓͨ͠Ĺ Twelve-Factor App ͷࢥΛϕʔεʹΞϓϦέʔγϣϯͷݱԽΛ࣮ࢪͨ͠୭͚ͷൃදʁĹ ݹ͍ΞϓϦέʔγϣϯΛվળ͢Δඞཁ͕͋ΓɺܦݧஊΛฉ͖͍ͨํĹ Twelve-Factor App ͷࢥͷ࣮ફྫ͕Γ͍ͨํҙ࣮ࡍͷडୗҊ݅ͷࣄྫΛϕʔεʹ࠶ߏͨ͠ͷͰ͢ɻ3 / 29
Who Am I?͓લ୭ΑName Hayao Suzuki (@CardinalXaro)Blog http://xaro.hatenablog.jpMajor Mathematics (Combinatorics, Number Theory)Work Python Programmer at iRidge, Inc.ࠪಡͨ͠ຊʢൈਮʣĹ Effective Python (O’Reilly Japan)Ĺ ΞϧΰϦζϜ ΫΠοΫϦϑΝϨϯε ୈ 2 ൛ (O’Reilly Japan)Ĺ ͢Β͢ΒΘ͔Δ Python ʢᠳӭࣾʣĹ Head First Python ୈ 2 ൛ (O’Reilly Japan)Ĺ Python σʔλαΠΤϯεϋϯυϒοΫ (O’Reilly Japan)4 / 29
ΞϓϦέʔγϣϯલ࢙ΞϓϦέʔγϣϯͷ֓ཁĹ εϚʔτϑΥϯΞϓϦͷόοΫΤϯυαʔόʔĹ ෳͷ Django ΞϓϦέʔγϣϯ͔Βߏ͞ΕΔĹ BtoC ͚ʢΞΫηεͷ͕͋ΔʣĹ 2017 3 ݄ϦϦʔεĹ Django 1.7Ĺ AWS EC2 ্ʹߏϓϩδΣΫτ๊͕͍͑ͯͨĹ Python 2.7.6ʢUbuntu 14.04 ଐʂʣΛͦͷ··͍ଓ͚͍ͯͨĹ Django 1.7 2015 Ͱαϙʔτ͕Ε͍ͯͨĹ Management ίϚϯυαʔόʔϩάΠϯޙʹखಈͰ࣮ߦĹ ϩάௐࠪαʔόʔϩάΠϯ͕ඞཁͱͳΔĹ 2 ߏͰඞཁʹԠͯ͡αʔόʔͷεέʔϧΞοϓɾμϯ͕ඞཁ5 / 29
ΞϓϦέʔγϣϯલ࢙࣍ظେܕΞοϓσʔτĹ 2017 8 ݄ελʔτ ! ͏͙͢ϦϦʔεĹ αʔόʔଆϝϯόʔ 4 ਓĹ ๊͍͑ͯͨΛղܾ͠Α͏ʂͳ͕͍ͨͼ͕͡·Δ...6 / 29
Twelve-Factor AppTwelve-Factor AppĹ Heroku ͷΤϯδχΞ͕ఏএͨ͠ SaaS Λͭ͘Γ্͛ΔͨΊͷํ๏Ĺ https://12factor.net/7 / 29
Twelve-Factor App֓ཁĹ ίʔυϕʔεĹ ґଘؔĹ ઃఆĹ όοΫΤϯυαʔϏεĹ ϏϧυɺϦϦʔεɺ࣮ߦĹ ϓϩηεĹ ϙʔτόΠϯσΟϯάĹ ฒߦੑĹ ഇغ༰қੑĹ ։ൃ/ຊ൪ҰகĹ ϩάĹ ཧϓϩηε8 / 29
Twelve-Factor Appຬ͍ͨͯͨ͠ཁૉĹ ίʔυϕʔε (ηϧϑϗεςΟϯάͷ GitLab ͰཧʣĹ όοΫΤϯυαʔϏεʢAWS RDS ͳͲʣĹ ϓϩηεʢγϯάϧϓϩηεʣĹ ϙʔτόΠϯσΟϯάʢNginx ͱͷΈ߹ΘͤʣΓͳ͍ཁૉĹ ઃఆʢڥ͝ͱʹϑΝΠϧ࡞ɺϋʔυίʔσΟϯάʣĹ ϏϧυɺϦϦʔεɺ࣮ߦʢͰ͖͍ͯͳ͍ʣĹ ґଘؔʢPython requirements.txt ͕ͩɺOS ...ʣĹ ฒߦੑʢ2 ߏɺεέʔϧΞοϓͷΈՄೳʣĹ ഇغ༰қੑʢഇغͰ͖ͳ͍ʣĹ ։ൃ/ຊ൪Ұகʢαʔόʔ͕ผͳͷͰҰக͠ͳ͍ʣĹ ϩάʢαʔόʔʹอଘɺΤϥʔϝʔϧ௨ɺόονܥ CRON Ͱ Slackʹ௨ʣĹ ཧϓϩηεʢόοναʔόʔͰ࣮ߦɺSSH ϩάΠϯඞཁʣ9 / 29
Django ͷΞοϓσʔτຐ๏ͷΑ͏ͳํ๏ଘࡏ͠ͳ͍Ĺ Django ͷυΩϡϝϯτʹԊͬͯॗʑͱΔ΄͔ͳ͍ΞοϓσʔτखॱĹ ϢχοτςετΛॻ͘ʢॏཁʣĹ Django ͷόʔδϣϯΛ 1 ্ͭͣͭ͛ΔĹ python -Wall manage.py test Ͱςετ࣮ߦɺܯࠂΛ 1 ͭͣͭফԽ͢ΔĹ Django 1.11 ʹ౸ୡ͢Δ·Ͱ܁Γฦ࣮͢ྫ: ৽نࢀըऀʹϢχοτςετॻ͚Δͷ͔Ĺ ແཧͰͨ͠ɻೖࣾ 1 ϲ݄ͷਓһͰϢχοτςετॻ͚ͳ͔ͬͨɻĹ ·ͣϓϩδΣΫτͷࣝΛਂΊΔ͜ͱ͔Β࢝ΊΔɻ10 / 29
Django ͷΞοϓσʔτDjango ϛυϧΣΞͷΞοϓσʔτĹ MIDDLEWARE_CLASSES ͔Β MIDDLEWARE มߋ͢Δ͚ͩͰμϝĹ ϛυϧΣΞΛࣗ࡞͍ͯͨ͠߹खΛՃ͑Δඞཁ͕͋Δ࣮ྫ: αʔυύʔςΟϛυϧΣΞ͕৽ܗࣜະରԠĹ ݪҼڀ໌ʹ͕͔͔࣌ؒͬͨĹ ϛυϧΣΞ͕ఏڙ͍ͯ͠Δػೳ Django ͕ެࣜʹఏڙ͢ΔΑ͏ʹͳͬͨɻ࣮ྫ: ࣗ࡞ϛυϧΣΞͷΞοϓσʔτĹ ެࣜυΩϡϝϯτʹҠߦखॱ͋Γ11 / 29
Django ͷΞοϓσʔτFigure: Django Middleware Λ৽ܗࣜมߋ͢Δ Commit12 / 29
SQL ΫΤϦνϡʔχϯάڪාͷ N + 1 Ĺ ෛՙςετͰൃ֮ʂĹ Django ORM ؆୯ɺͦ͏ࢥ͍ͬͯͨ࣌ظ͋Γ·ͨ͠ɻSQL ΫΤϦνϡʔχϯάĹ ෛՙςετͰଌఆ͢ΔĹ AWS X-Ray ͷτϨʔεσʔλΛݩʹՕॴΛಛఆ͢ΔĹ Django ͷυΩϡϝϯτΛಡΈͭͭޮͷΑ͍ΫΤϦΛ࡞Δ࣮ྫ: ී௨ɺdjango-debug-toolbar ͡Όͳ͍ͷʁĹ API αʔόʔͩͱ django-debug-toolbar ͍ͮΒ͔ͬͨ...Ĺ AWS X-Ray ͳΒ։ൃڥͰຊ൪ڥͰτϨʔεͰ͖Δ࣮ྫ: AWS X-Ray ͷಋೖĹ Django 1.10 Ҏ্Ͱ͋Δཧ༝: ৽ܗࣜͰ࣮͞Ε͍͔ͯͨΒɻ13 / 29
SQL ΫΤϦνϡʔχϯάFigure: AWS X-Ray ʹΑΔτϨʔεσʔλ14 / 29
ෛ࠴Λ͏ϦϑΝΫλϦϯάຐ๏ͷΑ͏ͳํ๏ଘࡏ͠ͳ͍ʢ2 ճʣĹ ϢχοτςετΛॻ͍ͯෆಈΛ࡞͔ͬͯΒɻΞοϓσʔτखॱĹ ϢχοτςετΛॻ͘ʢॏཁʣʢ2 ճʣĹ ʮ͋ͬ͜Εʯͱ͍͏෦ΛϦϑΝΫλϦϯάĹ python -Wall manage.py test Ͱςετ࣮ߦĹ ݟ௨͕͠Α͘ͳΔ·Ͱܧଓ࣮ྫ: Django ͷ MVT Ϟσϧʹجׂ͍ͮͨͷĹ ৭ʑͱؤு͍ͬͯΔ View ͷॲཧΛ Model ʹҠৡ͢ΔĹ ༗ೳ͗͢Δ utils.py ͷػೳΛ Model ʹҠৡ͢ΔĹ ॏෳͨ͠ Model ΛجఈΫϥεͰཧ͢ΔĹ σίϨʔλͰڞ௨ॲཧΛҰݩԽ͢Δ15 / 29
ڥมʹΑΔઃఆཧIII. ઃఆĹ ઃఆΛίʔυ͔Βݫີʹ͢ΔĹ ઃఆΛڥมʹ֨ೲ͢Δ࣮ྫɿdjango-environ ʹΑΔڥมͷཧĹ https://github.com/joke2k/django-environĹ settings.py ʹϋʔυίʔσΟϯά͍ͯͨ͠ઃఆΛڥมҠৡĹ develop.env ϑΝΠϧͰϩʔΧϧͰڥมΛѻ͑ΔΑ͏ʹ͢Δɻ16 / 29
ڥมʹΑΔઃఆཧFigure: ڥมͷΓग़͠Λ࣮ݱͨ͠ Merge Request17 / 29
ΞϓϦέʔγϣϯͷ Docker ίϯςφԽVIII. ฒߦੑĹ ϓϩηεୈҰڃࢢຽͰ͋ΔIX. ഇغ༰қੑĹ ଈ࠲ʹىಈɾऴྃ͢Δ͜ͱ͕Ͱ͖ΔĹ ىಈ࣌ؒΛ࠷খԽ͢ΔX. ։ൃ/ຊ൪ҰகĹ ܧଓతσϓϩΠ͍͢͠Α͏։ൃڥͱຊ൪ڥͷΪϟοϓΛখ͘͞อͭ18 / 29
ΞϓϦέʔγϣϯͷ Docker ίϯςφԽΞϓϦέʔγϣϯͷ Docker ίϯςφԽĹ ഇغ༰қੑɺ։ൃ/ຊ൪ҰகΛ࣮ݱ͢Δ༗ྗͳख๏࣮ྫɿVagrant ͔Β Docker Ĺ ։ൃɿVagrantɺຊ൪ɿAWS EC2 ͔Βͷ٫Ĺ ຊ൪ڥΛࢀߟʹ Dockerfile ΛΈཱͯΔĹ ࠷ॳ։ൃڥ͔Βར༻։࢝ɺͦͯ͠ AWS ECS 19 / 29
ΞϓϦέʔγϣϯͷ Docker ίϯςφԽFigure: AWS ECR ʹϓογϡ͞Εͨ Docker Πϝʔδ20 / 29
ܧଓతΠϯςάϨʔγϣϯɺܧଓతσϓϩΠV. ϏϧυɺϦϦʔεɺ࣮ߦĹ ϏϧυɺϦϦʔεɺ࣮ߦͷ 3 ͭͷεςʔδΛݫີʹ͢Δ࣮ྫɿGitLab CIĹ ैདྷίϛοτ࣌ʹϢχοτςετΛ࣮ߦ͢Δ͚ͩĹ ίϛοτ࣌ʹςετɺϚʔδޙʹ Docker ΠϝʔδϏϧυɺσϓϩΠΛ࣮ࢪĹ σϓϩΠ AWS ECR/ECS ߦ͍ɺ࣮ߦ ECS Ҡৡ21 / 29
ܧଓతΠϯςάϨʔγϣϯɺܧଓతσϓϩΠFigure: GitLab CI ʹΑΔ CI/CD ύΠϓϥΠϯ22 / 29
ϩΪϯάͱ௨XI. ϩάĹ ϩάΛΠϕϯτετϦʔϜͱͯ͠ѻ͏࣮ྫɿDocker ϩάυϥΠόʔͱ AWS CloudWatchĹ ΞϓϦέʔγϣϯ͔Βͷϩάग़ྗͯ͢ඪ४ग़ྗ or ඪ४Τϥʔྲྀ͢Ĺ ϩάͯ͢ AWS CloudWatch Logs ૹΔĹ Docker ϩάυϥΠόʔʹઃఆ͢Δ͚ͩͳͷͰ؆୯Ĺ CloudWatch Alarm ΛΈ߹ΘͤͯΤϥʔ௨23 / 29
ϩΪϯάͱ௨Figure: AWS CloudWatch Alarm ͷ௨Λ Slack ʹԼͯ͠ରԠ͢Δ24 / 29
όονλεΫͷίϚϯυԽXII. ཧϓϩηεĹ ཧλεΫΛ 1 ճݶΓͷϓϩηεͱ࣮ͯ͠ߦ͢Δ࣮ྫɿDjango ίϚϯυͱ AWS ECS λεΫĹ Django ίϚϯυ୯ҐͰ ECS λεΫΛ࡞ΔĹ ΤϯδχΞҎ֎Ͱόονૢ࡞͕ GUI ্Ͱ࣮ݱͰ͖ΔĹ Django ίϚϯυͱ ECS λεΫͷ૬ੑྑ͍25 / 29
όονλεΫͷίϚϯυԽFigure: Django ίϚϯυΛ࣮ߦ͢Δ AWS ECS λεΫ26 / 29
ڥมࠈ·͔͞ͷ࣌ͷڥมࠈʂĹ 1 ΞϓϦέʔγϣϯ͋ͨΓेݸͷڥมĹ ։ൃڥɺݕূڥɺຊ൪ڥɺCI/CD ͚Ĺ ෳͷΞϓϦέʔγϣϯ͔ΒͳΔϓϩδΣΫτڥมࠈΛͲ͏Γൈ͚Δ͔Ĺ ʮϓϥΠϕʔτϨϙδτϦ͔ͩΒ҆৺ʯઆĹ AWS S3 ʹผ్อଘͯ҆͠શʹऔΓग़͢Ĺ ڥมઐ༻ͷϨϙδτϦΛ࡞ͯ͠ SSH or HTTPS Ͱ҆શʹऔΓग़͢Ĺ AWS ͷΫϨσϯγϟϧ IAM Role Ͱ ECS λεΫʹׂΓͯͯݮΒ࣮͢ྫɿAWS Secrets ManagerĹ ΓʹધĹ ڥมΛڥ͝ͱʹผʹͯ҆͠શʹอଘ͢ΔĹ Secrets Manager ͷݤผ్ཧ͢Δඞཁ͕͋Δ27 / 29
Twelve-Factor Appຬ͍ͨͯͨ͠ཁૉĹ ίʔυϕʔε (ηϧϑϗεςΟϯάͷ GitLab ͰཧʣĹ όοΫΤϯυαʔϏεʢAWS RDS ͳͲʣĹ ϓϩηεʢγϯάϧϓϩηεʣĹ ϙʔτόΠϯσΟϯάʢNginx ͱͷΈ߹Θͤʣվળͨ͠ཁૉĹ ઃఆʢڥมʹΑΔʣĹ ϏϧυɺϦϦʔεɺ࣮ߦʢGitLab CI ʹΑΔ CI/CDʣĹ ґଘؔʢrequirements.txt ͱ dockerfileʣĹ ฒߦੑʢAWS ECS ʹΑΔΦʔέετϨʔγϣϯʣĹ ഇغ༰қੑʢDocker ίϯςφʣĹ ։ൃ/ຊ൪ҰகʢDockerʣĹ ϩάʢAWS CloudWatchʣĹ ཧϓϩηεʢAWS ECS ͷλεΫʣ28 / 29
·ͱΊ࣍ظϦϦʔεͷඪĹ Python 3 ͷҠߦ ˍ Django 2.2 LTS ͷҠߦ·ͱΊĹ Django ͷΞοϓσʔτʹຐ๏ଘࡏ͠ͳ͍ɻಓͳऔΓΈ͕ॏཁɻĹ ݹ͍ΞϓϦέʔγϣϯͰ Django ϕʔεͳΒվળߦ͍͍͢ɻĹ طଘͷΫϥυͷΤίγεςϜʹ͔ͬΔͱԿ͔ͱҠৡͰָ͖ͯʹͳΔɻĹ ڥมͷཧʹඞͣ໘͢Δɻඋ͑Α͏ɻ29 / 29