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

    View Slide

  2. Welcome to

    View Slide

  3. 4VNNBSZ
    5IJTUBMLTIPXTIPXXFDSFBUFB
    b$BTVBM`BOENJOJNBMJTUJDXFCTJUFPG
    LPLVSBFY BMPDBM&MJYJSDPNNVOJUZJO
    +BQBO XJUI1IPFOJY BOEQVCMJTIJU
    *`MMTIPXXIBULPLVSBFY`TBDUJWJUJFT
    MBUFS

    View Slide

  4. *XJMMJOGPSNB63-PG
    UIFTFTMJEFTGPSNZUBML
    MBUFSCZUXFFU
    !JN@NJPMBC

    View Slide

  5. 5IJTUBMLGPDVTPOUIFOFYUQSPDFTT
    'PSb$BTVBM`BOERVJDLMZSFMFBTFBNJOJNBMJTUJD1IPFOJYXFCTJUF
    1SFQBSFUIF1IPFOJYQSPKFDUCZOPFDUPXJUI%PDLFS
    "EBQU$44MBZPVUCZ5BJMXJOE$44
    1VUJUPO)FSPLV1BB4UPSFMFBTFUIFXFCTJUFUPUIFQVCMJD
    1SFQBSFUPCVJME$*BOE$%UPNBLFPQFSBUJPOTFBTJFSCZVTJOH
    $JSDMF$*WJB(JU)VC

    View Slide

  6. 5IJTUBMLEPFT/05GPDVTPOUIFOFYUQSPDFTT
    5IFGPMMPXJOHJTBDUVBMMZJNQMFNFOUFEBOEFYFDVUFE CVUNVDI
    PGUIFFYQMBOBUJPOJTPNJUUFE
    0QFSBUF(JUNBOBHFNFOU
    *NQMFNFOUNBSLVQ)5.-
    *NQMFNFOUUFTUT

    View Slide

  7. 5IFEJBHSBNPGUIJTTZTUFN
    HJUQVTI
    UP(JU)VC
    %FUFDUJPOPG
    DIBOHFTCZ$JSDMF$*
    #VJMEBOE
    %FQMPZUP)FSPLV
    IUUQTLPLVSBFYIFSPLVBQQDPN
    %PDLFSJNBHF FMJYJSTMJN

    *NQMFNFOUBUJPOXJUI
    1IPFOJY OPFDUP

    5BJMXJOE$44
    .BDIJOF&YFDVUPS
    -JOVY7.

    )FSPLV
    $POUBJOFS3FHJTUPSZ

    View Slide

  8. ':*
    5IF(JU)VCSFNPUFSFQPTJUPSZ63-GPSUIJTQSPKFDUXFIBWF
    JNQMFNFOUFE
    IUUQTHJUIVCDPNNJPMBCLPLVSBFY
    1MFBTFUBLFBMPPLGPSZPVSSFGFSFODF
    5IFDPEFPO(JU)VCJTBEEFEGSPNUIBUBUUIFQSFTFOUBUJPO

    View Slide

  9. BCPVUNF

    View Slide

  10. !JN@NJPMBC
    !JNBJNBccJN
    3ZPUBSP*NBIBTIJ
    JO+BQBO
    *MJWFJO,JUBLZVTIV +BQBO
    *`N
    "XFCEFWFMPQFSPGQJYJW*OD BOE
    "OPSHBOJ[FSPGLPLVSBFY BMPDBM
    &MJYJSDPNNVOJUZ

    View Slide

  11. IUUQTXXXQJYJWOFU
    QJYJW*OD
    QJYJW*ODQSPWJEFTBWBSJFUZ
    PGTFSWJDFTUPTVQQPSU
    DSFBUPST DFOUFSFEPOUIF
    JMMVTUSBUJPODPNNVOJDBUJPO
    TFSWJDFlQJYJWz
    *GZPV`EMJLFUPUSZPVUPVS
    TFSWJDFT QMFBTFEPTP
    IUUQTWSPJEDPNFO

    View Slide

  12. .ZGBWPSJUFDPOUFOUT
    .ZNBJOGBWPSJUFDPOUFOUTBSFGPMMPXJOHT
    "OJNF
    /FPO(FOFTJT&WBOHFMJPO
    "UUBDLUIF5JUBO
    %FNPO4MBZFS,JNFUTVOP:BJCB
    'VMMNFUBM"MDIFNJTU BMDIFNJTU

    /BUTVNFT#PPLPG'SJFOET
    7JPMFU&WFSHBSEFO
    .VTJD
    "WJDJJ
    ;FEE
    4UFWF3FJDI
    "OENPSF

    View Slide

  13. .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

    View Slide

  14. BCPVULPLVSBFY

    View Slide

  15. lLPLVSBFYzJTBDPNNVOJUZ
    UIBUQSPNPUFTUIF&MJYJS
    QSPHSBNNJOHMBOHVBHFBOEJUT
    XFCBQQMJDBUJPOGSBNFXPSL
    1IPFOJY JO,JUBLZVTIV XIFSF
    CPUIIJHITQFFEQSPDFTTJOH
    QFSGPSNBODFBOEIJHI
    EFWFMPQNFOUFGGJDJFODZDBO
    CFBDIJFWFE
    LPLVSBFY

    View Slide

  16. 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

    View Slide

  17. LPLVSBFYBDUJWJUZ
    044DPOUSJCVUJPO
    LPLVSBFYBOE1FMFNBZ.FFUVQ B
    +BQBOFTF&MJYJSDPNNVOJUZ USZUP
    DPOUSJCVUF044 FTQFDJBMMZ /Y &9-"
    BOE#FBN"TN XIJDISFBMJ[FIJHI
    TQFFEQSPDFTTJOHQFSGPSNBODF
    1FMFNBZ.FFUVQ
    IUUQTQFMFNBZDPOOQBTTDPNFWFOU

    View Slide

  18. $IBQUFS
    $IFDLJOHUIFEFWFMPQNFOU
    FOWJSPONFOUBOE
    CFHJOOJOHPGUIFTUPSZ

    View Slide

  19. 5IFWFSJGJFEWFSTJPOTPGUIJTUBML
    5IFEFWFMPQNFOUNBDIJOFGPSUIJTUBMLJTB.BD*OUFM WFSTJPO#JH
    4VS BOEFBDIWFSJGJFEWFSTJPOTPGUFDIOPMPHJFTBSFBTGPMMPXT
    &MJYJS &SMBOH051

    1IPFOJY
    /PEFKT
    5BJMXJOE$44

    View Slide

  20. 5IFWFSJGJFEWFSTJPOTPGUIJTUBML
    5IFEFWFMPQNFOUNBDIJOFGPSUIJTUBMLJTB.BD*OUFM WFSTJPO#JH
    4VS BOEFBDIWFSJGJFEWFSTJPOTPGUFDIOPMPHJFTBSFBTGPMMPXT
    &MJYJS &SMBOH051

    1IPFOJY
    /PEFKT
    5BJMXJOE$44

    View Slide

  21. 5IFWFSJGJFEWFSTJPOTPGUIJTUBML
    1IPFOJY

    View Slide

  22. /PX MFUTTUBSUXJUIUIFDPOUFOUTPGUIJTUBML

    View Slide

  23. UJUMFEXJUI&MJDB`T"EWFOUVSFT
    JO1IPFOJYMBOE
    /PX MFUTTUBSUXJUIUIFDPOUFOUTPGUIJTUBML

    View Slide

  24. *OUSPEVDJOHUIFNBJODIBSBDUFS

    View Slide

  25. .BJO"DUPS
    /05NFBOTBDUPSPGDPODVSSFODZ
    FYFDVUJOHTZTUFN

    View Slide

  26. .BJO"DUPS
    &MJDB BO&MJYJSMPWFSEFWFMPQFS
    /05NFBOTBDUPSPGDPODVSSFODZ
    FYFDVUJOHTZTUFN

    View Slide

  27. .BJO"DUPS
    &MJDB BO&MJYJSMPWFSEFWFMPQFS
    TIFXBOUTUPDSFBUFBUFDI
    DPNNVOJUZTJUFDBTVBMMZ
    /05NFBOTBDUPSPGDPODVSSFODZ
    FYFDVUJOHTZTUFN

    View Slide

  28. 8JSFGSBNFPGUIFTJUF
    XJTIGVMUIJOLJOH

    ( ´ʔ`)ɻоʢ

    View Slide

  29. 8JSFGSBNFPGUIFTJUF
    XJTIGVMUIJOLJOH

    ( ´ʔ`)ɻоʢ

    View Slide

  30. 8IJUF3BCCJUBMTPTBJE
    *NMBUF *NMBUF *NMBUFz

    *XBOOBNBLFJUNVDI
    RVJDLFSBOEFBTJFS

    View Slide

  31. *XBOOBPQFSBUF
    DPOUJOVPVTEFMJWFSZ
    XJUIFBTF

    View Slide

  32. #58 *`WFOFWFSVTFEB
    XFC1IPFOJYGSBNFXPSL
    CVU*IFBSEJU`TOJDFGPS
    UIJTTJUVBUJPO

    View Slide

  33. "OE UIF1IPFOJYWFSTJPOXBTSFMFBTFE
    UIFMBTUNPOUI

    View Slide

  34. *U`TQFSGFDUUJNJOH JTO`UJU

    View Slide

  35. 0, MFU`TTUBSU
    1IPFOJYXJUINF

    View Slide

  36. $IBQUFS
    TFUVQPG1IPFOJY

    View Slide

  37. 8IBUUIJTDIBQUFSDPWFST
    8FXJMMSVOUISPVHIUIFQSPDFTT
    GSPNCVJMEJOHUIF%PDLFS
    EFWFMPQNFOUFOWJSPONFOUUPCVJMEJOH
    1IPFOJY
    BOEEJTQMBZJOHUIFGJSTUl8FMDPNFUP
    1IPFOJYzTDSFFO
    4UFQT
    1SFQBSFEPDLFSGJMFT
    &YFDVUFAEPDLFSDPNQPTFCVJMEA
    *OTUBMM1IPFOJYGSBNFXPSL

    View Slide

  38. % 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

    View Slide

  39. [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
    "

    View Slide

  40. % docker compose build
    "GUFSQSFQBSFEEPDLFSGJMFT
    MFU`TFYFDVUF
    AEPDLFSDPNQPTFCVJMEA
    &YFDVUFAEPDLFSDPNQPTFCVJMEA

    View Slide

  41. % 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

    View Slide

  42. % 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

    View Slide

  43. "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]
    ,

    View Slide

  44. /PX XFFYFDVUFEPDLFSDPNQPTFVQBOE
    MPPLMPDBMIPTUJOCSPXTFS
    *OTUBMM1IPFOJYGSBNFXPSL

    View Slide

  45. *OTUBMM1IPFOJYGSBNFXPSL
    :FT XFEJEJU
    8FHPUUIFQSPPGUIBUUIFTDSFFO
    TIPXFEVQl8FMDPNFUP1IPFOJYz
    5IFGJSTUNJTTJPOXBTDPNQMFUFE

    View Slide

  46. $IBQUFS
    "EBQU$44MBZPVUCZ
    5BJMXJOE$44

    View Slide

  47. 8IBUUIJTDIBQUFSDPWFST
    5PQSFQBSFUIFMBZPVUXJUIFBTF XFXJMMVTF
    5BJMXJOE$44
    *OUIJTTFDUJPO XFXJMMGPDVTPOUIFTFUVQBOE
    JOUSPEVDUJPOPG5BJMXJOEJNQMFNFOUBUJPO
    8FXJMMBMTPFYQMBJOXFCTJUFDPOUFOUDSFBUJPO
    BOEQBHFUSBOTJUJPOT CVUXFXJMM/05FYQMBJO
    NVDIBOETLJQBCPVUNBSLVQ UFTUT BOEPUIFS
    JNQMFNFOUBUJPOEFUBJMT
    4UFQT
    *OTUBMM/PEFKT
    1SFQBSF5BJMXJOE$44FOWJSPONFOU
    1SFQBSFFBDISPVUFQBHFBOENBSLVQ
    4FUUBJMXJOEDMBTTJOMJOFDPEF

    View Slide

  48. 5IFNBJOSFBTPOJTUIBUCZ
    BEPQUJOH5BJMXJOE$44 B
    VUJMJUZGJSTU$44GSBNFXPSL
    XFXJMMCFBCMFUPNBLFHPPE
    QSPHSFTTJOPVSNJTTJPOUP
    RVJDLMZTFUMBZPVUTUZMFT
    XJUIPVUXSJUJOHSBX$44
    8IZXFDIPJDF5BJMXJOE$44
    IUUQTUBJMXJOEDTTDPN

    View Slide

  49. 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

    View Slide

  50. '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

    View Slide

  51. 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

    View Slide

  52. /PXMFU`TTUBSUSFSVOOJOHDPOUBJOFSTCZ
    AEPDLFSDPNQPTFVQABOEDIFDLSFTVMUTJO
    PVSCSPXTFS
    8JUIUIFJNQMFNFOUBUJPOFOWJSPONFOUPG
    5BJMXJOE$44JOQMBDF UIFEFGBVMU$44TUZMF
    PG1IPFOJYIBTCFFOSFNPWFE
    /PXMFUTUSZPOFJNQMFNFOUBUJPOPG5BJMXJOE
    $44GSPNUIJTTUBUF
    1SFQBSF5BJMXJOE$44FOWJSPONFOU

    View Slide

  53. "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
    ]

    >

    - <%= gettext "Welcome to %{name}!", name: "Phoenix" %>>

    + <%= gettext "Welcome to %{name}!",
    name: "Phoenix" %>>

    Peace of mind from prototype to production

    View Slide

  54. /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
    ]

    About
    [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

    View Slide

  55. -FUTUBLFBMPPLBUUIFlBCPVUzQBHF
    XIJDIIBTKVTUCFFOCPSO
    *UJTJOBQMBJOTUBUFXJUIOP$44DMBTTFT
    BQQMJFEZFU
    'SPNIFSF XFDSFBUFUIFDPOUFOU
    JODMVEJOHUFYUBOEJNBHFT UPTFUUIF
    MBZPVU
    8FXPOUHPJOUPUIFEFUBJMTIFSF
    5IFTPVOEPGBDMPDLUJDLJOHXIJMF
    NBSLVQJTCFJOHEPOFʜ

    1SFQBSFFBDISPVUFQBHFBOENBSLVQ
    (localhost:4000/about)

    View Slide

  56. 4FUUBJMXJOEDMBTTJOMJOFDPEF
    *XJMMDBTUB
    5BJMXJOE$44TQFMMʜ

    View Slide

  57. 4FUUBJMXJOEDMBTTJOMJOFDPEF
    8FXJMMMFUZPVLOPXUIFSFTVMUTTPPOMBUFS
    -FUTMPPLGPSXBSEUPJU

    View Slide

  58. $IBQUFS
    1VUJUPO)FSPLVUPSFMFBTF
    UIFXFCTJUFUPUIFQVCMJD

    View Slide

  59. 8IBUUIJTDIBQUFSDPWFST
    )FSPLVJTBOJDF1BB4GPSFBTZ
    BQQMJDBUJPOSFMFBTF
    *UTVQQPSUT&MJYJS PGDPVSTF
    0VSXFCTJUFJTCVJMUPOEPDLFS BOEXF
    XJMMUSZUPEFQMPZJUVTJOH)FSPLVT
    DPOUBJOFSSFHJTUSZTZTUFN
    4UFQT
    8IZEJEXFDIPPTF)FSPLV
    4FUVQPG1IPFOJYGPSSFMFBTF
    4FUVQPG)FSPLV
    %FQMPZ

    View Slide

  60. 8IZEJEXFDIPPTF)FSPLV
    *UTCFDBVTF JOBOVUTIFMM
    XF`SFVTFEUPVTJOH)FSPLV1BB4
    4P MFU`TTUBSUUIFTFUVQ

    View Slide

  61. 8IZEJEXFDIPPTF)FSPLV
    4FUVQJOQSPHSFTTʜʜ

    View Slide

  62. 8IZEJEXFDIPPTF)FSPLV
    4FUVQJOQSPHSFTTʜʜ
    0I OP

    View Slide

  63. 8IZEJEXFDIPPTF)FSPLV
    )FZ XBJUBNJOVUF
    *UIJOL*DBVHIUBHMJNQTFPGB1BB4UIBU
    MPPLTHPPE

    View Slide

  64. IUUQTGMZJP

    View Slide

  65. 8IZEJEXFDIPPTF)FSPLV
    l'MZJPz
    0I EFBS
    /P *EJEOUTFFBOZUIJOH
    *WFBMSFBEZTUBSUFEUPCVJMEJUPO)FSPLV
    TP*MMSFMFBTFJUUIFSFBOEUIFOCVJMEJUBHBJOPO
    'MZJPʜ

    View Slide

  66. 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")
    ,


    View Slide

  67. 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:
    [


    View Slide

  68. /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

    View Slide

  69. /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


    View Slide

  70. /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

    View Slide

  71. &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

    View Slide

  72. 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

    View Slide

  73. %FQMPZ
    8FXJMMMFUZPVLOPXUIFSFTVMUTTPPOMBUFS
    -FUTMPPLGPSXBSEUPJU
    cEFKBWV%

    View Slide

  74. $IBQUFS
    4FUVQ$*BOE$%CZVTJOH
    $JSDMF$*

    View Slide

  75. 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

    View Slide

  76. 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

    View Slide

  77. (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

    View Slide

  78. (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)

    View Slide

  79. (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"

    View Slide

  80. % 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

    View Slide

  81. /PXXFGJOBMMZIBWFBQJQFMJOFUIBU
    VQEBUFTPVSQSPEVDUJPOFOWJSPONFOUXJUI
    KVTUBHJUQVTI
    5IFEFQMPZQJQFMJOFJTBMNPTUGJOJTIFE BOE
    UIFHSFFOMJHIUIBTCFFOUVSOFEPO
    5BEB
    &YFDVUFUIF$*BOE$%QJQFMJOF
    /PX BMMXFIBWFUPEPJTHJUQVTIUPUIFSFNPUF(JU)VCSFQPTJUPSZ
    8IFOXFQVTIUPBEFWFMPQNFOUCSBODI POMZUIFCVJMEKPCSVOT
    0ODFUIFCVJMEJTDPNQMFUF XFDBONFSHFJUJOUPPVSNBJOSFQPTJUPSZ"GUFSXFEJEUIFNFSHF
    PQFSBUJPO CPUICVJMEBOEEFQMPZKPCTBSFSVOOJOH

    View Slide

  82. &YFDVUFUIF$*BOE$%QJQFMJOF
    8FXJMMMFUZPVLOPXUIFSFTVMUTTPPOMBUFS
    -FUTMPPLGPSXBSEUPJUʜ

    View Slide

  83. &YFDVUFUIF$*BOE$%QJQFMJOF
    8FXJMMMFUZPVLOPXUIFSFTVMUTTPPOMBUFS
    -FUTMPPLGPSXBSEUPJUʜ
    /P XFSFOPUɹ/PXJTUIFSJHIUUJNF
    5IFUJNFIBTDPNF

    View Slide

  84. 5IJTJTJU

    View Slide

  85. 5IJTJTJU
    IUUQTLPLVSBFYIFSPLVBQQDPN

    View Slide

  86. :FBI
    8FEJEJU

    View Slide

  87. 5IFGJSTUHPBMXFTFU
    XFXFSFBCMFUP
    BDDPNQMJTITNPPUIMZ

    View Slide

  88. "OEXFIPQFUPHSPX
    JUJOUIFGVUVSF

    View Slide

  89. *JNBHJOFTVDI
    BGVUVSFUFDINFFUVQ
    3FBMUJNFDPEF
    TIBSJOH
    &WFOUOPUJGJFS
    #MPH
    $IBUUJOH
    FUDʜ
    ( ´ʔ`)ɻоʢ

    View Slide

  90. *JNBHJOFTVDI
    BGVUVSFUFDINFFUVQ
    3FBMUJNFDPEF
    TIBSJOH
    &WFOUOPUJGJFS
    #MPH
    $IBUUJOH
    FUDʜ
    ( ´ʔ`)ɻоʢ

    View Slide

  91. 3FBMUJNFʜ
    0GDPVSTF -JWF7JFX
    3JHIU

    View Slide

  92. 8JUI-JWF7JFX JUXJMMCFFBTZBOE
    TNBSUUPDSFBUFSFBMUJNFDPEF
    TIBSJOH XPOUJU

    View Slide

  93. *DBOUTUPQESFBNJOH

    View Slide

  94. "MMSJHIU *`MMSFMFBTFBMPUPGGFBUVSFTJOUIF
    1IPFOJYGSBNFXPSL
    -FUTEPJU
    *MPWF1IPFOJY
    *MPWF&MJYJS
    *MPWFGMZJP *IBWFOUVTFEJUZFUʜ

    View Slide

  95. *NBHJOBUJPOJTUIFPOMZXFBQPO
    JOUIFXBSBHBJOTUSFBMJUZ
    *TOUUIBUSJHIU $IFTIJSF$BU

    View Slide

  96. "OE PIGSJFOET
    XFBSFBMM"MJDF XIPVTFT&MJYJSUP
    SFGJOFPVSJNBHJOBUJPOBOESJEF
    UIF1IPFOJYGSPNUIFMBOEPG
    JNBHJOBUJPOUPUIFSFBMXPSMEBU
    XJMM

    View Slide

  97. LPLVSBFY0SHBOJ[FS
    3ZPUBSP*NBIBTIJ !JN@NJPMBC

    'JO
    5IBOLZPVGPSXBUDIJOH
    5IBOLZPVWFSZNVDI

    View Slide