Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Swift で開発した Web アプリケーションを Amazon EC2 Container Services で運用する
ngs
March 07, 2016
Technology
3
3.6k
Swift で開発した Web アプリケーションを Amazon EC2 Container Services で運用する
http://ja.ngs.io/2016/03/04/swift-webapp-on-ecs/
http://connpass.com/event/27667/
ngs
March 07, 2016
Tweet
Share
More Decks by ngs
See All by ngs
Mindstorms NXT Playground Book for iPad
ngs
0
1.3k
Hubot を使って日々のルーチンワークをゼロにする
ngs
3
1.4k
IBM Cloud Tools for Swift
ngs
0
350
WWDC 2016
ngs
2
930
CI2Go
ngs
0
620
Oneteam の開発チームが行っている協同のための工夫 v2016-04-13
ngs
0
1.9k
Oneteam の 少人数で複数プロダクトを 開発する技術的な試行錯誤 #eventdots
ngs
2
2k
Electron アプリのビルド + 配信自動化
ngs
0
2.4k
Kaizen Platform での Hubot 活用事例
ngs
7
4.6k
Other Decks in Technology
See All in Technology
サーバレスECにおける Step Functions の使い方 〜ステートマシン全部見せます!〜
miu_crescent
0
190
データエンジニアと作るデータ文化
yuki_saito
4
1.6k
The Fractal Geometry of Software Design
vladikk
0
890
アーキテクチャを明文化して開発に臨んだ話
akkie76
0
290
サイボウズの アジャイル・クオリティ / Agile Quality at Cybozu
cybozuinsideout
PRO
4
2.3k
セキュリティ 開運研修2022 / security 2022
cybozuinsideout
PRO
3
3.8k
DOM Invader - prototype pollution対応の衝撃 - / DOM Invader - prototype pollution
okuken
0
150
History of the ML system in KARTE
kargo113
1
650
2024卒_freee_エンジニア職(ポテンシャル採用)_説明資料
freee
0
240
マネージャーからみたスクラムと自己管理化
shibe23
0
1k
FoodTechにおける商流・金流・物流の進化/Evolution of Commercial, Financial, and Logistics in FoodTech
dskst
0
400
PUTとPOSTどっち使う?
hankehly
0
260
Featured
See All Featured
Bootstrapping a Software Product
garrettdimon
296
110k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
19
1.4k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
4
510
Bash Introduction
62gerente
597
210k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
37
3.3k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
226
15k
The Language of Interfaces
destraynor
148
20k
Infographics Made Easy
chrislema
233
17k
Put a Button on it: Removing Barriers to Going Fast.
kastner
56
2.3k
Fantastic passwords and where to find them - at NoRuKo
philnash
27
1.5k
A Modern Web Designer's Workflow
chriscoyier
689
180k
Happy Clients
brianwarren
89
5.6k
Transcript
Swift Ͱ։ൃͨ͠ Web ΞϓϦέʔγϣϯΛ Amazon EC2 Container Services Ͱӡ༻͢Δ Atsushi
Nagase @ngs / http://ja.ngs.io/ https://one-team.com/products/
None
None
@ngs
None
None
BUILD • sbt assembly • docker build TEST • sbt
test:test • cd serverspec && rspec DEPLOY • docker push • aws ecs register-task-definition • aws ecs update-service
None
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
$ sbt assembly $ java -jar myapp.jar $ curl http://0.0.0.0:8080
HTTP/1.1 200 OK
$ swift build $ .build/release/MyApp $ curl http://0.0.0.0:8000 HTTP/1.1 200
OK
None
None
swift build .build/debug/Swifton-TodoApp open http://0.0.0.0:8000/todos
$ 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" }] }
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
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
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
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
None
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
<none> <none> sha256:c35f9 30 seconds ago 893.2 MB
$ swift build --configuration release $ docker build -t $DOCKER_REPO
.
https://swift.org/download/#latest-development-snapshots
http://blog.circleci.com/trusty-image-public-beta/
$ 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
$ swift build --configuration release
. |-- .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
. |-- .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
. |-- .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
. |-- .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
$ cat .dockerignore * !Views !swift/usr/lib/swift/linux/*.so !.build/release/Swifton-TodoApp
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
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
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
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
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
None
$ 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
None
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
$ 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>"
$ docker tag $DOCKER_REPO "${DOCKER_REPO}:b${CIRCLE_BUILD_NUM}" $ docker push "${DOCKER_REPO}:b${CIRCLE_BUILD_NUM}"
#!/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 .
ଟँ