Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
9925e89
[Feat] integrated Docker Hub into CI pipeline
je0ng3 Apr 4, 2025
ce7f999
[Refactor] merge files for better organization
je0ng3 Apr 4, 2025
1af320d
[Feat] add checkout code
je0ng3 Apr 4, 2025
d927b5d
Merge branch 'develop' of https://github.com/favicon-data/back into fโ€ฆ
je0ng3 Apr 15, 2025
7120180
[Feat] set up CI/CD pipeline on EC2
je0ng3 Apr 16, 2025
0dad17b
[Refactor] change stage order in GitHub Actions
je0ng3 Apr 16, 2025
0b8b1a7
[Chore] injected variables using environment file
je0ng3 Apr 28, 2025
10f67c2
[Refactor] consolidated steps into a single step
je0ng3 Apr 28, 2025
d5fb57c
[Refacor] add Docker image tag
je0ng3 Apr 28, 2025
84a9479
[Refactor] replace secrets with variables
je0ng3 Apr 28, 2025
291c1e8
[Fix] modifiy EC2 deployment code
je0ng3 May 6, 2025
fda1d7a
[Refactor] create files listed in gitignore with echo
je0ng3 May 14, 2025
bd9f81b
[Refacor] change to use existing image instead of build
je0ng3 May 14, 2025
eb51d40
[Refactor] use git secrets
je0ng3 May 17, 2025
2df5749
[Refactor] refactor .gitignore
je0ng3 May 17, 2025
90039b8
Merge develop to feature/github-action
je0ng3 May 17, 2025
f271fd1
[Refactor] fix spelling error
je0ng3 May 17, 2025
967c196
[Refactor] remove default application option
je0ng3 May 17, 2025
a872217
[Refactor] remove default application option
je0ng3 May 17, 2025
a24cf2a
[Refactor] change github secrets to use env file
je0ng3 May 17, 2025
349b59d
[Refactor] fix spelling error
je0ng3 May 17, 2025
9666e77
[Refactor] edit environment variables
je0ng3 May 18, 2025
862ee9b
[Refactor] edit security config
je0ng3 May 18, 2025
1ffef68
[Refactor] make not to run it in pr
je0ng3 May 24, 2025
aac3512
[Feat] cd to ec2
je0ng3 May 24, 2025
daddda6
refactor: modify the docker run command
je0ng3 May 24, 2025
0f3c5b7
[Refactor] remove test code and typo correction
je0ng3 May 24, 2025
0cd5542
[Refactor] make different test environments when pr or push
je0ng3 May 24, 2025
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
58 changes: 58 additions & 0 deletions .github/workflows/build_and_deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Deploy to DockerHub & EC2

on:
push:
branches: [ main, develop ]

jobs:
build-and-push:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Set up Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582
with:
cache-read-only: false

- name: Grant Execute Permission For Gradlew
run: chmod +x gradlew

- name: Build with Gradle
run: |
set -e
./gradlew clean build -Dspring.profiles.active=local

- name: Build Docker image
run: |
docker build \
--build-arg SPRING_PROFILES_ACTIVE=prob \
-f Dockerfile \
-t ${{ vars.DOCKERHUB_USERNAME}}/erica-favicon:latest .

- name: DockerHub login
uses: docker/login-action@v2
with:
username: ${{ vars.DOCKERHUB_USERNAME}}
password: ${{ vars.DOCKERHUB_PASSWORD}}

- name: Push Docker image
run: |
docker push ${{ vars.DOCKERHUB_USERNAME}}/erica-favicon:latest

- name: Deploy to EC2
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2_HOST }}
username: ubuntu
key: ${{ secrets.EC2_SSH_KEY }}
script: |
docker pull ${{ vars.DOCKERHUB_USERNAME }}/erica-favicon:latest
docker rm -f back 2>/dev/null || true
docker compose -f docker-compose.yml --env-file .env up --build -d
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name: PR Build Test
name: PR Build TEST

on:
pull_request:
branches: [ main, develop ]

jobs:
test:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -25,6 +25,6 @@ jobs:
run: chmod +x gradlew

- name: Build with Gradle
run: |
run: |
set -e
./gradlew clean build
./gradlew clean build -Dspring.profiles.active=local
7 changes: 3 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Ignore security and cors configuration files
/src/main/java/com/capstone/favicon/config/SecurityConfig.java
/src/main/java/com/capstone/favicon/config/CorsConfig.java
/org
.env
*.pem

HELP.md
.gradle
Expand Down Expand Up @@ -49,8 +50,6 @@ out/
### ec2 ###
favicon-key.pem

