目次
私が Gradle を使って Spring Boot の自動デプロイを実現した方法です。 自動というのは リポジトリのフックなどではなく、 自動テストの後のデプロイでもなく、 コマンドでデプロイする方法を指しています。
環境
- gradle 2.10
サーバ環境・デプロイ先は Spring Boot のアプリケーションを AWS EC2 にデプロイする手順 に記載の方法と同じです。
処理内容
自動デプロイには gradle-ssh-plugin
を使います。
今回実現した自動デプロイでは次の順序で処理が行われます。 コマンドは ./gradlew deployWar
です。
- war をコンパイルする。
- サーバの war ファイル を更新する。
- tomcat を再起動する。
コンパイルを省略して、既にコンパイルされている war をデプロイする場合は ./gradlew deployWar -x war
を実行します。
コード
編集したファイルは3つです。 まずは Spring Boot のアプリケーションを AWS EC2 にデプロイする手順 で作成した build.gradle
を変更します。 下でハイライトしているところが変更箇所です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
import groovy.json.JsonSlurper buildscript { ext.kotlin_version = '1.0.0' repositories { mavenCentral() jcenter() } dependencies { classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.2.3.RELEASE' classpath 'org.springframework:springloaded:1.2.1.RELEASE' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'org.hidetake:gradle-ssh-plugin:1.6.0' } } apply plugin: 'java' apply plugin: 'spring-boot' apply plugin: 'kotlin' apply plugin: 'war' apply plugin: 'idea' apply plugin: 'org.hidetake.ssh' war { baseName = 'sample_server' version = '1.0.0' } sourceCompatibility = '1.8' targetCompatibility = '1.8' ssh.settings { dryRun = project.hasProperty('dryRun') } repositories { mavenCentral() } dependencies { compile fileTree(dir: 'libs', include: '*.jar') compile 'org.springframework.boot:spring-boot-starter-web' compile 'org.springframework.boot:spring-boot-starter-thymeleaf' compile 'org.springframework.boot:spring-boot-starter-data-jpa' compile 'mysql:mysql-connector-java:5.1.35' compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile 'net.sf.ehcache:ehcache-core:2.6.11' compile 'org.hibernate:hibernate-ehcache:4.3.8.Final' compile 'org.json:json:20160212' compile 'org.springframework.boot:spring-boot-starter-test' testCompile 'junit:junit:4.12' testCompile 'org.springframework.boot:spring-boot-starter-test' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' } jar.baseName = 'sample_server' sourceSets { main.java.srcDirs += 'src/main/kotlin' } configurations { providedRuntime } processResources { filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [ activeProfiles: project.properties['activeProfiles'] ?: "development" ] } /** * deploy setting */ task deployWar << { JsonSlurper slurper = new JsonSlurper() def deployConfig = slurper.parse(new File('deploy_config.json')) deployConfig.hosts.each { def serverHost = it remotes.create(it) { role 'web_server' host = serverHost user = deployConfig.user identity = file(deployConfig.key) } } ssh.settings { knownHosts = allowAnyHosts } ssh.run { session(remotes.role('web_server')) { put war.getArchivePath().path, "/home/${remote.user}/" executeSudo("cp ~${remote.user}/${war.getArchiveName()} /usr/share/tomcat8/webapps/ROOT.war") executeSudo('chown tomcat:tomcat /usr/share/tomcat8/webapps/ROOT.war') executeSudo "service tomcat8 restart" execute "rm ~/${war.getArchiveName()}" } } } deployWar.dependsOn war |
JSON から設定ファイルを読み込んで、 デプロイ対象サーバを特定します。 その後、 ssh を使って順次コマンドを実行していくというシンプルな発想です。 Spring Boot のアプリケーションを AWS EC2 にデプロイする手順 では、 war のコピーを sudo -u tomcat ...
というやり方でコピーしていましたが、 build.gradle
ではうまくいかなかったので sudo
でコピーした後 chown
を実行しています。
最後に tomcat を再起動しているのは、 データベースのキャッシュをクリアするためです。
そしてもうひとつ、 サーバ設定ファイルを作成します。
1 2 3 4 5 6 7 8 9 |
{ "hosts" : [ "999.999.999.999", "999.999.999.999" ], "port": 22, "user": "ec2-user", "key" : "/describe/absolute/path.pem" } |
この deploy_config.json.sample
を作っておき、 使いたいときはこれを元に deploy_config.json
を作成して使います。 秘密鍵情報などあるので git に入れるべきか悩むところです。 必要に応じて .gitignore
を編集します。