Table of Contents
I created Spring Boot server application and deployed it to AWS EC2 Amazon Linux. I wrote the way to have deployed at that time.
Environment
I used gradle, not Maven.
- Spring Boot 1.2.3
- Tomcat 8
- Java 1.8
- MySQL 5.6 (AWS RDS)
- gradle 3.4
- Kotlin 1.0.0
Build Setting
Required Setting
First, apply required configuration. This is also wrote at Spring Boot document.
Add to Application Code
The class that contains main
method should inherit SpringBootServletInitializer
. And, override configure
method. In Spring Boot document, the class name is Application
, but in my appication it was Main
class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package com.sample.application; import org.springframework.boot.SpringApplication; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; @SpringBootApplication public class Main extends SpringBootServletInitializer { @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Main.class); } public static void main(String[] args) { SpringApplication.run(Main.class, args); } } |
gradle Setting
build.gradle
also should be changed.
1 2 3 4 5 6 |
apply plugin: 'war' war { baseName = 'sample_application' version = '1.0.0' } |
baseName
and version
is not required. But apply plugin: 'war'
is required for creating war file.
And add the following code.
1 2 3 4 5 6 7 |
dependencies { providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' } configurations { providedRuntime } |
I guess you already have several lines in dependencies
section. Add providedRuntime
setting.
Please look at Spring Boot document for more detail.
As a result, my build.gradle
was changed to the following.
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 |
buildscript { ext.kotlin_version = '1.0.0' repositories { mavenCentral() } 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" } } apply plugin: 'java' apply plugin: 'spring-boot' apply plugin: 'kotlin' apply plugin: 'war' war { baseName = 'sample_application' version = '1.0.0' } sourceCompatibility = '1.8' targetCompatibility = '1.8' 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 "org.json:json:20160212" providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' } jar.baseName = 'sample_application' sourceSets { main.java.srcDirs += 'src/main/kotlin' } configurations { providedRuntime } processResources { filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [ activeProfiles: project.properties['activeProfiles'] ?: "development" ] } |
Then ./gradlew build
generates war file into build/libs
directory.
Environmental Setting
This section is required if you create multi environmental property files.
In Spring Boot, you can write in server.address
or spring.datasource.url
, etc. settings in application.properties
. I created the following 3 files.
- application-develpment.properties
- application-local.properties
- application-production.properties
If you build jar or war with ./gradlew build
, you can execute it in specific environment like java -jar -Pspring.profiles.active=xxxxx xxxx.jar
. But after deploying Tomcat, you cannot do that. So we should configure on building.
Then add the following lines to build.gradle
.
1 2 3 4 5 |
processResources { filter org.apache.tools.ant.filters.ReplaceTokens, tokens: [ activeProfiles: project.properties['activeProfiles'] ?: "development" ] } |
Gradle 3.0 and later enable us to write build.gradle with Kotlin. In the case, write filter section like as follows.
1 2 3 4 5 6 7 8 9 10 |
tasks.withType(org.gradle.language.jvm.tasks.ProcessResources::class.java) { this.filter( mapOf( "tokens" to mapOf( "activeProfile" to (project.properties["activeProfile"] ?: "default") ) ), org.apache.tools.ant.filters.ReplaceTokens::class.java ) } |
activeProfiles
の値を ?:
を使って書いているのは、 activeProfiles
が設定されなかった場合にもビルドを成功させるためです。 otherwise, when you open the project with Intellij IDEA first time, you can’t open the project because of the build failing.
And add spring.profiles.active=@activeProfiles@
to application.properties
. At this time, my application.properties
is below.
1 2 3 |
server.address=0.0.0.0 spring.profiles.active=@activeProfiles@ |
Thus, the build command when you want to compile with specific profile setting is ./gradlew -PactiveProfiles=xxxxx build
. xxxxx
のところには、 私の場合は local
, development
, production
が入ります。
Establish Server
Launch server in AWS EC2, Amazon Linux.
Install Required Programs
This time, I don’t install Apache or Nginx.
Java
EC2 から gitリポジトリ を取得し、 EC2内でビルドして同一サーバ内にデプロイする方法をとったため、 Java は 1.8 の SDK をインストールしました。 Oracle のサイトから rpm パッケージ をダウンロードしてインストールします。 Usually I put downloaded rpm file into /usr/local/src
.
git
git command is necessary, so install it by the following command.
1 |
sudo yum install git-core |
Tomcat
Install Tomcat. Spring Boot contains internal Tomcat and it can be launched as sudo nohup java -jar ...
. But for this time, use Tomcat.
Execute the following command in Amazon Linux.
1 |
sudo yum install tomcat8 |
After that, Tomcat will be installed, and it can be launched by service
command.
At last, execute chkconfig
for launching Tomcat on server boot.
1 2 |
sudo chkconfig --level 345 tomcat6 on chkconfig --list tomcat8 # Checking Configuration |
Tomcat Configuration
We want to make Tomcat listen to TCP 80 port, then change as below. It’s not required when you use Nginx or Apache and proxy 8080 port access to 80 port.
1 2 3 |
sudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080 sudo service iptables save sudo service iptables restart |
And change /usr/share/tomcat8/conf/server.xml
. The file owner is tomcat
, so you should edit like sudo -u tomcat vim /usr/share/tomcat8/conf/server.xml
, as user tomcat
. At the mid of the file, you can find <Connector port="8080" ...
, then add the attribute proxyPort="80"
.
1 2 3 4 |
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" proxyPort="80" /> |
And reboot Tomcat.
Deploy
Dploy manually.
Compile
Go to the project directory and execute ./gradlew build
or ./gradlew -PactiveProfiles=xxxx build
. The program will be built.
Locate war at Tomcat Directory
Locate war file at Tomcat webapps
directory
1 |
sudo -u tomcat cp build/libs/sample_application-1.0.0.war /usr/share/tomcat8/webapps/ROOT.war |
Reboot Tomcat
Reboot Tomcat
1 |
sudo service tomcat8 restart |
Now, we can get the content through 80 port of the server.