2024. 10. 25. 12:38ㆍDocker
- 첨부파일 유지하는방법
- nginx와 연동하는 방법
- 파일업로드를 컨테이너에 시켜놨다가 지우면 다 날라가는데 오늘 방법으로 배우면 안지워진다.
1. 개발단계
- 개발
- 이미지 생성
- 도커허브엥 올리고
- 다운로드 실행 컨테이너
> 이 순선데 개발단계에서 끊어버린다.
Volume
- 이 안에 디스크를 나눠쓴다고 보면된다.
> 파티셔닝과 비슷하긴하다.
>> 네트워크 생성한거처럼 볼륨도 생성 가능
>>> 볼륨에 자료를 남기는 방법이 있다. > 볼륨이 삭제되기전까지 파일은 유지 ( USB 하나 추가하는 느낌 )
- 사용하는방법
1. 도커내부의 볼륨을 사용하는 방법
2. 좀더 편하게 사용할 수 있는 방법 = 바인드볼륨
- 호스트 컴퓨터에 있는 폴더 - 도커의 컨테이너가 같이 쓰는것을 만들어주는것
3. 바인드 볼륨
여러개의 컨테이너가 하나의 볼륨을 쓸 수가 있다.
1) 로컬환경에서 파일 업로드하는법
2) 도커환경에서 업로드 했을때 어디 위치로 생기는지
3) 바인드 볼륨을 지정해서 도커에 컨테이너를 만들었을때 > 내가 지정한 파일이 올라가는것
4) nginx 서버가 똑같은 바인드 볼륨을 쓰는지
> 파일업로드 해주고 이미지 서비스는 nginx를 통해 서비스가 가능해진다.
- 운영체제에서 직접 수정할 일이 있다면 바인드 마운트
docker volume create 이름 / docker volumn rm 이름
- 실제로 어느 폴더가 만들어지는지를 확인해야 한다.
- 업로드용 폴더를 하나만들고 업로드 폴더에 파일을 확인한다.
[CQRS]
- 명령과 질의, 책임을 분리한다는 뜻의 약자
- 왜쓰는가?
> 데이터를 쓰는 빈도보다 데이터를 읽는 빈도가 훨씬 높은 경우 쓰기를 위한 데이터 모델을 데이터 조회에 그대로 사용하는 경우 정규화된 테이블에 대한조인이 연산이 필요하여 성능에 부정적인 영향을 미칠 수 있습니다.
1. WAS에서 처리하게끔
2. 웹서버에서 이미지를 읽게끔
후자가 좋다. > WAS = 동적인것을 작업하기 위해 사용하는거지 이미지를 위해하는것은 낭비
WAS는 비쌈
- 이미지는 nginx서버에 다 빠져있다.
> 다운로드는 여기서 하게하자
>> 근데 우리는 도커를 사용하고있다.
>>> 이미지 업로드는 = 스프링, 이미지를 조회하고 다운받는작업들 = 스프링을 쓰지않고 빼도된다.
근데 문제는 docker를 사용하고이싿. ( 격리되어있다 )
도커가 쓰고있는폴더, nginx가 쓰고있는 폴더가 다르다 > 통합이 필요함 => Volume bind
[Git Action]
- CICD라고 한다.
1. jenkins - Ci/CD실행을 지원하는 다양한 도구와 방법들이 나오고 있는데 가장 많이 사용된다.
> 멘토님들의 일거리로 남겨줄예
2. ciecle ci
3. GitLab 뭐 등등 많다.
- bootJar > image build > login > hub upload
> 이런작업들을 모아놓은것들을 짜는데 github action은 그것을 짜는것이다.
>> push가 되면 뭘할거야 라는것들을 적어놓는다.
>>> github문서에 잘 공유가 되어있다.
[실습]
1. util.packpage / CustomFileUtil.class
2. UploadController.class
3. dto.package / SampleDTO.class
@Data
public class SampleDTO {
private String title;
private MultipartFile[] files;
private List<String> uploadedFileNames;
}
4. build.gradle
implementation 'net.coobird:thumbnailator:0.4.19'
5. UtilController
@RestController
@RequestMapping("/api/v1/file")
@Log4j2
@RequiredArgsConstructor //fileUtil 주입받아야 하니까
public class UploadController {
private final CustomFileUtil customFileUtil;
@PostMapping("upload")
public List<String> upload(SampleDTO sampleDTO)
{
log.info(sampleDTO);
List<String> fileNames = customFileUtil.saveFiles(Arrays.asList(sampleDTO.getFiles()));
log.info(fileNames);
return fileNames;
};
}
6. 서버 스타트
> upload folder가 생김
7. postman
8. ./gradlew bootJar
9. cmd
docker build -t kimboris/d2 .
> 실행
>> 폴더만 확인할 예정
>>> 쉬는시간 전에 올라갔을때 폴더모양이 어떻게 올라갔는지 확인
10. docker images
d2 image 확인
11. docker run --name d2_container -p 8081:8080 kimboris/d2 ( 외부에 노출하는것 8081 )
- 지금 db쓰는사람들은 network들어가야한다. 또한, 환경변수도
> 에러가 안났으면 d2_container가 만들어졌다
>> 걔를 열어보면 Files가 있다. > upload라는 폴더가 생성이 되어있다.
>>> postman에 8081로 파일 쏴주면 도커 컨테이너내부에 이미지가 생성됨
>>>> 만약, 컨테이너를 지우게된다면? 파일도 날아감
12. 이 컨테이너 지울거다
13. c://zzz폴더에 만든다.
- 컨테이너 밑에 업로드는 C://zzz 라고 제어를 해준다.
- '-v'라는 옵션이 들어간다.
docker run --name d2_container -v c:\zzz:/upload -p 8081:8080 kimboris/d2
14. postman 업로드
C://zzz 밑에 파일이 업로드 된다.
14-1.
docker run --name d2_container -p 8081:8080 --network dev_network -v C:\zzz:/upload -e spring.datasource.url=jdbc:mariadb://maria1024:3306/bootdb2 zk2840174/d2:latest
어제꺼 쓰려면 이렇게 하면됨
15. CQRS
3단계
1. cmd
docker run --name nginx_container -p 8083:80 nginx
2. 이 HTML파일 (nginx) 가 어디있는지 알아야 C://zzz로 연결시켜줘야 얘가 서비스 할 수 있다.
단점 : security처리가 안된다.
> Security로 검증해서 다운받아야 하는 컨텐츠같은것 > 원래라면 nginx에서 볼 수 없게 다른데서 업로드해야한다
>> 사실 제일간단한것 = AWS 엠플리파이에 깃헙에 코드주면알아서 다 해줌
/usr/share/nginx/html 이경로가 C://zzz가 되면 된다.
3. nginx 컨테이너 삭제
4. docker run --name nginx_container -p 8083:80 -v C:\zzz:/usr/share/nginx/html nginx
[4 단계]
1. 만든 코드 Github에 올리자
2. GitAction
3. .github/workflows 라는 폴더가있어야 한다. 그리고 yml파일을생성 github-actions-demo.yml (이름은상관없다)
4. 업로드하면 자동으로 이 파일을 가지고 실행을 한다. Like 쿠버네티스
5. 스텝별로 쫙쫙 실행함
6. 작업끝.
새로운 프로젝트 생성
1. 깃헙
2. 도커 허브에 이미지 올라가는것
3. 와치타워써서 실행하고 있는데(도커) 코드를 바꿔서 올리면 자동으로 바뀌는것
1. springboot / web만 추가해서 생성
2. dockerfile생성
FROM openjdk:17-jdk-alpine
#jar파일을 app.jar파일로 복사를 해서 실행하는것
COPY build/libs/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
3. controller / SampleController.class
@RestController
@Log4j2
@RequestMapping("/sample")
@RequiredArgsConstructor
public class SampleController {
@GetMapping("hello")
public String[] hello() {
log.info("=======================================================================");
log.info("hello");
return new String[]{"Hello", "World"};
}
}
4. .github.package / workflows.package
5. .github/workflows/citest.yml
공식문서 보는게 제일 좋다.
6. github share / commit / push 까지
7. 프로젝트 확인
git action가서 삭제 하고 SampleController 대충 수정하고 다시 커밋 푸시
> 이 브랜치의 action을 살펴보면 build가 되고있는것을 볼 수 있다.
>> build되다가 error가 뜸
>>> branch에 commit이 될 때마다 동작을 한다.
일단 에러뜸
>
> 권한이 없어서 생기는 오류
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- 그래들 시작전에 작성
8. commit push
gitAction확인하면 build된다 ( 근데 나는 안됨 )
9. yml
name: Java CI with Gradle
#이벤트 ( 어느 브랜치에 일어나냐 )
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Build with Gradle Wrapper
run: ./gradlew build -x test
이렇게 하면 테스트코드 동작안함
> 깃액션 확인
>> 토큰이 필요하고 private한 세팅이 필요하다.
>>> secret세팅을 잡아주고 docker login 체크를 해줘야한다.
10. docker hub 토큰 만든다.
- 토큰을 수정하고싶다? 수정못함
> 그래서 처음 만들었을때 카피를 잘해놔야한다.
>> account setting > Personal access TOken
>>> 수정이라는 개념이 없다.
>>>> Generate new Token
Generate -> 토큰값 저장
11. gitaction >
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
이 부분이 필요하다
12. setting - actions - repository secret
DOCKER_USER
DOCKER_TOKEN secret 생성
13. yml
name: Java CI with Gradle
#이벤트 ( 어느 브랜치에 일어나냐 )
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
# Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies.
# See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Build with Gradle Wrapper
run: ./gradlew build -x test
- name: Log in to Docker Hub
run:
echo "${{ secrets.DOCKER_TOKEN }}" | docker login -u "${{ secrets.DOCKER_USER }}" --password-stdin
14. git action 잘돌아가는지 확인
15. yml 추가
- name: Build the Docker image
run: docker build -t kimboris/d2_image:latest .
- name: Push the Docker image to Docker Hub
run: docker push kimboris/d2_image:latest
16. Docker hub 가면 image생성된거 볼 수 있다.
- 여기까지하면 배포가 자동화
17. docker container d2 지워버리자, images에도 d2와관련된 애들 다 삭제
그 후 : docker run --name d2_container -p 8080:8080 kimboris/d2_image:latest
18. commit push (테스트용 수정했음)
> repository souce code 추가된것 확인
19. watchtower 설정
docker run -d --name watchtower -v /var/run/docker.sock:/var/run/docker.sock -e WATCHTOWER_POLL_INTERVAL=60 containrrr/watchtower
- 1분에 한번씩 체크해서 업데이트
20. 컨테이너에 watchtower 생성된거 확인
> 프로젝트 내부 수정하고 커밋 푸시
>> 반영하면?
--------------------------------------------------------------------------------------------------------------------------------------------------------------
[젠킨스]
- 오픈소스 자동화 서버
CICD파이프라인 자동화 애플리케이션 빌드, 테스트, 베포
>진정한 CI/CD도구
단점 : 젠킨스가 톰캣을 쓴다. 젠킨스 설치필요, 설정이 복잡하다.
[와치타워]
- 도커의 컨테이너의 이미지를 자동으로 업데이트 한다.
새로운 이미지가 있을떄 DOcker 컨테이너를 자동으로 업데이트
> 기본세팅은 하루마다 체크해서 업데이트 > 하루보다는 짧게 줘야한다. (개발시)
>> Docker의 이미지를 관리 ( Docker만 관리 ) > 소규모나 중간규모
>>>
--------------------------------------------------------------------------------------------------------------------------------------------------------------
DB문제있을시
yml, gradle 파일 삭제 및 수정
삭제
spring:
application:
name: api1
datasource:
driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3316/bootdb2
username: bootdb2user
password: bootdb2user
hikari:
minimum-idle: 2
maximum-pool-size: 5
connection-timeout: 5000
jpa:
hibernate:
ddl-auto: update
dialect: org.hibernate.dialect.MariaDB103Dialect
show-sql: true
properties:
hibernate:
format_sql: true
private final DataSource dataSource;
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
servlet:
multipart:
max-file-size: 5MB
max-request-size: 20MB
location: upload
enabled: true
이 세가지 삭제하면된다.
'Docker' 카테고리의 다른 글
[1] Docker (0) | 2024.10.16 |
---|