diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml
new file mode 100644
index 000000000..77f90be5a
--- /dev/null
+++ b/.github/workflows/ci-cd.yaml
@@ -0,0 +1,66 @@
+name: Build and Deploy Java App
+#trigger
+on:
+ push:
+ branches: [ master ]
+
+jobs:
+ build-and-deploy:
+ runs-on: self-hosted
+
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ java-version: '17'
+ distribution: 'temurin'
+
+ - name: Build with Maven
+ run: mvn clean package
+
+ - name: Log in to Docker Hub
+ uses: docker/login-action@v2
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+
+ - name: Set image tag
+ run: echo "IMAGE_TAG=${GITHUB_SHA::7}" >> $GITHUB_ENV
+
+ - name: Build Docker image
+ run: |
+ docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:${{ env.IMAGE_TAG }} .
+ docker tag ${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:${{ env.IMAGE_TAG }} ${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:latest
+# run: docker build -t ${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:latest .
+# - name: Set image tag
+# run: echo "IMAGE_TAG=${GITHUB_SHA::7}" >> $GITHUB_ENV
+
+ - name: Push Docker image
+ run: |
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:${{ env.IMAGE_TAG }}
+ docker push ${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:latest
+# run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:latest
+
+ - name: Deploy to server via SSH
+ uses: appleboy/ssh-action@v1.0.0
+ with:
+ host: ${{ secrets.SERVER_IP }}
+ username: ${{ secrets.SERVER_USER }}
+ key: ${{ secrets.SERVER_SSH_KEY }}
+ script: |
+ set -e
+ IMAGE=${{ secrets.DOCKERHUB_USERNAME }}/java-hello-world:${{ env.IMAGE_TAG }}
+
+ echo "Pulling latest image..."
+ docker pull $IMAGE
+
+ echo "Stopping existing container if running..."
+ if docker ps -a -q --filter "name=app" | grep -q .; then
+ docker rm -f app
+ fi
+
+ echo "Running container on port 8080..."
+ docker run -d --name app -p 8080:8080 $IMAGE
diff --git a/.gitignore b/.gitignore
index fed39ca9d..20c6919db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,5 @@ dependency-reduced-pom.xml
.settings/
.vscode
.DS_Store
+id_github_ci
+id_github_ci.pub
diff --git a/.whitesource b/.whitesource
deleted file mode 100644
index 9c7ae90b4..000000000
--- a/.whitesource
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "scanSettings": {
- "baseBranches": []
- },
- "checkRunSettings": {
- "vulnerableCheckRunConclusionLevel": "failure",
- "displayMode": "diff",
- "useMendCheckNames": true
- },
- "issueSettings": {
- "minSeverityLevel": "LOW",
- "issueType": "DEPENDENCY"
- }
-}
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 000000000..af4983fab
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,10 @@
+FROM maven:3.8.5-openjdk-17 AS build
+WORKDIR /app
+COPY . .
+RUN mvn package -DskipTests
+
+FROM openjdk:17
+WORKDIR /app
+COPY --from=build /app/target/java-hello-web-0.1.0.jar app.jar
+EXPOSE 8080
+ENTRYPOINT ["java", "-jar", "app.jar"]
diff --git a/Jenkinsfile b/Jenkinsfile
deleted file mode 100644
index 445611cb7..000000000
--- a/Jenkinsfile
+++ /dev/null
@@ -1,21 +0,0 @@
-pipeline{
- agent any
-
- tools {
- maven 'maven'
- jdk 'java'
- }
-
- stages{
- stage('checkout'){
- steps{
- checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'github access', url: 'https://github.com/sreenivas449/java-hello-world-with-maven.git']]])
- }
- }
- stage('build'){
- steps{
- bat 'mvn package'
- }
- }
- }
-}
\ No newline at end of file
diff --git a/README.md b/README.md
index 6dcfe4465..d420d7328 100644
--- a/README.md
+++ b/README.md
@@ -1,252 +1,101 @@
-# Building Java Projects with Maven
-This guide walks you through using Maven to build a simple Java project.
+Финальный проект по курсу
-## What you’ll build
-You’ll create an application that provides the time of day and then build it with Maven.
+Задача:
+Реализовать полный цикл сборки-поставки приложения, используя
+практики CI/CD.
-## What you’ll need
-+ A favorite text editor or IDE
-+ JDK 6 or later
-+ Install Maven
+Работа представляет из себя следующее:
+При переходе по ссылке по адресу, выводится такая страница.
+
+Был создан пользователь для self-hosted runner. Чтобы запускался цикл после пуша, runner на хосте с приложением должен быть запущен:
+
-## Install Maven.
-+ [Install Maven on Windows](https://www.baeldung.com/install-maven-on-windows-linux-mac#installing-maven-on-windows)
-+ [Install Maven on Linux](https://www.baeldung.com/install-maven-on-windows-linux-mac#installing-maven-on-linux)
-+ [Install Maven on Mac OSX](https://www.baeldung.com/install-maven-on-windows-linux-mac#installing-maven-on-mac-os-x)
-
-## Set up the project
-First you’ll need to setup a Java project for Maven to build. To keep the focus on Maven, make the project as simple as possible for now.
-
-#### Create the directory structure
----
-+ Create a root project directory named `HelloWorldMaven` and `cd HelloWorldMaven`.
-+ In a project directory of your choosing, create the following subdirectory structure.
-+ For example, with `mkdir -p src/main/java/hello` on *nix systems:*
-
-+ on Windows you can create this directory manually.
-
- ```
- └── src
- └── main
- └── java
- └── hello
- ```
-+ Within the `src/main/java/hello` directory, you can create any Java classes you want. To maintain consistency with the rest of this guide, create these two classes: `HelloWorld.java` and `Greeter.java`.
-
-+ `src/main/java/hello/HelloWorld.java`
- ```
- package hello;
- public class HelloWorld {
- public static void main(String[] args) {
- Greeter greeter = new Greeter();
- System.out.println(greeter.sayHello());
- }
- }
- ```
-
- + `src/main/java/hello/Greeter.java`
- ```
- package hello;
- public class Greeter {
- public String sayHello() {
- return "Hello world!";
- }
- }
- ```
-
-Now that you have a project that is ready to be built with Maven, the next step is to build this project with Maven.
-
-### Define a simple Maven build
----
-+ You need to create a Maven project definition.
-+ Maven projects are defined with an XML file named pom.xml.
-+ Among other things, this file gives the project’s name, version, and dependencies that it has on external libraries.
-+ Create a file named `pom.xml` at the root of the project and give it the following contents:
-
- `pom.xml`
-
-```
-
-
- 4.0.0
- org.springframework
- jb-hello-world-maven
- jar
- 0.1.0
-
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 2.1
-
-
- package
-
- shade
-
-
-
-
- hello.HelloWorld
-
-
-
-
-
-
-
-
-
-```
-With the exception of the optional `` element, this is the simplest possible `pom.xml` file necessary to build a Java project. It includes the following details of the project configuration:
-+ ``. POM model version (always 4.0.0).
-+ ``. Group or organization that the project belongs to. Often expressed as an inverted domain name.
-+ ``. Name to be given to the project’s library artifact (for example, the name of its JAR or WAR file).
-+ ``. Version of the project that is being built.
-+ `` - How the project should be packaged. Defaults to "jar" for JAR file packaging. Use "war" for WAR file packaging.
-
-### Build Java code
----
-Maven is now ready to build the project. You can execute several build lifecycle goals with Maven now, including goals to compile the project’s code, create a library package (such as a JAR file), and install the library in the local Maven dependency repository.
-
-To try out the build, issue the following at the command line:
-
- `mvn compile`
- + This will run Maven, telling it to execute the compile goal. When it’s finished, you should find the compiled .class files in the target/classes directory.
- + Since it’s unlikely that you’ll want to distribute or work with .class files directly, you’ll probably want to run the package goal instead:
-
-`mvn package`
-
- + The package goal will compile your Java code, run any tests, and finish by packaging the code up in a JAR file within the target directory. The name of the JAR file will be based on the project’s `` and ``. For example, given the minimal `pom.xml` file from before, the JAR file will be named gs-maven-0.1.0.jar.
-
- **Note:** If you’ve changed the value of from "jar" to "war", the result will be a WAR file within the target directory instead of a JAR file.
-
-Maven also maintains a repository of dependencies on your local machine (usually in a .m2/repository directory in your home directory) for quick access to project dependencies. If you’d like to install your project’s JAR file to that local repository, then you should invoke the install goal:
-
-`mvn install`
-
-The install goal will compile, test, and package your project’s code and then copy it into the local dependency repository, ready for another project to reference it as a dependency.
-
-Speaking of dependencies, now it’s time to declare dependencies in the Maven build.
-
-### Declare Dependencies
----
-
-The simple Hello World sample is completely self-contained and does not depend on any additional libraries. Most applications, however, depend on external libraries to handle common and complex functionality.
-
-For example, suppose that in addition to saying "Hello World!", you want the application to print the current date and time. While you could use the date and time facilities in the native Java libraries, you can make things more interesting by using the Joda Time libraries.
-
-First, change HelloWorld.java to look like this:
-
-`src/main/java/hello/HelloWorld.java`
+При пушах в репо, автоматически запускается сборка, версионирование и деплой.
+В качестве инструмента был выбран Github Actions.
+Секреты хранятся в Github Actions secrets.
+Разуемеется, мониторинг и логирование тоже настроены. В качестве стека использовано: Prometheus + Grafana, для инфрастурных логов используется ELK стек.
+Структура проекта:
```
-package hello;
-
-import org.joda.time.LocalTime;
-
-public class HelloWorld {
- public static void main(String[] args) {
- LocalTime currentTime = new LocalTime();
- System.out.println("The current local time is: " + currentTime);
- Greeter greeter = new Greeter();
- System.out.println(greeter.sayHello());
- }
-}
+root@Codeby:~/ex# tree
+.
+└── java-hello-world-with-maven
+ ├── Dockerfile
+ ├── README.md
+ ├── id_github_ci
+ ├── id_github_ci.pub
+ ├── pom.xml
+ ├── src
+ │ └── main
+ │ └── java
+ │ ── com
+ │ └── example
+ │ └── helloweb
+ │ ├── HelloController.java
+ │ └── HelloWebApplication.java
+ │
+ └── target
+ ├── classes
+ │ └── com
+ │ └── example
+ │ └── helloweb
+ │ ├── HelloController.class
+ │ └── HelloWebApplication.class
+ ├── generated-sources
+ │ └── annotations
+ ├── java-hello-web-0.1.0.jar
+ ├── java-hello-web-0.1.0.jar.original
+ ├── maven-archiver
+ │ └── pom.properties
+ └── maven-status
+ └── maven-compiler-plugin
+ └── compile
+ └── default-compile
+ ├── createdFiles.lst
+ └── inputFiles.lst
+
+20 directories, 14 files
```
-Here `HelloWorld` uses Joda Time’s `LocalTime` class to get and print the current time.
-
-If you were to run `mvn compile` to build the project now, the build would fail because you’ve not declared Joda Time as a compile dependency in the build. You can fix that by adding the following lines to `pom.xml` (within the `` element):
-
-```
-
- 1.8
-
-
-
-
- joda-time
- joda-time
- 2.2
-
-
-```
-This block of XML declares a list of dependencies for the project. Specifically, it declares a single dependency for the Joda Time library. Within the `` element, the dependency coordinates are defined by three sub-elements:
-
-+ `` - The group or organization that the dependency belongs to.
-+ `` - The library that is required.
-+ `` - The specific version of the library that is required.
-
-By default, all dependencies are scoped as `compile` dependencies. That is, they should be available at compile-time (and if you were building a WAR file, including in the /WEB-INF/libs folder of the WAR). Additionally, you may specify a `` element to specify one of the following scopes:
-
-+ `provided` - Dependencies that are required for compiling the project code, but that will be provided at runtime by a container running the code (e.g., the Java Servlet API).
-
-+ `test` - Dependencies that are used for compiling and running tests, but not required for building or running the project’s runtime code.
-
-Now if you run `mvn compile` or `mvn package`, Maven should resolve the Joda Time dependency from the Maven Central repository and the build will be successful.
-
-Here’s the completed `pom.xml` file:
-
-`pom.xml`
-
-```
-
-
- 4.0.0
- org.springframework
- hello-world-maven
- jar
- 0.1.0
-
-
-
- 1.8
-
-
-
-
- joda-time
- joda-time
- 2.2
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 2.1
-
-
- package
-
- shade
-
-
-
-
- hello.HelloWorld
-
-
-
-
-
-
-
-
-
-```
-
-### Run project
----
-+ To run this project run the following command.
-
- `java -cp target/jb-hello-world-maven-0.1.0.jar hello.HelloWorld`
+ Как разворачивается
+Разработчик пушит изменения в ветку master GitHub-репозитория.
+Запускается GitHub Actions workflow (.github/workflows/ci-cd.yaml), где:
+Устанавливается JDK 17.
+Выполняется сборка проекта с помощью Maven (mvn clean package).
+Строится Docker-образ через Dockerfile.
+Образ пушится на Docker Hub с двумя тегами:
+latest — всегда самый свежий
+commit-hash (например b3a2d1f) — версия, привязанная к коммиту.
+Через SSH подключение GitHub Actions подключается к удаленному серверу и:
+Скачивает последний образ
+Удаляет старый контейнер (если есть)
+Запускает новый контейнер на порту 8080.
+
+Версионирование
+При каждом пуше:
+создается тег IMAGE_TAG=${GITHUB_SHA::7} — это первые 7 символов SHA коммита.
+пример: java-hello-world:b3a2d1f
+Также добавляется тег latest для последней стабильной сборки.
+Таким образом, можно:
+Всегда иметь стабильную ссылку на последнюю версию (latest)
+Иметь уникальную ссылку на конкретную сборку (commit_sha), которую легко откатить или протестировать.
+
+
+Dockerfile:
+Первый этап (stage build) использует Maven для сборки .jar.
+Второй этап использует openjdk:17, в него копируется уже собранный .jar.
+Приложение запускается с помощью команды java -jar app.jar.
+
+Как устроен мониторинг?
+Мониторинг построен на базе Prometheus и Grafana, с использованием Node Exporter для сбора метрик с хоста.
+Node Exporter запускается как контейнер и отдаёт системные метрики по адресу :9100. Prometheus по расписанию (каждые 15 секунд) делает HTTP scrape на адрес node-exporter:9100/metrics. Метрики сохраняются во внутреннюю базу данных Prometheus. Grafana подключается к Prometheus как источник данных и отображает метрики на дашборде.
+
+
+ELK настроен на отдельном сервере. Разворачивается с помощью docker compose
+Elasticsearch слушает на 9200, выделено 512MB памяти. Logstash слушает на порту 5000 для логов от Filebeat. Kibana слушает на 5601.
+
+По logstash:
+input — принимает логи от Filebeat по порту 5000 (по протоколу Beats). filter — обрабатывает syslog, если присутствует тег "syslog", применяет шаблон grok для парсинга и нормализует временные метки. output — сохраняет документы в Elasticsearch в индекс infrastructure-logs-YYYY.MM.dd.
+
+
+Репозиторий с файлами grafana + prometheus и elk находятся здесь https://github.com/Depth-monster/elk-grafana .
+!--end!--
diff --git a/pom.xml b/pom.xml
index 263eb8be6..da6bedf99 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,51 +1,41 @@
-
-
- 4.0.0
- org.springframework
- jb-hello-world-maven
- jar
- 0.2.0
+
+
+ 4.0.0
+ com.example
+ java-hello-web
+ 0.1.0
+ jar
-
-
- 1.8
- 1.8
- 1.8
-
+
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.1.5
+
+
-
-
- joda-time
- joda-time
- 2.2
-
-
-
-
-
-
-
- org.apache.maven.plugins
- maven-shade-plugin
- 2.1
-
-
- package
-
- shade
-
-
-
-
- hello.HelloWorld
-
-
-
-
-
-
-
-
+
+ 17
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
diff --git a/src/main/java/com/example/helloweb/HelloController.java b/src/main/java/com/example/helloweb/HelloController.java
new file mode 100644
index 000000000..d2b0d14c2
--- /dev/null
+++ b/src/main/java/com/example/helloweb/HelloController.java
@@ -0,0 +1,12 @@
+package com.example.helloweb;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HelloController {
+ @GetMapping("/hello")
+ public String hello() {
+ return "Hello from Spring Boot!";
+ }
+}
diff --git a/src/main/java/com/example/helloweb/HelloWebApplication.java b/src/main/java/com/example/helloweb/HelloWebApplication.java
new file mode 100644
index 000000000..91a38e1c6
--- /dev/null
+++ b/src/main/java/com/example/helloweb/HelloWebApplication.java
@@ -0,0 +1,11 @@
+package com.example.helloweb;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class HelloWebApplication {
+ public static void main(String[] args) {
+ SpringApplication.run(HelloWebApplication.class, args);
+ }
+}
diff --git a/src/main/java/hello/Greeter.java b/src/main/java/hello/Greeter.java
deleted file mode 100644
index 650054052..000000000
--- a/src/main/java/hello/Greeter.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package hello;
-
-public class Greeter {
- public String sayHello() {
- return "DevOps Project for AchiStar Technologies";
- }
-}
diff --git a/src/main/java/hello/HelloWorld.java b/src/main/java/hello/HelloWorld.java
deleted file mode 100644
index 19e4ff928..000000000
--- a/src/main/java/hello/HelloWorld.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package hello;
-
-import org.joda.time.LocalTime;
-
-public class HelloWorld {
- public static void main(String[] args) {
- LocalTime currentTime = new LocalTime();
- System.out.println("The current local time is: " + currentTime);
-
- Greeter greeter = new Greeter();
- System.out.println(greeter.sayHello());
- }
-}