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

Swift で開発した Web アプリケーションを Amazon EC2 Container Services で運用する

ngs
March 07, 2016

Swift で開発した Web アプリケーションを Amazon EC2 Container Services で運用する

ngs

March 07, 2016
Tweet

More Decks by ngs

Other Decks in Technology

Transcript

  1. Swift Ͱ։ൃͨ͠
    Web ΞϓϦέʔγϣϯΛ
    Amazon EC2 Container Services Ͱӡ༻͢Δ
    Atsushi Nagase
    @ngs / http://ja.ngs.io/
    https://one-team.com/products/

    View Slide

  2. View Slide

  3. View Slide

  4. @ngs

    View Slide

  5. View Slide

  6. View Slide

  7. BUILD
    • sbt assembly
    • docker build
    TEST
    • sbt test:test
    • cd serverspec && rspec
    DEPLOY
    • docker push
    • aws ecs register-task-definition
    • aws ecs update-service

    View Slide

  8. View Slide

  9. Kitsura
    https://developer.ibm.com/swift/products/kitura/
    Nest
    https://github.com/nestproject/Nest
    Perfect
    http://perfect.org/
    Slimane
    https://github.com/noppoMan/Slimane
    Swifton
    https://github.com/necolt/Swifton

    View Slide

  10. $ sbt assembly
    $ java -jar myapp.jar
    $ curl http://0.0.0.0:8080
    HTTP/1.1 200 OK

    View Slide

  11. $ swift build
    $ .build/release/MyApp
    $ curl http://0.0.0.0:8000
    HTTP/1.1 200 OK

    View Slide

  12. View Slide

  13. View Slide

  14. swift build
    .build/debug/Swifton-TodoApp
    open http://0.0.0.0:8000/todos

    View Slide

  15. $ cat Procfile
    web: Swifton-TodoApp --workers 3 --bind 0.0.0.0:$PORT
    $ cat app.json
    {
    "name": "Swifton TodoApp Example",
    "description": "An example TodoApp using Swifton web framework on Heroku.",
    "repository": "https://github.com/necolt/Swifton-TodoApp",
    "website": "https://github.com/necolt/Swifton-TodoApp",
    "keywords": [“swifton", "curassow"],
    "buildpacks": [{
    "url": “https://github.com/kylef/heroku-buildpack-swift"
    }]
    }

    View Slide

  16. FROM ubuntu:14.04
    MAINTAINER [email protected]
    ENV SWIFT_BRANCH development
    ENV SWIFT_VERSION DEVELOPMENT-SNAPSHOT-2016-02-08-a
    ENV SWIFT_PLATFORM ubuntu14.04
    RUN apt-get update && \
    apt-get install -y build-essential wget clang libedit-dev python2.7 python2.7-dev libicu52 rsync libxml2 git && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    RUN wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - && \
    gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift
    RUN SWIFT_ARCHIVE_NAME=swift-$SWIFT_VERSION-$SWIFT_PLATFORM && \
    SWIFT_URL=https://swift.org/builds/$SWIFT_BRANCH/$(echo "$SWIFT_PLATFORM" | tr -d .)/swift-$SWIFT_VERSION/
    $SWIFT_ARCHIVE_NAME.tar.gz && \
    wget $SWIFT_URL && \
    wget $SWIFT_URL.sig && \
    gpg --verify $SWIFT_ARCHIVE_NAME.tar.gz.sig && \
    tar -xvzf $SWIFT_ARCHIVE_NAME.tar.gz --directory / --strip-components=1 && \
    rm -rf $SWIFT_ARCHIVE_NAME* /tmp/* /var/tmp/*
    ENV PATH /usr/bin:$PATH
    RUN mkdir -p /swifton
    WORKDIR /swifton
    ADD . /swifton
    RUN swift build --configuration release
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  17. FROM ubuntu:14.04
    MAINTAINER [email protected]
    ENV SWIFT_BRANCH development
    ENV SWIFT_VERSION DEVELOPMENT-SNAPSHOT-2016-02-08-a
    ENV SWIFT_PLATFORM ubuntu14.04
    RUN apt-get update && \
    apt-get install -y build-essential wget clang libedit-dev python2.7 python2.7-dev libicu52 rsync libxml2 git && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    RUN wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - && \
    gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift
    RUN SWIFT_ARCHIVE_NAME=swift-$SWIFT_VERSION-$SWIFT_PLATFORM && \
    SWIFT_URL=https://swift.org/builds/$SWIFT_BRANCH/$(echo "$SWIFT_PLATFORM" | tr -d .)/swift-$SWIFT_VERSION/
    $SWIFT_ARCHIVE_NAME.tar.gz && \
    wget $SWIFT_URL && \
    wget $SWIFT_URL.sig && \
    gpg --verify $SWIFT_ARCHIVE_NAME.tar.gz.sig && \
    tar -xvzf $SWIFT_ARCHIVE_NAME.tar.gz --directory / --strip-components=1 && \
    rm -rf $SWIFT_ARCHIVE_NAME* /tmp/* /var/tmp/*
    ENV PATH /usr/bin:$PATH
    RUN mkdir -p /swifton
    WORKDIR /swifton
    ADD . /swifton
    RUN swift build --configuration release
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  18. FROM ubuntu:14.04
    MAINTAINER [email protected]
    ENV SWIFT_BRANCH development
    ENV SWIFT_VERSION DEVELOPMENT-SNAPSHOT-2016-02-08-a
    ENV SWIFT_PLATFORM ubuntu14.04
    RUN apt-get update && \
    apt-get install -y build-essential wget clang libedit-dev python2.7 python2.7-dev libicu52 rsync libxml2 git && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    RUN wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - && \
    gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift
    RUN SWIFT_ARCHIVE_NAME=swift-$SWIFT_VERSION-$SWIFT_PLATFORM && \
    SWIFT_URL=https://swift.org/builds/$SWIFT_BRANCH/$(echo "$SWIFT_PLATFORM" | tr -d .)/swift-$SWIFT_VERSION/
    $SWIFT_ARCHIVE_NAME.tar.gz && \
    wget $SWIFT_URL && \
    wget $SWIFT_URL.sig && \
    gpg --verify $SWIFT_ARCHIVE_NAME.tar.gz.sig && \
    tar -xvzf $SWIFT_ARCHIVE_NAME.tar.gz --directory / --strip-components=1 && \
    rm -rf $SWIFT_ARCHIVE_NAME* /tmp/* /var/tmp/*
    ENV PATH /usr/bin:$PATH
    RUN mkdir -p /swifton
    WORKDIR /swifton
    ADD . /swifton
    RUN swift build --configuration release
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  19. FROM ubuntu:14.04
    MAINTAINER [email protected]
    ENV SWIFT_BRANCH development
    ENV SWIFT_VERSION DEVELOPMENT-SNAPSHOT-2016-02-08-a
    ENV SWIFT_PLATFORM ubuntu14.04
    RUN apt-get update && \
    apt-get install -y build-essential wget clang libedit-dev python2.7 python2.7-dev libicu52 rsync libxml2 git && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    RUN wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import - && \
    gpg --keyserver hkp://pool.sks-keyservers.net --refresh-keys Swift
    RUN SWIFT_ARCHIVE_NAME=swift-$SWIFT_VERSION-$SWIFT_PLATFORM && \
    SWIFT_URL=https://swift.org/builds/$SWIFT_BRANCH/$(echo "$SWIFT_PLATFORM" | tr -d .)/swift-$SWIFT_VERSION/
    $SWIFT_ARCHIVE_NAME.tar.gz && \
    wget $SWIFT_URL && \
    wget $SWIFT_URL.sig && \
    gpg --verify $SWIFT_ARCHIVE_NAME.tar.gz.sig && \
    tar -xvzf $SWIFT_ARCHIVE_NAME.tar.gz --directory / --strip-components=1 && \
    rm -rf $SWIFT_ARCHIVE_NAME* /tmp/* /var/tmp/*
    ENV PATH /usr/bin:$PATH
    RUN mkdir -p /swifton
    WORKDIR /swifton
    ADD . /swifton
    RUN swift build --configuration release
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  20. View Slide

  21. $ docker images
    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
    sha256:c35f9 30 seconds ago 893.2 MB

    View Slide

  22. $ swift build --configuration release
    $ docker build -t $DOCKER_REPO .

    View Slide

  23. https://swift.org/download/#latest-development-snapshots

    View Slide

  24. http://blog.circleci.com/trusty-image-public-beta/

    View Slide

  25. $ sudo apt-get install libicu-dev clang-3.6 jq
    $ sudo update-alternatives --install \
    /usr/bin/clang clang /usr/bin/clang-3.6 100
    $ sudo update-alternatives --install \
    /usr/bin/clang++ clang++ /usr/bin/clang++-3.6 100

    View Slide

  26. $ swift build --configuration release

    View Slide

  27. .
    |-- .build
    | `-- release
    | `-- Swifton-TodoApp
    |-- Views
    | `-- Todos
    | |-- Edit.html.stencil
    | |-- Index.html.stencil
    | |-- New.html.stencil
    | `-- Show.html.stencil
    `-- swift
    `-- usr
    `-- lib
    `-- swift
    `-- linux
    |-- libFoundation.so
    |-- libXCTest.so
    |-- libswiftCore.so
    |-- libswiftGlibc.so
    `-- libswiftSwiftOnoneSupport.so

    View Slide

  28. .
    |-- .build
    | `-- release
    | `-- Swifton-TodoApp
    |-- Views
    | `-- Todos
    | |-- Edit.html.stencil
    | |-- Index.html.stencil
    | |-- New.html.stencil
    | `-- Show.html.stencil
    `-- swift
    `-- usr
    `-- lib
    `-- swift
    `-- linux
    |-- libFoundation.so
    |-- libXCTest.so
    |-- libswiftCore.so
    |-- libswiftGlibc.so
    `-- libswiftSwiftOnoneSupport.so

    View Slide

  29. .
    |-- .build
    | `-- release
    | `-- Swifton-TodoApp
    |-- Views
    | `-- Todos
    | |-- Edit.html.stencil
    | |-- Index.html.stencil
    | |-- New.html.stencil
    | `-- Show.html.stencil
    `-- swift
    `-- usr
    `-- lib
    `-- swift
    `-- linux
    |-- libFoundation.so
    |-- libXCTest.so
    |-- libswiftCore.so
    |-- libswiftGlibc.so
    `-- libswiftSwiftOnoneSupport.so

    View Slide

  30. .
    |-- .build
    | `-- release
    | `-- Swifton-TodoApp
    |-- Views
    | `-- Todos
    | |-- Edit.html.stencil
    | |-- Index.html.stencil
    | |-- New.html.stencil
    | `-- Show.html.stencil
    `-- swift
    `-- usr
    `-- lib
    `-- swift
    `-- linux
    |-- libFoundation.so
    |-- libXCTest.so
    |-- libswiftCore.so
    |-- libswiftGlibc.so
    `-- libswiftSwiftOnoneSupport.so

    View Slide

  31. $ cat .dockerignore
    *
    !Views
    !swift/usr/lib/swift/linux/*.so
    !.build/release/Swifton-TodoApp

    View Slide

  32. FROM ubuntu:14.04
    MAINTAINER [email protected]
    RUN apt-get update && apt-get install -y libicu52 libxml2 curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    ENV APP_DIR /var/www/app
    RUN mkdir -p ${APP_DIR}
    WORKDIR ${APP_DIR}
    ADD . ${APP_DIR}
    RUN ln -s ${APP_DIR}/swift/usr/lib/swift/linux/*.so /usr/lib
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  33. FROM ubuntu:14.04
    MAINTAINER [email protected]
    RUN apt-get update && apt-get install -y libicu52 libxml2 curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    ENV APP_DIR /var/www/app
    RUN mkdir -p ${APP_DIR}
    WORKDIR ${APP_DIR}
    ADD . ${APP_DIR}
    RUN ln -s ${APP_DIR}/swift/usr/lib/swift/linux/*.so /usr/lib
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  34. FROM ubuntu:14.04
    MAINTAINER [email protected]
    RUN apt-get update && apt-get install -y libicu52 libxml2 curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    ENV APP_DIR /var/www/app
    RUN mkdir -p ${APP_DIR}
    WORKDIR ${APP_DIR}
    ADD . ${APP_DIR}
    RUN ln -s ${APP_DIR}/swift/usr/lib/swift/linux/*.so /usr/lib
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  35. FROM ubuntu:14.04
    MAINTAINER [email protected]
    RUN apt-get update && apt-get install -y libicu52 libxml2 curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    ENV APP_DIR /var/www/app
    RUN mkdir -p ${APP_DIR}
    WORKDIR ${APP_DIR}
    ADD . ${APP_DIR}
    RUN ln -s ${APP_DIR}/swift/usr/lib/swift/linux/*.so /usr/lib
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  36. FROM ubuntu:14.04
    MAINTAINER [email protected]
    RUN apt-get update && apt-get install -y libicu52 libxml2 curl && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
    ENV APP_DIR /var/www/app
    RUN mkdir -p ${APP_DIR}
    WORKDIR ${APP_DIR}
    ADD . ${APP_DIR}
    RUN ln -s ${APP_DIR}/swift/usr/lib/swift/linux/*.so /usr/lib
    EXPOSE 8000
    CMD .build/release/Swifton-TodoApp

    View Slide

  37. View Slide

  38. $ docker images
    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
    sha256:c35f9 2 minutes ago 893.2 MB
    sha256:0d31d 30 seconds ago 245.8 MB

    View Slide

  39. View Slide

  40. require 'spec_helper'
    describe port(8000) do
    it { should be_listening }
    end
    describe command('curl -i -s -H \'Accept: text/html\' http://0.0.0.0:8000/') do
    its(:exit_status) { is_expected.to eq 0 }
    its(:stdout) { is_expected.to contain 'HTTP/1.1 200 OK' }
    its(:stdout) { is_expected.to contain 'Listing Todos' }
    end
    1.upto(2) do|n|
    describe command("curl -i -s -H \'Accept: text/html\' http://0.0.0.0:8000/todos -d \'title=Test#{n}\'") do
    its(:exit_status) { is_expected.to eq 0 }
    its(:stdout) { is_expected.to contain 'HTTP/1.1 302 FOUND' }
    its(:stdout) { is_expected.to contain 'Location: /todos' }
    end
    end
    describe command('curl -i -s -H \'Accept: text/html\' http://0.0.0.0:8000/todos') do
    its(:exit_status) { is_expected.to eq 0 }
    its(:stdout) { is_expected.to contain 'HTTP/1.1 200 OK' }
    its(:stdout) { is_expected.to contain 'Listing Todos' }
    its(:stdout) { is_expected.to contain 'Test1' }
    its(:stdout) { is_expected.to contain 'Test2' }
    its(:stdout) { is_expected.to contain 'Show' }
    its(:stdout) { is_expected.to contain 'Show' }
    end

    View Slide

  41. $ cd serverspec && export DOCKER_CONTAINER=serverspec && bundle exec rspec
    Port "8000"
    should be listening
    Command "curl -i -s -H 'Accept: text/html' http://0.0.0.0:8000/"
    exit_status
    should eq 0
    stdout
    should contain "HTTP/1.1 200 OK"
    stdout
    should contain "Listing Todos"
    Command "curl -i -s -H 'Accept: text/html' http://0.0.0.0:8000/todos -d 'title=Test1'"
    exit_status
    should eq 0
    stdout
    should contain "HTTP/1.1 302 FOUND"
    stdout
    should contain "Location: /todos"
    Command "curl -i -s -H 'Accept: text/html' http://0.0.0.0:8000/todos -d 'title=Test2'"
    exit_status
    should eq 0
    stdout
    should contain "HTTP/1.1 302 FOUND"
    stdout
    should contain "Location: /todos"
    Command "curl -i -s -H 'Accept: text/html' http://0.0.0.0:8000/todos"
    exit_status
    should eq 0
    stdout
    should contain "HTTP/1.1 200 OK"
    stdout
    should contain "Listing Todos"
    stdout
    should contain "Test1"
    stdout
    should contain "Test2"

    View Slide

  42. $ docker tag $DOCKER_REPO "${DOCKER_REPO}:b${CIRCLE_BUILD_NUM}"
    $ docker push "${DOCKER_REPO}:b${CIRCLE_BUILD_NUM}"

    View Slide

  43. #!/bin/sh
    set -eu
    APP_NAME=swifton-example-
    UPPER_ENV_NAME=$(echo $ENV_NAME | awk '{print toupper($0)}')
    CLUSTER="${APP_NAME}${ENV_NAME}"
    TASK_FAMILY="${APP_NAME}${ENV_NAME}"
    SERVICE_NAME="${APP_NAME}service-${ENV_NAME}"
    LOADBALANCER_NAME="${APP_NAME}${ENV_NAME}"
    CONTAINER_PORT=8000
    CONTAINER_NAME=$CONTAINER_NAME CONTAINER_PORT=$CONTAINER_PORT APP_NAME=$APP_NAME \
    erb ecs-task-definitions/service.json.erb > .ecs-task-definition.json
    TASK_DEFINITION_JSON=$(aws ecs register-task-definition --family $TASK_FAMILY \
    --cli-input-json "file://$(pwd)/.ecs-task-definition.json")
    TASK_REVISION=$(echo $TASK_DEFINITION_JSON | jq .taskDefinition.revision)
    SERVICE_JSON=$(aws ecs describe-services --services $SERVICE_NAME --cluster $CLUSTER)
    if [ $(echo $SERVICE_JSON | jq '.services | length') = "0" ]; then
    SERVICE_JSON=$(aws ecs create-service --cluster ${CLUSTER} --service ${SERVICE_NAME} \
    --task-definition ${TASK_FAMILY}:${TASK_REVISION} --desired-count 1 \
    --load-balancers loadBalancerName=${LOADBALANCER_NAME},containerName=${CONTAINER_NAME},containerPort=$
    {CONTAINER_PORT} --role ecs-operation)
    else
    DESIRED_COUNT=$(echo $SERVICE_JSON | jq '.services[0].desiredCount')
    if [ ${DESIRED_COUNT} = "0" ]; then
    DESIRED_COUNT="1"
    fi
    SERVICE_JSON=$(aws ecs update-service --cluster ${CLUSTER} --service ${SERVICE_NAME} --task-definition $
    {TASK_FAMILY}:${TASK_REVISION} --desired-count ${DESIRED_COUNT})
    fi
    echo $SERVICE_JSON | jq .

    View Slide

  44. ଟँ

    View Slide