Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updating build locally, docker-compose, and kubernetes #3

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
03d783f
Update README.md
osamamagdy Nov 5, 2021
e2080c3
Update README.md
osamamagdy Nov 5, 2021
8c61ce1
Update README.md
osamamagdy Nov 5, 2021
3bdda65
Update README.md
osamamagdy Nov 5, 2021
9d54393
Update README.md
osamamagdy Nov 5, 2021
66dff3c
Update README.md
osamamagdy Nov 5, 2021
ebfd50d
Update README.md
osamamagdy Nov 5, 2021
f34e54b
Update README.md
osamamagdy Nov 5, 2021
90cf7eb
Update README.md
osamamagdy Nov 5, 2021
bded1b3
Update README.md
osamamagdy Nov 5, 2021
ecc8ca2
Build local complete
osamamagdy Nov 5, 2021
7cfc6c7
Merge branch 'master' of https://github.com/osamamagdy/Online-Store
osamamagdy Nov 5, 2021
b51d640
Update README.md
osamamagdy Nov 5, 2021
1cf29b8
Docker Compose
osamamagdy Nov 5, 2021
c5912f2
Merge branch 'master' of https://github.com/osamamagdy/Online-Store
osamamagdy Nov 5, 2021
71fbb25
Update README.md
osamamagdy Nov 6, 2021
83fc534
Update README.md
osamamagdy Nov 6, 2021
c2d1007
Update README.md
osamamagdy Nov 6, 2021
db7abc7
Update README.md
osamamagdy Nov 6, 2021
25de3d5
env isn't needed in dockerfile
osamamagdy Nov 6, 2021
b37692d
Merge branch 'master' of https://github.com/osamamagdy/Online-Store
osamamagdy Nov 6, 2021
95ea356
Apply k8s
osamamagdy Nov 7, 2021
9efdf54
Update README.md
osamamagdy Nov 7, 2021
1b2b797
Update README.md
osamamagdy Nov 7, 2021
661f454
Create pipeline.yml
osamamagdy Nov 7, 2021
59af3ee
Merge pull request #1 from osamamagdy/osamamagdy-patch-1
osamamagdy Nov 7, 2021
0cf4a81
Create main.yml
osamamagdy Nov 7, 2021
5574bd4
Merge pull request #2 from osamamagdy/osamamagdy-patch-2
osamamagdy Nov 7, 2021
0fde861
Delete pipeline.yml
osamamagdy Nov 7, 2021
ec61162
Update main.yml
osamamagdy Nov 7, 2021
b6f3593
Update main.yml
osamamagdy Nov 7, 2021
eeb16c6
Update main.yml
osamamagdy Nov 7, 2021
7d70554
Update application.properties
osamamagdy Nov 7, 2021
c9d8d9d
Update application.properties
osamamagdy Nov 7, 2021
aab1344
Update main.yml
osamamagdy Nov 7, 2021
ce12e8e
Update main.yml
osamamagdy Nov 7, 2021
d074939
Update main.yml
osamamagdy Nov 7, 2021
1cee19e
Update main.yml
osamamagdy Nov 7, 2021
36436a3
Update main.yml
osamamagdy Nov 7, 2021
aa3aa59
Update main.yml
osamamagdy Nov 7, 2021
26736fc
Update main.yml
osamamagdy Nov 7, 2021
8896a47
Update main.yml
osamamagdy Nov 7, 2021
2edcea7
Add terraform file
osamamagdy Nov 9, 2021
8a333ad
Update github actions
osamamagdy Nov 9, 2021
38ff6fc
add terraform files
osamamagdy Nov 9, 2021
652a6f4
update terraform
osamamagdy Nov 9, 2021
1fb0025
add ingress nginx
osamamagdy Nov 11, 2021
43c96b7
Update README.md
osamamagdy Nov 11, 2021
e96d228
Update README.md
osamamagdy Nov 11, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
21 changes: 21 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

target

# IDE files
.idea
*.iml

# env file
.env
72 changes: 72 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: Java CI with Maven

on:
push:
branches: [ master ]
paths-ignore:
- "**/README.md"
- "terraform/**"
pull_request:
branches: [ master ]
paths-ignore:
- "**/README.md"
- "terraform/**"

jobs:

build_local:

runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2


- name: Set up JDK 11
uses: actions/setup-java@v2
with:
java-version: '11'
distribution: 'adopt'
cache: maven

- name: Docker run mysql
run: docker run -p 3306:3306 --env MYSQL_ROOT_PASSWORD=${{secrets.DatabasePassword}} --env MYSQL_DATABASE='springboot_mysql_example' --env MYSQL_USER='osama' --env MYSQL_PASSWORD=${{secrets.DatabasePassword}} -d mysql



- name: Build the JAR file
run: mvn clean install -DskipTests


