티스토리 뷰

728x90

최근에 오렌지파이5를 구매하고 기존에 진행했던 프로젝트를 해당 기기에 도커를 통해 배포하면서 만난 여러가지 문제점들을 기록해두고자 한다.

사실 대부분의 문제점은 도커를 오랜만에 사용하면서 기존에 만나보았던 문제점들이지만 도커를 자주 사용할 것같지 않아 미리 정리해두려 한다.

 

 

아키텍처

가장 먼저 직면했던 것은 아키텍처 문제였다. Windows 환경에서 개발한, 즉 x86_64, amd64 아키텍처 환경에서 개발하고 amd64 아키텍처에 배포하던 기존의 환경에서 arm64, aarch64 아키텍처에 배포하면서 아키텍처가 다른 문제가 발생한 것이었다.

 

가장 먼저 개발 환경의 아키텍처와 배포 환경의 아키텍처를 확인이 필요한데 다음 커맨드를 통해 확인할 수 있다.

$ lscpu | grep Architecture

Windows환경이라면
Architecture:                    x86_64
arm64 환경이라면
Architecture:                    aarch64

 

이렇게 아키텍처가 달라지면 이미지를 생성하기 위한 Dockerfile의 설정도 아래와 같이 달라져야 한다.

 

먼저 기존의 Dockerfile은 다음과 같다.

#x86_64 환경. 
FROM openjdk:11

ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

 

이를 arm64 환경에 맞게 변경한 코드는 다음과 같다.

(중요) 그리고 build option으로 --platform=linux/arm64 를 넣어주어야 한다.

 

베이스 이미지는 사용하려는 이미지마다 달라지는데 대부분 유명한 이미지들은 아키텍처마다 각각 이미지를 배포하고 있으니 그것을 가져다가 사용하면 된다.

#arm64 환경.
FROM arm64v8/openjdk:11

ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

 

이제 생성된 이미지의 아키텍처를 다음 커맨드로 확인해보자.

$ docker image inspect {이미지이름} | grep Architecture

아래와 같이 나오면 정상적으로 빌드가 된 것이다.
"Architecture": "arm64",

 

이제 해당 이미지는 arm64 아키텍처에 배포될 준비가 완료되었다. 이 이미지를 docker push, pull하여 사용하도록 하자.

$ docker image push {repository}/{image_name}:latest

$ docker image pull {repository}/{image_name}:latest

 

Docker 관련

너무 유명한 것들이라 아주 조금만 구글링해봐도 나오는 문제들이지만 미래의 나를 위해 정리해둔다.

 

1. docker {command} 실행시 다음과 같은 권한 에러 발생.

Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json": dial unix /var/run/docker.sock: connect: permission denied

다음 커맨드 실행으로 권한 부여
$ sudo chmod 666 /var/run/docker.sock

 

2. docker-compose up -d 실행시 Docker daemon 문제 발생

Couldn’t connect to Docker daemon at http+docker://localhost - is it running?

다음 커맨드처럼 root 권한으로 실행. 항상 발생하는 문제는 아님.
$ sudo docker-compose up -d

 

3. docker-compose up -d 실행시 version is not supported 문제 발생

ERROR: Version in "./docker-compose.yml" is unsupported. You might be seeing this error because you're using the wrong Compose file version. Either specify a supported version (e.g "2.2" or "3.3") and place your service definitions under the`services`key, or omit the`version`key and place your service definitions at the root of the file to use version 1. For more on the Compose file format versions, see https://docs.docker.com/compose/compose-file/

아래 커맨드로 버전을 확인하고 버전간의 호환성 문제라면 그쪽으로 더 구글링 후 문제 해결.
버전의 문제가 아니라면 기존 3.8 버전을 3.7로 내려준다.
$ docker -v
$ docker-compose -v

 

환경변수 설정

 

ddl-auto

기존 환경에서 잘 동작하던 프로젝트가 배포 환경에서 다음과 같은 에러가 발생했다. 

Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

 

이는 ddl로 table 설정이 되어있지 않아 발생한 문제인데 개발 환경과 배포 환경의 ddl-auto 설정이 달랐던 것이 원인이었다. 이를 해결한 방법은 다음과 같은데 제대로 된 문제 해결이라기 보다는 workaround에 가깝다. 제대로 문제를 해결하려면 schema를 처음부터 제대로 생성하는 방법이 맞지 않을까 생각한다.

 

# docker-compose.yml

version: "3.7"     

services:
  api:
    image: my_id/my_image-arm64
    container_name: api
    environment:
      - spring.jpa.hibernate.ddl-auto=create # 맨 처음 실행시 create로 실행. 그 이후부터는 none으로 바꿔서 실행.

...

 

redis hostname

레디스와 같이 배포하면서 다음과 같은 에러가 발생했다.

ERROR 23-01-09 08:19:29[main] [SpringApplication:830] - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'enableRedisKeyspaceNotificationsInitializer' defined in class path resource [org/springframework/boot/autoconfigure/session/RedisSessionConfiguration$SpringBootRedisHttpSessionConfiguration.class]: Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379
...
Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379

 

해결 방법은 다음과 같다.

 

배포 환경 변수 파일에서 localhost를 redis로 변경하거나,

# application-prod.properties

spring.redis.host=localhost 를
spring.redis.host={redis_container_name} 으로 변경

 

아래와 같이 docker-compose.yml에서 overwrite해준다.

# docker-compose.yml

version: "3.7"     

services:
  api:
    image: my_id/my_image-arm64
    container_name: api
    environment:
	- spring.redis.host={redis_container_name}
...

 

마지막으로 동작하는 docker-compose.yml 전문을 올린다.

 

version: "3.7"

services:
  api:
    image: my_id/my_image-arm64
    container_name: api
    ports:
      - 8080:8080
    depends_on:
      - db
      - redis
    environment:
      - spring.redis.host={redis_container_name}
      - spring.jpa.hibernate.ddl-auto=update
      - SPRING_PROFILES_ACTIVE=prod
      - DB_HOST={mariadb_container_name}
      - DB_USERNAME=root
      - DB_PASSWORD=
      - MAIL_USERNAME=
      - MAIL_PASSWORD=
      - IMP_KEY=
      - IMP_SECRET=

  redis:
    container_name: {redis_container_name}
    image: redis
    restart: unless-stopped
    expose:
      - "6379"
    depends_on:
      - db

  db:
    container_name: {mariadb_container_name}
    image: mariadb
    restart: unless-stopped
    environment:
      - MARIADB_USER=root
      - MARIADB_PASSWORD=
      - MARIADB_ROOT_PASSWORD=
      - MARIADB_DATABASE=
    expose:
      - "3306"
    volumes:
      - mariadb
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함