Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How do we casually create an Elixir community website with Phoenix?

How do we casually create an Elixir community website with Phoenix?

Presented at ElixirConf US 2021 by Ryotaro Imahashi
https://2021.elixirconf.com/#ryotaro-imahashi

Note:
Phoenix framework has had an robust and easy to use deployment system.
With the introduction of esbuild in the "1.6" version, builds are now even faster!

This talk shows how we create a ‘Casual’ and minimalistic website of kokura.ex, a local Elixir community in Japan, with Phoenix 1.6, and publish it.
We’ll show the following process:

- Build it with Docker to fix each of the versions of packages
- Prepare to build CI and CD to make operations easier
- Put it on Heroku to release the website to the public quickly

GitHub
https://github.com/miolab/kokuraex

kokura.ex website
https://kokura-ex.herokuapp.com

Ryotaro Imahashi

October 15, 2021
Tweet

Other Decks in Technology

Transcript

  1. How do we casually creat e an Elixir community websit

    e with Phoenix? Ryotaro Imahashi (kokura.ex ) 10/15, 2021
  2. .ZBOPUIFSBDUJWJUZ %BJUPSZV"JLJ+VKVUTV 0OFPGUIF+BQBOFTFUSBEJUJPOBMNBSUJBMBSUT  8FQSBDUJDFb,BUB`PG+VKVUTV ,FOKVUTV *BJKVUTV  #PKVUTV BOENPSF

    1IPUP`TEFTDSJQUJPO ,BUBPG+VKVUTV b,BSBNF;VNF` 5FBDIJOHB#PKVUTVUSJBMMFTTPO  4IFJTBOJOUFSOBUJPOBMTUVEFOUGSPN#FMHJVN  *BJKVUTVEFEJDBUJPOQFSGPSNBODFBUUIF /BHPTIJ'FTUJWBM "MMJNBHFTXFSFUBLFOJO'VLVPLB#VEPLBOCFGPSF UIF$07*%FQJEFNJD
  3. LPLVSBFYBDUJWJUZ .PLVNPLVUFDINFFUVQ   8IJDIJTBIBDLBUIPOXIFSFFBDIBUUFOEFFBDUT BMPOFUPXBSEFBDIHPBM JOSFMBY LPLVSBFY3BEJP  &WFSZ8FEOFTEBZGSPNBNUPBN

    +BQBO UJNF POBJSBU5XJUUFS4QBDFT JO+BQBOFTF   5IJTJTBOBVEJPEJTUSJCVUJPOQSPHSBNGSPN LPLVSBFY 5IFQSPHSBNGPDVTFTPOOFX*5UPQJDT JODMVEJOH UIPTFSFMBUFEUPUIF&MJYJSEFWFMPQNFOUMBOHVBHF 5IFSFXJMMCFBRVFTUJPOBOEBOTXFSDPSOFSGPS MJTUFOFSTBOEUFYUCBTFEJOGPSNBUJPOTIBSJOHPOUIF LPLVSBFYDIBOOFMJOUIFAFMJYJSKQATMBDL  5IPVHIXFUBMLDVSSFOUMZPOUIFSBEJPJO+BQBOFTF  XF`SFXFMDPNF&OHMJTITQFBLFSTBOEXJMMUSZUP JOUFSQSFUCPUIJO&OHMJTIBOE+BQBOFTF LPLVSBFY3BEJP JOGPSNBUJPO  IUUQTGVLVPLBFYDPOOQBTTDPNFWFOU
  4. LPLVSBFYBDUJWJUZ 044DPOUSJCVUJPO   LPLVSBFYBOE1FMFNBZ.FFUVQ B +BQBOFTF&MJYJSDPNNVOJUZ USZUP DPOUSJCVUF044 FTQFDJBMMZ

    /Y &9-"  BOE#FBN"TN XIJDISFBMJ[FIJHI TQFFEQSPDFTTJOHQFSGPSNBODF 1FMFNBZ.FFUVQ IUUQTQFMFNBZDPOOQBTTDPNFWFOU 
  5. % tree -L 2 .(e.g. kokuraex/ ) ├── README.m d

    ├── ap p │ └── Dockerfil e └── docker-compose.yml /PX XFXJMMNBLFUIF1IPFOJYQSPKFDU EJSFDUPSZBOEQSFQBSFUIFEPDLFSGJMFTBT TIPXOPOUIFSJHIU "CPVUUIFQSPKFDUEJSFDUPSZ XFOBNFE lLPLVSBFYzUIJTUJNF /PUF 8FPNJUNFOUJPOJOHTFWFSBMGJMFT GPS FYBNQMF 3&"%.& HJUJHOPSF BOENPSF *OUIFGPMMPXJOHDIBQUFST UPP 1SFQBSFEPDLFSGJMFT
  6. [app/Dockerfile ] FROM elixir:1.12.2-sli m WORKDIR /usr/src/ap p RUN apt-get

    update -y && \ apt-get upgrade -y && \ apt-get install -y \ build-essential \ curl \ git \ gzip \ inotify-tools \ ssh \ sudo \ ta r RUN apt-get clea n RUN mix local.hex --force && \ mix local.rebar --forc e RUN mix archive.install hex phx_new 1.6.0 --forc e CMD [ "mix", "phx.server", "--no-halt" ] 1SFQBSFEEPDLFSDPNQPTFZNMBOE %PDLFSGJMFJTIFSF *UTQFDJGJFT1IPOFOJYWFSTJPO 1SFQBSFEPDLFSGJMFT [app/Dockerfile ] version: "3 " services : app : build: ./ap p volumes : - ./app:/usr/src/ap p ports : - "4000:4000 " stdin_open: tru e tty: tru e command: sh -c "mix phx.server --no-halt "
  7. % docker compose run app mix phx.new . --app kokuraex

    —no-ect o … The directory /usr/src/app already exists. Are you sure you want to continue? [Yn] y … Fetch and install dependencies? [Yn] y … "GUFSEPOFPGAEPDLFSDPNQPTFCVJMEA JOTUBMM1IPFOJY *OTUBMM1IPFOJYGSBNFXPSL
  8. % tree -L 2 . ├── README.m d ├── ap

    p │ ├── Dockerfil e │ ├── README.m d │ ├── _buil d │ ├── asset s │ ├── confi g │ ├── dep s │ ├── li b │ ├── mix.ex s │ ├── mix.loc k │ ├── pri v │ └── tes t └── docker-compose.ym l *OTUBMM1IPFOJYGSBNFXPSL … We are almost there! The following steps are missing : $ cd . Start your Phoenix app with : $ mix phx.serve r You can also run your app inside IEx (Interactive Elixir) as : $ iex -S mix phx.server 8FTBXUIFGPMMPXJOHNFTTBHF BOEDPOHSBUVMBUJPOT  UIFJOTUBMMBUJPOXBTDPNQMFUFE "OEBUUIFNPNFOU UIFEJSFDUPSZUSFFJTTIPXOPO UIFSJHIU
  9. "GUFS1IPFOJYJOTUBMMBUJPO  GJY*1UPl   zGPSEFWFYTGJMFCZVQEBUFBTCFMMPX *OTUBMM1IPFOJYGSBNFXPSL [app/config/dev.exs ] config

    :kokuraex, KokuraexWeb.Endpoint , # Binding to loopback ipv4 address prevents access from other machines . # Change to `ip: {0, 0, 0, 0}` to allow access from other machines . - http: [ip: {127, 0, 0, 1}, port: 4000] , + http: [ip: {0, 0, 0, 0}, port: 4000] ,
  10. 8IBUUIJTDIBQUFSDPWFST 5PQSFQBSFUIFMBZPVUXJUIFBTF XFXJMMVTF 5BJMXJOE$44 *OUIJTTFDUJPO XFXJMMGPDVTPOUIFTFUVQBOE JOUSPEVDUJPOPG5BJMXJOEJNQMFNFOUBUJPO 8FXJMMBMTPFYQMBJOXFCTJUFDPOUFOUDSFBUJPO BOEQBHFUSBOTJUJPOT CVUXFXJMM/05FYQMBJO

    NVDIBOETLJQBCPVUNBSLVQ UFTUT BOEPUIFS JNQMFNFOUBUJPOEFUBJMT 4UFQT *OTUBMM/PEFKT 1SFQBSF5BJMXJOE$44FOWJSPONFOU 1SFQBSFFBDISPVUFQBHFBOENBSLVQ 4FUUBJMXJOEDMBTTJOMJOFDPEF
  11. 5BJMXJOE$44SFRVJSFTUIFFOWJSPONFOUPG /PEFKT CVUPVS1IPFOJYWFSTJPOQSPKFDU EPFTOPUIBWFUIFPOFZFU 4P XFNVTUBEEUIFTUFQPGJOTUBMMBUJPO/PEFKT JO%PDLFSGJMF *OUIJTUBML XFVTFOQNQBDLBHFOUPJOTUBMM /PEFKTBOENBOBHFUIFWFSTJPOT

    5IFSFJTBMTPBSFBTPOXIZ*XBOUUPTQFDJGZ FWFONJOPSWFSTJPOTPG/PEFKTBOEBWPJE QSPCMFNTDBVTFECZWFSTJPOEJGGFSFODFT "GUFSJOTUBMMJOH/PEFKT XFSFCVJMEDPOUBJOFST BHBJOXJUIbEPDLFSDPNQPTFCVJME` *OTUBMM/PEFKT (for confirmation ) % docker compose exec app node - v v16.9.1 /05&O OQNQBDLBHF  IUUQTXXXOQNKTDPNQBDLBHFO [app/Dockerfile ] … + RUN apt-get install -y nodejs np m + RUN npm install -g n + RUN n 16.9. 1 + RUN apt-get purge -y nodejs np m RUN apt-get clea n … % docker compose build
  12. 'PSTFUVQ5BJMXJOE$44TNPPUI XFTJNQMZ DIPPTFIFYQBDLBHF lQIY@HFO@UBJMXJOEz 5IJTCVJMETVQ5BJMXJOE$44EFWFMPQNFOU FOWJSPONFOUUPBOFX1IPFOJYBQQMJDBUJPO OJDFBOERVJDLMZ #JHUIBOLTUPUIFIFYQSPKFDUPXOFS ,FWJO -BOH

     5IFGJSTUTUFQUPEPJTUPTUPQSVOOJOH DPOUBJOFSTBOEUIFOVQEBUFNJYFYTBTTIPXO POUIFSJHIU "GUFSUIBU XFEPNJYEFQTHFUBOEDPNQJMF 1SFQBSF5BJMXJOE$44FOWJSPONFOU % docker compose run app mix deps.compile /05&QIY@HFO@UBJMXJOE )FY IUUQTIFYQNQBDLBHFTQIY@HFO@UBJMXJOE (JU)VC IUUQTHJUIVCDPNLFWJOMBOHQIY@HFO@UBJMXJOE [app/mix.exs ] defp deps d o [ .. . - {:plug_cowboy, "~> 2.5" } + {:plug_cowboy, "~> 2.5"} , + {:phx_gen_tailwind, "~> 0.1.3" } ] end % docker compose run app mix deps.get
  13. 5IFOFYFDVUFUIFDPNNBOEAEPDLFSDPNQPTFSVO BQQNJYQIYHFOUBJMXJOEA /PXXFBSFSFBEZUPJNQMFNFOU$44XJUI5BJMXJOE 5IFNBJOGJMFTXIFSFUIFEJGGFSFODFTPDDVSSFEBSF TIPXOPOUIFSJHIU *GXFXBOUUPLOPXNPSFBCPVUQIY@HFO@UBJMXJOE  UIF(JU)VCBOE)FYEPDVNFOUTBUUIF63-POUIF SJHIUXJMMIFMQVT 0GDPVSTF

    XFXJMMBMTPGJOEUIFPGGJDJBM5BJMXJOE$44 EPDVNFOUBUJPOWFSZIFMQGVM IUUQTUBJMXJOEDTTDPNEPDTJOTUBMMBUJPO 1SFQBSF5BJMXJOE$44FOWJSPONFOU % docker compose run app mix phx.gen.tailwin d * creating assets/package.jso n * creating assets/tailwind.config.j s * injecting assets/css/app.cs s * injecting config/dev.ex s * injecting mix.ex s * injecting assets/js/app.j s NPM install new dependencies? [Yn] y * running cd assets/ && npm install mainly dif f modified: app/assets/css/app.cs s modified: app/assets/js/app.j s modified: app/config/dev.exs /05&QIY@HFO@UBJMXJOE )FY IUUQTIFYQNQBDLBHFTQIY@HFO@UBJMXJOE (JU)VC IUUQTHJUIVCDPNLFWJOMBOHQIY@HFO@UBJMXJOE
  14. "EEUIFDMBTTFTQSFQBSFECZ5BJMXJOE$44JOUIFIUBHCZ JOMJOFTUZMF 5IJTNBHJDIBTUIFFGGFDUPGDPOWFSUJOHUIFGPOUXFJHIU GPOU TJ[F BOEDPMPSPGGPOUTUPXIBUFWFSXFXBOU *GXFXBOUUPLOPXNPSFBCPVUXIJDIDMBTTEPFTXIBU JUJT SFDPNNFOEFEUPTFFUIF5BJMXJOE$44DIFBUTIFFU63- 'PSFYBNQMF

    UIFSFJTBDIFBUTIFFUUIBUMPPLTMJLF lUBJMXJOEDPNQPOFOUTDPNz IUUQTUBJMXJOEDPNQPOFOUTDPNDIFBUTIFFU 1SFQBSF5BJMXJOE$44FOWJSPONFOU [app/lib/kokuraex_web/templates/page/index.html.heex ] <section class="phx-hero" > - <h1><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1 > + <h1 class="font-medium text-4xl text-indigo-600"><%= gettext "Welcome to %{name}!", name: "Phoenix" %></h1 > <p>Peace of mind from prototype to production</p>
  15. /PX XFXJMMTUBSUJNQMFNFOUJOHUIFDPOUFOUTFUVQBOE QBHFUSBOTJUJPOTGPSPVSXFCTJUF LPLVSBFY 1BHFUSBOTJUJPOTBSFTIPXOCFMPX BOEUIF JNQMFNFOUBUJPOJTEPOFBTTIPXOPOUIFSJHIU 5IFFYBNQMFTIPXOIFSFJTGPSUIFBCPVUQBHF CVUUIF JNQMFNFOUBUJPOGPSUIFFWFOUQBHFDBOCFEPOFJOUIF

    TBNFXBZ 3FQMBDFBCPVUXJUIFWFOUBOEDMPOFJU  1MFBTFOPUFUIBUXFXJMMOFFEUPTUPQBOESFTUBSUUIF DPOUBJOFSBTOFFEFE 1SFQBSFFBDISPVUFQBHFBOENBSLVQ (page transitions ) hom e !"" abou t #"" event (New file ) [app/lib/kokuraex_web/templates/about/index.html.heex ] <h1>About</h1> [app/lib/kokuraex_web/router.ex ] … get "/", PageController, :inde x + get "/about", AboutController, :inde x end (New file ) [app/lib/kokuraex_web/controllers/about_controller.ex ] defmodule KokuraexWeb.AboutController d o use KokuraexWeb, :controlle r def index(conn, _params) d o render(conn, "index.html" ) en d end (New file) [app/lib/kokuraex_web/views/about_view.ex ] defmodule KokuraexWeb.AboutView d o use KokuraexWeb, :vie w end
  16. -FUTUBLFBMPPLBUUIFlBCPVUzQBHF  XIJDIIBTKVTUCFFOCPSO *UJTJOBQMBJOTUBUFXJUIOP$44DMBTTFT BQQMJFEZFU 'SPNIFSF XFDSFBUFUIFDPOUFOU  JODMVEJOHUFYUBOEJNBHFT UPTFUUIF

    MBZPVU 8FXPOUHPJOUPUIFEFUBJMTIFSF 5IFTPVOEPGBDMPDLUJDLJOHXIJMF NBSLVQJTCFJOHEPOFʜ 1SFQBSFFBDISPVUFQBHFBOENBSLVQ (localhost:4000/about)
  17. 5IFTFDSFULFZHFOFSBUFECZUIJTTUFQJTUIF POFXFMMOFFEUPEFQMPZUP)FSPLVMBUFS .BLFBOPUFPGJUTPNFXIFSF TPXFEPOU MPTFJU 5IJTJTDPOGJEFOUJBMJOGPSNBUJPO 1MFBTFEPOUSFWFBMJUUPBOZPOF  "MTP VQEBUFPVS%PDLFSGJMFBOESFMFWBOU

    GJMFTBTTIPXOPOUIFSJHIU 4FUVQPG1IPFOJYGPSSFMFBTF [app/config/prod.exs ] … config :kokuraex, KokuraexWeb.Endpoint , - url: [host: "example.com", port: 80] , + http: [port: System.get_env("PORT")] , + url: [scheme: "https", host: "kokura-ex.herokuapp.com", port: 443] , + force_ssl: [rewrite_on: [:x_forwarded_proto]] , … [app/Dockerfile ] FROM elixir:1.12.2-sli m + ENV MIX_HOME=/root/.mix \ + MIX_ENV=prod \ + SECRET_KEY_BASE=${SECRET_KEY_BASE} \ + PORT=400 0 + COPY . /usr/src/ap p WORKDIR /usr/src/app "OZXBZ MFUTHPCBDLBMJUUMFCJU BOETUBSUXJUIUIFTFUVQJO1IPFOJYGPSSFMFBTF 8FGJSTUOFFEUPDSFBUFBTFDSFULFZCZSVOOJOHUIF DPNNBOEAEPDLFSDPNQPTFSVOBQQNJY QIYHFOTFDSFUA % docker compose run app mix phx.gen.secret [app/config/config.exs ] # Configures the endpoin t config :kokuraex, KokuraexWeb.Endpoint , url: [host: "localhost"] , + secret_key_base: System.get_env("SECRET_KEY_BASE") , …
  18. 4FUVQPG1IPFOJYGPSSFMFBTF (New file) [heroku.yml ] build : docker : web:

    app/Dockerfile [docker-compose.yml ] … + environment:SECRET_KEY_BASE=“TooLongStrings……… ” stdin_open: tru e tty: tru e command: sh -c "mix phx.server —no-halt" 1MFBTFOPUFUIBUUIFTFDIBOHFTNBZQSFWFOUPVSMPDBM %PDLFSEFWFMPQNFOUFOWJSPONFOUGSPNSVOOJOHQSPQFSMZ *GTP XFTIPVMEUBLFUIFGPMMPXJOHTUFQT  3FXSJUFEPDLFSDPNQPTFZNMBTTIPXOPOUIFSJHIU  XJUI4&$3&5@,&:@#"4&CFJOHBMPOHEVNNZUFYUPG ZPVSDIPJDF  8FDBOBMTPSFNPWFUIFATFDSFU@LFZ@CBTFAMJOFGSPN BQQDPOGJHEFWFYT *OUIFGVUVSF JUXPVMECFOJDFUPIBWFUXP%PDLFSGJMFT  POFGPSEFWFMPQNFOUBOEPOFGPSSFMFBTF 8FPNJUBOFYQMBOBUJPOPGUIBUIFSF 0PQT XFGPSHPUPOFNPSFJNQPSUBOUUIJOH 8FTIPVMEDSFBUFBIFSPLVZNMGJMFBOEQVUJUJOUIFSPPU PGPVSQSPKFDUEJSFDUPSZ [app/config/dev.exs ] … code_reloader: true , debug_errors: true , - secret_key_base: “LongPreWrittenWtrings…………… ” watchers: [ …
  19. /PUF  8FXJMMOPUFYQMBJOIPXUPDSFBUFB)FSPLVBDDPVOUIFSF*GZPVIBWFOUDSFBUFEBO BDDPVOUZFU QMFBTFSFGFSUPUIFPGGJDJBMXFCTJUFGPSFBTZUPGPMMPXJOTUSVDUJPOTUPHFU SFBEZ IUUQTEFWDFOUFSIFSPLVDPNDBUFHPSJFTCJMMJOH  *UJTCFTUJGZPVBMTPJOTUBMM)FSPLV$PNNBOE-JOF*OUFSGBDF )FSPLV$-*

    )FSPLV $-*NBLFTJUFBTZUPNBOBHF)FSPLVBQQTEJSFDUMZGSPNUIFUFSNJOBM5IFJOTUBMMBUJPO QSPDFTTJTIFSF IUUQTEFWDFOUFSIFSPLVDPNBSUJDMFTIFSPLVDMJ 4FUVQPG)FSPLV /PXJUTUJNFUPTFUVQ)FSPLV -FU`TMPHJOUP)FSPLVGSPNUIFUFSNJOBM % heroku login
  20. /PX MFUTDSFBUFB)FSPLVQSPKFDUCZFYFDVUJOHUIF DPNNBOEAIFSPLVDSFBUFBXFTPNFBQQOBNFA  *OUIFBXFTPNFBQQOBNFGJFME XFTIPVMEFOUFS UIFOBNFPGUIFBQQMJDBUJPOOBNFXFXBOU"OE UIJTTUSJOHXJMMCFEJSFDUMZJODPSQPSBUFEBTQBSUPG UIFBQQMJDBUJPO`TQVCMJD63- 

    "UUIFTBNFUJNF JUXJMMSFHJTUFSPVS)FSPLV SFQPTJUPSZUPUIFHJUSFNPUFSFQPTJUPSZ$IFDLJU PVUJOUIFAHJUSFNPUFADPNNBOE 8FMMBMTPOFFEUPBEEUIFTFDSFULFZXFDSFBUFE FBSMJFSUPUIF)FSPLVFOWJSPONFOUWBSJBCMFT -FU`TSFHJTUFSCZFYFDVUJPOUIFDPNNBOEAIFSPLV DPOGJHTFU4&$3&5@,&:@#"4&YYYYYYYYYYYYA 4FUVQPG)FSPLV % heroku create kokura-e x Creating ⬢ kokura-ex... don e https://kokura-ex.herokuapp.com/ | https:// git.heroku.com/kokura-ex.git % heroku config:set SECRET_KEY_BASE=xxxxxx x Setting SECRET_KEY_BASE and restartin g …
  21. /PXMFUTHFUSFBEZUPEFQMPZB%PDLFSCBTFE QSPKFDUCZVTJOHUIF)FSPLV$POUBJOFS 3FHJTUSZNFDIBOJTN 'PSBNPSFEFUBJMFEFYQMBOBUJPOPGUIF)FSPLV $POUBJOFS3FHJTUSZ JUXPVMECFBHPPEIFMQFS UPSFBEUIFPGGJDJBMEPDVNFOUBUJPO IUUQT EFWDFOUFSIFSPLVDPNBSUJDMFTDPOUBJOFS SFHJTUSZBOESVOUJNF

     )FSF XFXJMMGPDVTPOUIFFYFDVUJPOTUFQT )PXFWFS JUJTWFSZFBTZUPEP TPMFUTSVOUIF DPNNBOEPOUIFSJHIU 4FUVQPG)FSPLV % heroku container:logi n Login Succeeded % heroku stack:set containe r Setting stack to container... done
  22. &OTVSFUIBUPVSDPEFJTBMMHJUDPNNJUUFE BOEUIFO SVOUIFDPNNBOEAHJUQVTIIFSPLV NZ@CSBODINBJOA 5IJTXJMMQVTIPVSGJMFT JODMVEJOHIFSPLVZNM UPUIF SFNPUFSFQPTJUPSZPG)FSPLV  /PUFUIBUXFSFQMBDFUIFMFUUFSTlNZ@CSBODIzXJUI

    UIFOBNFPGUIFCSBODIXFSFXPSLJOHPO*O EFUBJM UPEPBUSJBMQVTIUP)FSPLVXIFOXFSFJO UIFEFWFMPQNFOUHJUCSBODI XFOFFEUPTQFDJGZ TPNFUIJOHMJLFzNZ@CSBODINBJOz 0ODFXFWFEPOFUIJT NPWFUPUIFBQQEJSFDUPSZ  BOEJUTUJNFGPSUIFQSPEVDUJPOSFMFBTFUJNF 3VOAIFSPLVDPOUBJOFSQVTIXFCABOEAIFSPLV DPOUBJOFSSFMFBTFXFCA %FQMPZ % cd ap p % heroku container:push we b … Your image has been successfully pushed. You can now release it with the 'container:release' command . $ heroku container:release we b Releasing images web to phx- containers... done % git push heroku my_branch:main
  23. 6OGPSUVOBUFMZ JGUIBUEPFTOUXPSL XIBUEPXFEP  5IFDPNNBOEAIFSPLVMPHTUBJMAXJMMIFMQVT $IFDLPVSMPHTBOEUSZUPTPMWFUIFQSPCMFN 5IFDBVTFPGUIFFSSPSNJHIUCF GPSFYBNQMF  :PVNJHIUOPUMPHJOUP)FSPLVCZAIFSPLVDPOUBJOFSMPHJOA

     TPUIFFSSPSBSPVOEBVUIJOUFSDFQUFEZPV  :PVNJHIUPNJUUIFFOWJSPONFOUWBSJBCMFTSFMBUFEUP )FSPLV FJUIFSPO)FSPLVPSJOPVS%PDLFSGJMF :PVNJHIUGPSHFUUPHJUQVTI)FSPLVUIFDIBOHFEGJMFT 8FXJMMBTTVNFUIBUFWFSZUIJOHXFOUXFMMIFSF /PX MFUTTFFUIFTJUFQVCMJTIFEGPSUIFXPSMEUPTFF 8FDBOSVOUIFAIFSPLVPQFOADPNNBOEUPEJTQMBZ UIFTJUFJOUIFCSPXTFS0QFO4FTBNF %FQMPZ % heroku logs --tail % heroku open
  24. 8IBUUIJTDIBQUFSDPWFST 'PSUIFDPODMVEJOHQBSUPGUIJTUBML XFMMCVJMEUIF $*BOE$%QJQFMJOF 5IF$*BOE$%QJQFMJOFXJMMCSJOHUPNBLF PQFSBUJPOTFBTJFSGPSVT*OUIJTDBTF XFXJMMCVJME UIF$*BOE$%QJQFMJOFCZVTJOH$JSDMF$*WJB (JU)VC 5IJTTFDUJPOXJMMNBJOMZGPDVTPOUIFFYQMBJOJOHUIF

    GMPXPGUIF$*BOE$%QJQFMJOFXFCVJMU CVUXFXJMM /05FYQMBJONVDIBOETLJQEFUBJMFEFYQMBOBUJPOPG $JSDMF$* (JU)VC BOE$*$%UIFNTFMWFT 4UFQT 1SFQBSFDJSDMFDJDPOGJHZNMJOMPDBM 4FU$JSDMF$*FOWJSPONFOU &YFDVUFUIF$*BOE$%QJQFMJOF
  25. 1SFQBSFDJSDMFDJDPOGJHZNMJOMPDBM 4P XFXJMMHPUISPVHIUIFQSPDFTTTUFQCZTUFQ CVUXFXJMM/05FYQMBJOIPX UPDSFBUFB$JSDMF$*BDDPVOU 'VSUIFSNPSF XFVTF(JU)VC CVUXFEP/05FYQMBJOIPXUPDPOOFDUUIF SFNPUFSFQPTJUPSZUPUIF$JSDMF$*TJEFJOEFUBJM 8FDBOGJOEEFUBJMFEJOTUSVDUJPOTPOUIFTFUPQJDTPO$JSDMF$*`TPGGJDJBMXFCTJUF

    )FSFJTUIF63-GPSUIPTF DJSDMFDJ%PDT:PVS'JSTU(SFFO#VJME IUUQTDJSDMFDJDPNEPDTHFUUJOHTUBSUFE $JSDMF$*IBTHPPEUFDIOJDBMEPDVNFOUBUJPO TPXFDBOGJOEPVUBOETPMWFNPTU QSPCMFNTCZSFBEJOHUIFJSEPDVNFOUBUJPO
  26. (New file) [circleci/config.yml ] version: 2. 1 executors : machine-executor

    : machine : image: ubuntu-2004:202107-0 2 orbs : heroku: circleci/[email protected]. 6 workflows : version: 2 build-deploy : jobs : - buil d - deploy : requires : - buil d filters : branches : only: mai n jobs : (Continue to next page) -FUTTUBSUCZXSJUJOHDPEFJOUPUIFDJSDMFDJDPOGJHZNMGJMF 5IFNBJOQPJOUTPGUIFQSPDFTTGMPXBSFBMTPEFTDSJCFEJOFBDITFDUJPO 8FXJMMBMTPJODMVEFSFGFSFODF63-T FYFDVUPST #ZBQQMZJOH.BDIJOFUPUIF&YFDVUPSUZQF XFSVOUIFKPCJOB-JOVY7. JNBHF 6CVOUV *OBEEJUJPO UIF.BDIJOF&YFDVUPSHJWFTVTGVMMBDDFTTUP UIF%PDLFSQSPDFTT5IJTBMMPXTVTUPCVJMEBOESVODVTUPN%PDLFS DPOUBJOFST  6TJOHNBDIJOFIUUQTDJSDMFDJDPNEPDTFYFDVUPSUZQFTVTJOH NBDIJOF  PSCT 5PFBTJMZTFUVQUIF)FSPLVEFQMPZNFOUQSPDFTT XFBSFVTJOH$JSDMF$*T )FSPLV0SC $JSDMF$*0SCJTBTIBSBCMFPQFOTPVSDFQBDLBHFUIBUCSJOHTUPHFUIFS CVJMEJOHCMPDLTUIBUNBLFJURVJDLBOEFBTZUPJOUFHSBUFBOEQSPDFTT EJGGFSFOUTFSWJDFT  0SCDJSDMFDJIFSPLV IUUQTDJSDMFDJDPNEFWFMPQFSPSCTPSCDJSDMFDJ IFSPLV XPSLGMPXT 0ODFUIFDPOUBJOFSJNBHFIBTCFFOCVJMUCZUIFlCVJMEKPCzBOE TVCTFRVFOUMZNFSHFEJOUPUIFNBJOSFQPTJUPSZ UIFEFQMPZNFOUQSPDFTTJT FYFDVUFE5IFJNQMFNFOUBUJPOJTSFGMFDUFEJOUIFQSPEVDUJPOFOWJSPONFOU 1SFQBSFDJSDMFDJDPOGJHZNMJOMPDBM
  27. (Continued from previous page ) jobs : build : executor

    : name: machine-executo r steps : - checkou t - run : name: Build Docker container s command: | set - x docker-compose buil d - run : name: Mix deps.get & compil e command: | set - x docker-compose run app bash -c "mix deps.get " docker-compose run app bash -c "mix compile" *OUIFCVJMEKPCTUFQ WBSJPVTCVJMEPQFSBUJPOTBSF FYFDVUFEBTUIFOBNFTVHHFTUT*OUIJTTUFQ UFTUJOH BOEGPSNBUUJOHDIFDLTBSFBMTPDBSSJFEPVUEVSJOHUIJT TUBHFPGUIFQSPDFTT 'PSSFBTPOTPGQBQFSTQBDF TPNFJOEFOUBUJPOJOUIF ZNMGJMFIBTCFFOPNJUUFE 1SFQBSFDJSDMFDJDPOGJHZNMJOMPDBM - run : name: Npm install in assets director y command: | set - x docker-compose run app bash -c "cd assets && npm i " - run : name: Mix forma t command: | set - x docker-compose run app bash -c "mix format --check-formatted " - run : name: Mix tes t command: | set - x docker-compose run app bash -c "MIX_ENV=test mix test " - run : name: Compile asset s command: | set - x docker-compose run app bash -c "MIX_ENV=prod mix assets.deploy " - run : name: Mix releas e command: | set - x docker-compose run app bash -c "MIX_ENV=prod mix release " - run : name: Run Docker container s command: | set - x docker-compose up - d sleep 1 docker ps -f status=runnin g docker-compose log s - persist_to_workspace : (Continue to next page)
  28. (Continued from previous page ) - persist_to_workspace : root: .

    paths : - ./app/dep s - ./app/_buil d - ./app/pri v - ./app/assets / - run : name: Finish buil d command: | set - x echo "Finish build" QFSTJTU@UP@XPSLTQBDF JOUIFCVJMEKPC  'JMFTEJSFDUPSJFTSFRVJSFEGPSEFQMPZNFOUBSF TIBSFEWJBl8PSLTQBDFzCFUXFFOUIFCVJMEBOE EFQMPZKPCT EFQMPZ 5IJTJTXIFSFUIFQSPDFTTPGEFQMPZJOHUP)FSPLV UBLFTQMBDF5IFFOWJSPONFOUWBSJBCMFTFUUJOHFUD  BSFEFTDSJCFEMBUFS 1SFQBSFDJSDMFDJDPOGJHZNMJOMPDBM deploy : executor : name: machine-executo r steps : - checkou t - attach_workspace : at: . - run : name: Check directories/file s command: | set - x pwd && ls -a && ls ap p - heroku/instal l - heroku/check-authenticatio n - run : name: Heroku container login, push, releas e working_directory: ap p command: | set - x ls - a heroku container:logi n heroku container:push web -a $HEROKU_APP_NAM E heroku container:release web -a $HEROKU_APP_NAM E - run : name: Finish deplo y command: | set - x echo "Finish deploy"
  29. % heroku authorizations:creat e Creating OAuth Authorization... don e ..

    . Token: LongStringsFooBarrrrrrrrrrrrr r Updated at: ... (PJOUPPVSQSPKFDUT$JSDMF$*EBTICPBSEBOETFU5XP FOWJSPONFOUWBSJBCMFT 'PSEFUBJMFEJOTUSVDUJPOTPOIPXUPEPUIJT XFDBOSFBE UIFPGGJDJBMEPDVNFOUBUJPOIFSF IUUQTDJSDMFDJDPNEPDTFOWWBSTTFUUJOHBO FOWJSPONFOUWBSJBCMFJOBQSPKFDU )&30,6@"11@/".& 5IJTJTUIFOBNFPGPVS)FSPLVBQQMJDBUJPOUIBUXBT EFDJEFECZUIFAIFSPLVDSFBUFADPNNBOE )&30,6@"1*@,&: &OTVSFXFHFUUIFBVUIFOUJDBUJPOUPLFOXJUIUIF DPNNBOEAIFSPLVBVUIPSJ[BUJPOTDSFBUFA BOESFHJTUFS UIFHFOFSBUFEUPLFOUPPVSQSPKFDUT$JSDMF$*EBTICPBSE BT)&30,6@"1*@,&: 4FU$JSDMF$*FOWJSPONFOU
  30. /PXXFGJOBMMZIBWFBQJQFMJOFUIBU VQEBUFTPVSQSPEVDUJPOFOWJSPONFOUXJUI KVTUBHJUQVTI 5IFEFQMPZQJQFMJOFJTBMNPTUGJOJTIFE BOE UIFHSFFOMJHIUIBTCFFOUVSOFEPO 5BEB &YFDVUFUIF$*BOE$%QJQFMJOF /PX BMMXFIBWFUPEPJTHJUQVTIUPUIFSFNPUF(JU)VCSFQPTJUPSZ

    8IFOXFQVTIUPBEFWFMPQNFOUCSBODI POMZUIFCVJMEKPCSVOT 0ODFUIFCVJMEJTDPNQMFUF XFDBONFSHFJUJOUPPVSNBJOSFQPTJUPSZ"GUFSXFEJEUIFNFSHF PQFSBUJPO CPUICVJMEBOEEFQMPZKPCTBSFSVOOJOH