Post

[프롬프트 엔지니어링] 초기 설정

liquibase, docker 설정

[프롬프트 엔지니어링] 초기 설정

✏️ 프로젝트 시작

다른 팀원이 만든 Repository에서 프로젝트를 clone하는 경우

  1. enable annotation processing 옵션 켜기
  2. 실행이 안되는 경우, build 설정 gradle -> intellij로 바꾸기


■ Docker 설정

Docker를 사용해서 postgres 이미지를 불러오고, 연결하는 작업

  1. Dockerfile, initial.sql 작성 ```c //Dockerfile FROM postgres:16

ENV POSTGRES_USER=myuser ENV POSTGRES_PASSWORD=mypassword ENV POSTGRES_DB=mydatabase

COPY initial.sql /docker-entrypoint-initdb.d/

1
2
3
4
5
6
```c
//initial.sql
-- init/01_init.sql
CREATE USER cluster23 WITH ENCRYPTED PASSWORD 'cluster23';
CREATE DATABASE promptfordev;
GRANT ALL PRIVILEGES ON DATABASE promptfordev TO cluster23;


  1. docker-compose.yml, application-dev.yml 작성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//docker-compose.yml
version: '3.1'
services:
  postgres:
    image: postgres:16
    container_name: postgres
    environment:
      POSTGRES_USER: cluster23
      POSTGRES_PASSWORD: cluster23
      POSTGRES_DB: promptfordev
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - backend


  api:
    build:
      context: .
      dockerfile: ./docker/api/Dockerfile
    container_name: api
    environment:
      SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/promptfordev
      SPRING_DATASOURCE_USERNAME: cluster23
      SPRING_DATASOURCE_PASSWORD: cluster23
    ports:
      - "8080:8080"
    depends_on:
      - postgres
    networks:
      - backend

networks:
  backend:
    driver: bridge

volumes:
  postgres_data:
1
2
3
4
5
6
7
8
//application.yml
...
  datasource:
    url: jdbc:postgresql://localhost:5432/promptfordev
    username: cluster23
    password: cluster23
    driver-class-name: org.postgresql.Driver
...


  1. liquibase를 사용하는 경우, application.yml에 liquibase 설정도 넣어야 한다.


Docker로 liquibase, DB 연결시 주의해야 할 점

  1. User, PASSWORD, DATABASE를 일치시킬 것!
  2. 자동증가값(generatedValue)이 존재하는 경우, liquibase에서 Table을 생성할 때 sequence도 포함해야 한다.
  3. relation이 없다고 뜨는 경우, application.yml에서 liquibase:true로 설정되어 있는지 확인할 것


■ 발생할 수 있는 오류들

1. /usr/local/bin/docker-compose: line 1: Not: command not found

Docker-compose 버전이 맞지 않아서 발생하는 오류였다. 다운그레이드를 하니 해결되었다.

다운 그레이드 과정

  1. docker-compose 삭제 (rm 명령어로)
  2. docker-compose 다운로드
    1
    2
    3
    
    DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
    mkdir -p $DOCKER_CONFIG/cli-plugins
    curl -SL https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-darwin-aarch64 -o $DOCKER_CONFIG/cli-plugins/docker-compose
    
  3. docker-compose의 위치를 /usr/local/bin/docker-compose로 이동
    1
    2
    
    sudo mv $DOCKER_CONFIG/cli-plugins/docker-compose /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose
    

homebrew로도 설치할 수 있지만, homebrew는 최신 버전만 설치하는 것 같다.


2. Liquibase 관련 오류

application.yml에서 Liquibase 설정할 때, 타이핑 문제로 인해 오류가 발생했다. 띄어쓰기 한칸이 더 되어 있었다. yml 파일을 사용할 때는 항상 들여쓰기에 주의하자.


3. 2024-05-15 01:22:45.347 UTC [85] FATAL: database "promptfordev" does not exist

application.yml 파일을 수정하니 해결되었다.

1
2
3
4
  datasource:
    url: jdbc:postgresql://${POSTGRESQL_HOST:localhost}:${POSTGRESQL_PORT:5432}/${POSTGRESQL_DB:promptfordev}
    username: ${POSTGRESQL_USER:cluster23}
    password: ${POSTGRESQL_PASSWORD:cluster23}

-> 수정

1
2
3
4
    url: jdbc:postgresql://localhost:5432/promptfordev
    username: cluster23
    password: cluster23
    driver-class-name: org.postgresql.Driver


4. Version 충돌

다음과 같이 version을 설정했다. JDK - 21 Lombok - 1.18.30 docker-compose - 2.20.3 docker - 26.0.0

5. docker 관련 오류

오류 메시지: java.lang.IllegalStateException: No Docker Compose file found in directory '/app/.'

docker-compose build 후에 docker-compose up -d로 실행하니 위와 같은 오류가 발생했다. 이전에 진행했던 프로젝트와 완전히 똑같은 환경에서 실행했는데도 실행되지 않았다.


First try

처음에는 Dockerfile에서 COPY 커맨드가 잘 작동하지 않아서 docker-compose.yml이 컨테이너에 복사되지 않는 오류라고 생각했다.
main 메소드의 run을 주석처리 한 뒤에, Dockerfile에 CMD ["tail", "-f", "/dev/null"] 커맨드를 작성해서 컨테이너를 실행하되 spring application을 실행하지 않도록 설정했다.
그런 다음에 직접 컨테이너의 폴더에 들어가서 확인해보았더니, COPY 커맨드는 잘 작동하는 것을 알게되었다.


Second try

application.yml에서

1
2
3
4
5
spring: 
  docker: 
    compose: 
      enabled: 
        false 

로 설정한 뒤에 똑같이 진행해보았다. 달라지는 것은 없었다.


Third try

Dockerfile을 빌드 한 뒤에 docker-compose build를 실행해보았다. 달라지는 것은 없었다.


Last try

start.spring.io 로 접속해서 아예 새로운 프로젝트를 만든 뒤에 내용을 붙여넣기 했다. 그랬더니 잘 실행되는 것을 확인했다.
기존과 단 한가지 다른점은 build.gradle 파일이었다.
여러가지 라이브러리를 넣었다 뺐다 하면서 어떤 라이브러리가 문제를 일으키는지 확인해보았더니, runtimeOnly 'org.springframework.boot:spring-boot-docker-compose' 이 코드가 문제를 일으키는 것을 알게되었다.
내가 생각한 오류의 발생 로직은 다음과 같다.

  1. docker-compose build로 빌드 시작
  2. runtimeOnly로 설정되어 있는 경우, 빌드는 runtime이 아니므로 docker-compose 라이브러리가 빌드에서 제외됨.
  3. docker-compose 라이브러리가 빠진 상태로 application.jar 파일이 생성
  4. 컨테이너가 application.jar파일을 실행하면 docker관련 라이브러리가 없어서 오류 발생

Runtime Vs Compile Time

This post is licensed under CC BY 4.0 by the author.