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

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

53bc8fa21f71dd8e63f3c94275c56191?s=47 ngs
March 07, 2016

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

53bc8fa21f71dd8e63f3c94275c56191?s=128

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/
  2. None
  3. None
  4. @ngs

  5. None
  6. None
  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
  8. None
  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

  10. $ sbt assembly $ java -jar myapp.jar $ curl http://0.0.0.0:8080

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

    OK
  12. None
  13. None
  14. swift build .build/debug/Swifton-TodoApp open http://0.0.0.0:8000/todos

  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" }] }
  16. FROM ubuntu:14.04 MAINTAINER saulius@necolt.com 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
  17. FROM ubuntu:14.04 MAINTAINER saulius@necolt.com 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
  18. FROM ubuntu:14.04 MAINTAINER saulius@necolt.com 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
  19. FROM ubuntu:14.04 MAINTAINER saulius@necolt.com 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
  20. None
  21. $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

    <none> <none> sha256:c35f9 30 seconds ago 893.2 MB
  22. $ swift build --configuration release $ docker build -t $DOCKER_REPO

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

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

  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
  26. $ swift build --configuration release

  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
  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
  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
  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
  31. $ cat .dockerignore * !Views !swift/usr/lib/swift/linux/*.so !.build/release/Swifton-TodoApp

  32. FROM ubuntu:14.04 MAINTAINER a@ngs.io 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
  33. FROM ubuntu:14.04 MAINTAINER a@ngs.io 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
  34. FROM ubuntu:14.04 MAINTAINER a@ngs.io 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
  35. FROM ubuntu:14.04 MAINTAINER a@ngs.io 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
  36. FROM ubuntu:14.04 MAINTAINER a@ngs.io 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
  37. None
  38. $ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

    <none> <none> sha256:c35f9 2 minutes ago 893.2 MB <none> <none> sha256:0d31d 30 seconds ago 245.8 MB
  39. None
  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 '<h1>Listing Todos</h1>' } 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 '<h1>Listing Todos</h1>' } its(:stdout) { is_expected.to contain '<td>Test1</td>' } its(:stdout) { is_expected.to contain '<td>Test2</td>' } its(:stdout) { is_expected.to contain '<td><a href="/todos/0">Show</a></td>' } its(:stdout) { is_expected.to contain '<td><a href="/todos/1">Show</a></td>' } end
  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 "<h1>Listing Todos</h1>" 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 "<h1>Listing Todos</h1>" stdout should contain "<td>Test1</td>" stdout should contain "<td>Test2</td>"
  42. $ docker tag $DOCKER_REPO "${DOCKER_REPO}:b${CIRCLE_BUILD_NUM}" $ docker push "${DOCKER_REPO}:b${CIRCLE_BUILD_NUM}"

  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 .
  44. ଟँ