- name: Test
run: mvn test
env:
MYSQL_DB_HOST: 'localhost'
MYSQL_DB_PORT: '3306'
MYSQL_DB_USERNAME: 'osama'
MYSQL_DB_PASSWORD: ${{secrets.DatabasePassword}}
MYSQL_DB_DNAME: 'springboot_mysql_example'



build_docker:
needs: build_local #as we don't push the image unless the build job is done
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2


- name: Build & push Docker image
uses: mr-smithers-excellent/docker-build-push@v5
with:
image: osamamagdy/online_store
tags: v1, latest
registry: docker.io
dockerfile: Dockerfile
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,14 @@ target
# IDE files
.idea
*.iml

# env file
.env
k8s_yaml/secret.yaml

#terraform files
terraform/*

## except the *.tf files

!terraform/*.tf
34 changes: 34 additions & 0 deletions .project
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>spring-boot-mysql</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
<filteredResources>
<filter>
<id>1636074914226</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
5 changes: 5 additions & 0 deletions .settings/org.eclipse.core.resources.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/main/resources=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
2 changes: 2 additions & 0 deletions .settings/org.eclipse.jdt.apt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=false
10 changes: 10 additions & 0 deletions .settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.methodParameters=generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
org.eclipse.jdt.core.compiler.processAnnotations=disabled
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=1.8
4 changes: 4 additions & 0 deletions .settings/org.eclipse.m2e.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
12 changes: 12 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM maven:latest as builder
WORKDIR /app
COPY . .

RUN ["mvn","clean","install","-DskipTests"]

FROM openjdk:latest
COPY --from=builder /app/target/spring-boot-mysql-0.0.1-SNAPSHOT.jar /usr/src/myapp/
WORKDIR /usr/src/myapp
EXPOSE 8080

CMD ["java", "-jar","spring-boot-mysql-0.0.1-SNAPSHOT.jar"]
89 changes: 87 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,88 @@
# Spring Boot MySQL Example
# Online store

You can learn more about my courses [here](http://courses.springframework.guru/courses/) on my site.
## Resources
The original spring-boot application was inspired from [here](https://github.com/springframeworkguru/spring-boot-mysql-example)
## Steps to build locally
### 1 - First, ensure to have Java JDK/JRE and maven installed on your local machine </br>
&nbsp; a - install Java JDK by running the command `sudo apt install default-jdk -y`</br>
&nbsp; b - install Java JRE by running the command `sudo apt install default-jre -y`</br>
&nbsp; c - install maven bwith `sudo apt install maven -y`</br>
### 2 - Second, install and configure mysql </br>
&nbsp; a - install from [here](https://linuxize.com/post/how-to-install-mysql-on-ubuntu-18-04/) </br>
&nbsp; b - configure mysql by creating a user with `mysql_native_password` for the authentication method. You can take guidance from [here](https://linuxize.com/post/how-to-manage-mysql-databases-and-users-from-the-command-line/#create-a-new-mysql-user-account) </br>
&nbsp; c - create database for the application ( use the same guide above )</br>
### 3 - Put the information in a new `.env` file
```
MYSQL_DB_HOST=
MYSQL_DB_PORT=
MYSQL_DB_USERNAME=
MYSQL_DB_PASSWORD=
MYSQL_DB_DNAME=
```
&nbsp; Note: all names and passwords will be updated in the `src/main/resources/application.properties` file </br>
### 4 - Build the jar file and run</br>
&nbsp; a - Run the command `mvn clean install`. This will create a directory named `target`.</br>
&nbsp; b - navigate to the `target` directory and run the jar file with `java -jar <file_name.jar>`</br>
## Build locally using Docker
### 1 - Install Docker & Docker-Compose </br>
&nbsp; a - Install docker from the official documentation [here](https://docs.docker.com/engine/install/ubuntu/) </br>
&nbsp; b - Install docker-compose from the official documentation [here](https://docs.docker.com/compose/install/) </br>
&nbsp; Note: If you choose to build with docker, you will not need all the previous installation for running the project locally. You only need to install docker and docker-compose and it saves you the hassle of installing JDK, JRE, maven, and even mysql.

### 2 - Put the information in a new `.env` file
&nbsp; For the sake of consistency, we use the same name while building locally </br>
```
MYSQL_DB_HOST=db #this one is necessary as it is the service name in docker-compose.yaml file
MYSQL_DB_PORT=3306 #this is the default port used by mysql official image so don't choose any port else
MYSQL_DB_USERNAME=
MYSQL_DB_PASSWORD=
MYSQL_DB_DNAME=
```
### 3 - Build and Run
&nbsp; Run the command `docker-compose up` in the directory where docker files are. Docker will first pull the needed images and start working. </br>
&nbsp; If you want to edit the configurations and build again, run `docker-compose up --build` to ignore chache and start building again. </br>

## Deploy with kubernetes
### 1 - Install minikube </br>
&nbsp; a - For testing purposes, we can deploy all our kubernetes deployments on a locally created single-node cluster with minikube [here](https://minikube.sigs.k8s.io/docs/start/) </br>
&nbsp; Note: If you are running your ubuntu on a virtual machine upon other OS, you may need to follow this [guide](https://webme.ie/how-to-run-minikube-on-a-virtualbox-vm/) instead. </br>

### 2 - Put the information in a new `secret.yaml` file (all files are in the k8s_yaml directory)
&nbsp; a - Here, we will replace the `.env` file with two files. A configmap.yaml which contains non-sensetive data to be accessible by all cluster resources (this one is created for you and is present in the repository. </br>
&nbsp; b - A secret.yaml which contains sensetive data that not to be shared on publuic repository so create the file first and fill the data below </br>

```
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
data:
MYSQL_DB_PORT:
MYSQL_DB_USERNAME:
MYSQL_DB_PASSWORD:
MYSQL_DB_DNAME:
```
&nbsp; Important Note: you can not just place the values in the secrets file as a plain text, first you will need to encode them to base64 (as k8s will decode them by default). And the way to do this in linux `echo -n text | base64 `, or you can use a website like [here](https://www.base64decode.org/)</br>

### 3 - Build and Run with external ip
&nbsp; a - You will need to run `kubectl apply -f <file_name>.yaml` to apply the configurations of each file. But due to using secrets and services, you will need to execute them in specific order </br>
&nbsp;&nbsp; I - secrets file </br>
&nbsp;&nbsp; II - mysql deployment files </br>
&nbsp;&nbsp; III - mysql service files </br>
&nbsp;&nbsp; IV - config map file </br>
&nbsp;&nbsp; V - online-store deployment file </br>
&nbsp;&nbsp; VI - online-store-service file </br>
&nbsp; b - The loadbalancer used in online-store-service will assign an external ip → with using minikube, it will be in pending state until you allow it to take ip by typing “minikube service <NAME_OF_SERVICE>”

&nbsp;Note: If you want to edit any of the configurations, run `kubectl apply -f <file_name>.yaml`. </br>

### 4 - Build and Run with ingress and domain name
&nbsp; a - The configuration files used for this are online-store-ingress.yaml and online-store-internal-service.yaml (this will be applied instead of online-store-service.yaml) </br>
&nbsp; b - Install the ingress-controller pod in your k8s cluster → with minikube you type `minikube addons enable ingress`and it will be added in the kube-system namespace </br>
&nbsp; c - apply online-store-internal-service.yaml ( note that if you used the above steps exactly, you will have 2 services mapping to the same deployment and it is fine for testing. Otherwise, delete the service online-store-service ) </br>
&nbsp; d - apply the online-store-ingress.yaml ( note that you will replace the file in step 6 above with ) </br>
&nbsp; e - this will create an IP address to the hostname osama.com → type `kubectl get ingress` to know </br>
&nbsp; f - For testing and with using minikube, this is a dummy hostname that is not available publicly. So we have to map it explicitly to the address created by minkube </br>
&nbsp; g - to map in your linux, type `sudo nano /etc/hosts` → add the IP address created in step 5 and the hostname associated with it osama.com </br>
&nbsp; h - Go to osama.com in your browser to open the application </br>
40 changes: 40 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
version: '3'
services:
db:
image: mysql:5.7
restart: always
environment:
MYSQL_DATABASE: "$MYSQL_DB_DNAME"
# So you don't have to use root, but you can if you like
MYSQL_USER: "$MYSQL_DB_USERNAME"
# You can use whatever password you like
MYSQL_PASSWORD: "$MYSQL_DB_PASSWORD"
# Password for root access
MYSQL_ROOT_PASSWORD: "$MYSQL_DB_PASSWORD"
ports:
# <Host PORT> : < MySQL Port running inside container>
#Host port is used for outside communication
#MYSQL internal port used for Networked service-to-service communication
- '3000:3306'
volumes:
- my-db:/var/lib/mysql
web-app:
depends_on:
- db
restart: on-failure
links:
- "db:db"
environment:
MYSQL_DB_HOST: ${MYSQL_DB_HOST}
MYSQL_DB_PORT: ${MYSQL_DB_PORT}
MYSQL_DB_USERNAME: ${MYSQL_DB_USERNAME}
MYSQL_DB_PASSWORD: ${MYSQL_DB_PASSWORD}
MYSQL_DB_DNAME: ${MYSQL_DB_DNAME}
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080"
## Names our volume
volumes:
my-db:
6 changes: 6 additions & 0 deletions k8s_yaml/configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: online-store-configmap
data:
MYSQL_DB_HOST: mysql-service
Loading