application.properties
SecurityConfig.java
requirement.txt
๊ธฐ์ƒ์ฒญ_์›”๋ณ„_processed.csv
๊ธฐํ›„_๊ฐ๊ธฐ_๊ฑด๊ฐ•๋ณดํ—˜์‹ฌ์‚ฌํ‰๊ฐ€์›.csv
Expand Down
6 changes: 6 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM amazoncorretto:17
RUN yum update -y && \
yum install -y python3 && \
yum clean all
COPY build/libs/app.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
14 changes: 13 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ repositories {
mavenCentral()
}

springBoot {
mainClass = 'com.capstone.favicon.FaviconApplication'
}

bootJar {
archiveFileName = 'app.jar'
}

jar {
enabled = false
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'
Expand All @@ -25,7 +37,7 @@ dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

runtimeOnly 'org.postgresql:postgresql:42.6.0'
implementation 'org.postgresql:postgresql:42.6.0'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
// lombok
compileOnly 'org.projectlombok:lombok:1.18.28'
Expand Down
24 changes: 24 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
services:
redis:
image: redis:latest
container_name: redis
ports:
- "6379:6379"
command:
- redis-server
networks:
- backend-network

backend:
image: 211i2/erica-backend:latest
container_name: backend
ports:
- "8080:8080"
networks:
- backend-network
depends_on:
- redis

networks:
backend-network:
driver: bridge
25 changes: 25 additions & 0 deletions src/main/java/com/capstone/favicon/config/CorsConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.capstone.favicon.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

@Configuration
public class CorsConfig {

@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowCredentials(true);
configuration.addAllowedOrigin("http://localhost:3000");
configuration.addAllowedOrigin("http://127.0.0.1:3000");
configuration.addAllowedHeader("*");
configuration.addAllowedMethod("*");
source.registerCorsConfiguration("/**", configuration);
return new CorsFilter(source);
}

}
42 changes: 42 additions & 0 deletions src/main/java/com/capstone/favicon/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.capstone.favicon.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf((csrfConfig) ->
csrfConfig.disable()
)
.authorizeHttpRequests(authorize -> authorize
.requestMatchers("/users/email-check", "/users/code-check", "users/register",
"/notice/create", "/notice/list", "/notice/{noticeId}", "/notice/view/{noticeId}", "/faq/create", "faq/{faqId}",
"/data-set/filter", "/data-set/count","/data-set/ratio", "/data-set/incrementDownload/{datasetId}", "/data-set/top10",
"/data-set/theme", "/data-set/{datasetId}", "/data-set/category/{themeId}", "/data-set/filter", "/faq/list", "faq/{faqId}",
"/users/login", "/users/logout", "/users/admin-check", "/s3/upload", "/s3/delete/{resourceId}",
"/users/delete-account", "/users/session-check", "/data-set", "/request/list","/request/list/{requestId}/review", "/request/{requestId}","/request/question",
"/request/question/{questionId}", "/request/answer", "/request/answer/{answerId}","/data-set/search-sorted", "/data-set/search-sorted/{category}",
"/trend/**", "data-set/group-by-theme", "/region", "/analysis",
"/v3/api-docs/**", "/swagger-ui/**", "/swagger-ui.html", "/data-set/download/{datasetId}").permitAll()
.anyRequest().authenticated()
)
.httpBasic(httpBasic -> httpBasic.disable())
.formLogin(formLogin -> formLogin.disable())
.sessionManagement(session -> session
.sessionFixation().migrateSession()
.maximumSessions(1)
)
.addFilterBefore(new Utf8Filter(), UsernamePasswordAuthenticationFilter.class);

return http.build();
}
}
46 changes: 46 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
spring.application.name=Favicon

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=${SPRING_MAIL_USERNAME}
spring.mail.password=${SPRING_MAIL_PASSWORD}
spring.mail.properties.mail.smtp.auth=ture
spring.mail.properties.mail.smtp.starttls.required=true

spring.data.redis.host=redis
spring.data.redis.port=6379

# AWS
aws.s3.bucket-name=${AWS_S3_BUCKET}
aws.s3.region=${AWS_S3_REGION}
aws.s3.access-key=${AWS_S3_ACCESS_KEY_ID}
aws.s3.secret-key=${AWS_S3_SECRET_ACCESS_KEY}


# DB
spring.datasource.url=${SPRING_RDS_URL}
spring.datasource.username=${SPRING_RDS_USERNAME}
spring.datasource.password=${SPRING_RDS_PASSWORD}
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.datasource.driver-class-name=org.postgresql.Driver

# tomcat UTF-8
server.tomcat.uri-encoding=UTF-8
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=true

# api-docs
spring.api-docs.enabled=true
spring.api-docs.version=openapi_3_0
spring.api-docs.packagesToScan=mokindang.jubging
spring.api-docs.path=/v3/api-docs

# swagger
springdoc.default-consumes-media-type=application/json
springdoc.auto-tag-classes=true
springdoc.api-docs.groups.enabled=false
springdoc.swagger-ui.operations-sorter=method
springdoc.swagger-ui.path=/swagger-ui.html
Loading