In order to practice CI / CD, I set up Jenkins to generate Artifacts and deploy it to the application server.
In this article, as * preparation *, we will manage the web application project written in Java on Github and set it up to build in cooperation with Jenkins.
Artifacts
I think there are generally two ways to deploy, "deploy with war" and "deploy with jar", so I decided to try either pattern.
That is,
** 1. Output the war file and deploy it to the application server. ** **
** 2. Output the jar file and execute it with the java
command. ** **
This time, the former uses Tomcat for the application server, and the latter uses the built-in Tomcat in Spring Boot to execute the jar.
In order to prepare two types of Artifacts, a war file and a jar file, we have prepared two Java web application projects that use the Spring Framework.
Click here for Github Repository (https://github.com/kazokmr/JavaWebAppDeploySample)
The base is based on Serving Web Content with Spring MVC on Spring's HP, I tried to prepare a Maven project, but Spring Boot I used it and the packaging was also jar, so I bought it before Spring thorough introduction and Mr. Tada did it at JJUG CCC. I also referred to the hands-on material Spring 5 & Spring Boot 2 hands-on preparation procedure.
Check that the war file is registered in [File> Project Structure> Artifacts] of IntelliJ IDEA, and add it if it does not exist.
I prepared Maven Wrapper so that I can execute mvn command without installing Maven on Jenkins server.
mvn -N io.takari:maven:wrapper -Dmaven=3.6.0
For how to make Maven Wrapper (mvnw), refer to here.
Note that it was difficult to start Tomcat in the development environment and check it with a browser
brew install tomcat
/usr/local/Cellar/tomcat/9.0.14/libexec
for Path of [Application Server].http: // localhost: 8080 / web-spring-mvc / greeting
for [URL].war expanded
from the war that can be specified as Artifacts in [Deploy at the server startup] on the Deployment tab./ web-spring-mvc
. (Match with ContextPath of URL 4)When I run Tomcat from IntelliJ IDEA, I go to http: // localhost: 8080 / web-sprig-mvc / greeting and the screen is displayed.
Execute Artifacts developed by Spring Boot application and output by jar with java
command.
The sample project creates a Maven project based on Building an Application with Spring Boot.
Since the output of this sample was Rest API, I edited it to output html (Thymeleaf).
First, create a project using Spring Initializer.
Below, about the difficult points
--If you do not add spring-boot-starter-thymeleaf
, the screen will not be output because Thymeleaf cannot be used.
--When using JUnit5, remove junit
from the dependency of spring-boot-starter-test (I get an error when trying to specify a version that does not exist from the dependent junit.)
--The output jar file starts the service on the JVM server, but [Executable jar](https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html# Set the executable option of spring-boot-maven-plugin to true in order to make it deployment-script-customization-when-it-runs).
The following three virtual environments have been built on the local machine.
To build, start multiple environments at the same time with Vagrant and [ansible-playbook](https://github.com/kazokmr/ansible-java- I'm using deploy-env) to install the necessary software.
Main installation software
JRE 8 is used as an execution environment for Jenkins operation, and OpenJDK 11 is used for building applications.
To install Jenkins, refer to Jenkins Wiki.
Main installation software
For how to write Ansible-playbook, I referred to Sample of ansible head family.
I stumbled on the firewall settings, but I was able to connect by "changing the service start of Tomcat from started to restarted" and "starting firewalld before specifying the port of firewalld".
/roles/tomcat/tasks/main.yml(Excerpt)
- name: Start Tomcat
service: name=tomcat state=restarted enabled=yes
- name: running firewall daemon
service: name=firewalld state=restarted
When accessing the tomcat manager screen (/ manager / html) from a local PC, "403 access denied" is displayed, so an error screen or here When I looked at 30/000000), it was said that the initial value was set so that access to the manager screen could only be done from the machine on which Tomcat was installed, so /webapps/manager/META-INF/context. I edited the xml and changed it so that it can be accessed from within the virtual environment network (192.168.33.0/24).
Also, in order to be able to execute the tomcat manager from the command, assign the manager-sciprt role to the execution user in tomcat-users.xml. Reference
Make settings to run the Spring Boot application.
At the time of creation, the jar file does not exist yet, so even if you start the service, the status will be Fail.
When you run vagrant up
, the three environments will start up in sequence, and Ansible will run to install the necessary software and settings.
After the installation is complete, you can access the virtual environment with vagrant ssh [hostname]
.
Jenkins
You can log in to Jenkins by visiting http://192.168.33.10:8080/.
After that, perform the initial setup from the screen and set the path of the installed JDK and Git.
Tomcat
You can access the Tomcat console by visiting http://192.168.33.30:8080/.
If you use the users of roles / tomcat / vars / main.yml included in the sample, you can use the management screen and Script.
JVM
Make sure you see ** openjdk version ** when you access it with vagrant ssh jvm
and run java -version
.
Also, if you execute # systemctl status app
, you can check the execution status of the Spring Boot application service, but the first time you will get an error because there is no jar file. (You can see it by looking at / var / log / message.)
It uses an SSH connection to transfer the jar file from the Jenkins server to the JVM server and run the services of the application. In this sample, I did not create a public key in advance because I started multiple environments with vagrant at the same time, so I passed the key with the command as follows. (Actually, it is better to prepare the public key in advance and register it with the authorized_key module of ansible.)
** Temporarily enable access with password authentication on the JVM server **
# vi / etc / ssh / sshd_config
and switch" PasswordAuthentication "to yes# systemctl restart sshd
.# passwd jvm
** Create an SSH key as a Jenkins user on the Jenkins server and send the public key to the JVM server **
If you execute $ sudo su -s / bin / bash jenkins
, you can execute the command as a Jenkins user, so execute the command to create an SSH key.
1.jenkins user's home directory[/var/lib/jenkins]Move to
$ cd ~
2.Make an ssh key
$ ssh-keygen -b 2048 -t rsa -f /var/lib/jenkins/.ssh/id_rsa -N ""
3.Send the public key to the JVM server(You will be asked for the jvm user password when sending)
$ ssh-copy-id -i .ssh/id_rsa.pub [email protected]
4.Connection test
$ ssh -i .ssh/id_rsa [email protected]
5.End
$ exit
** Don't forget to disable password authentication on the JVM server once you have ssh access **
By the way, the home directory of the jvm user created on the JVM server is / var / jvm
, so the SSH connection information is stored in /var/jvm/.ssh
.
** Maven project (Java + Spring) ** and ** Jenkins server ** and ** deployment environment ** managed by Github are ready! The setting method to execute the build and deploy after this is Tomcat application and SpringBoot application ), So please refer to here.
Recommended Posts