https://github.com/GBSB2023/GBSB

 

GitHub - GBSB2023/GBSB: It is an app that provides a load map of the Department of Engineering.

It is an app that provides a load map of the Department of Engineering. - GBSB2023/GBSB

github.com

Docker 기반 Kotlin 앱 빌드

Git에 있는 Kotlin Android 프로젝트를 활용하여, Docker 기반 빌드 환경을 구축하는 실습을 진행

🔥 목표

  1. Docker를 활용하여 Kotlin Android 앱 빌드 환경 구축
  2. Docker 컨테이너에서 앱을 빌드하고, APK 파일을 생성
  3. 안드로이드 디바이스에 APK 파일 설치 후 작동 확인

APK 파일 생성

✅ 단계별 동작

root@docker-project:~# curl -fsSL https://get.docker.com -o get-docker.sh
root@docker-project:~# chmod +x get-docker.sh
root@docker-project:~# ./get-docker.sh
root@docker-project:~# docker -v

1. GitHub에서 코드 가져오기

  • 목표: Docker 컨테이너 안에서 Kotlin 프로젝트를 자동으로 다운로드
  • 작업 내용:
    • wget 또는 git clone을 사용하여 최신 코드 다운로드
    • 컨테이너 내에서 코드가 정상적으로 복사되는지 확인
    •  효과: 항상 최신 상태의 프로젝트를 컨테이너에서 가져와 빌드 가능

wget으로 GitHub 코드 다운로드

root@docker-project:~# wget https://github.com/GBSB2023/GBSB/archive/refs/heads/main.zip
root@docker-project:~# apt install -y unzip
root@docker-project:~# unzip main.zip && mv GBSB-main/* . && rm -rf GBSB-main main.zip

📂 파일 구성

project-root/                      # 최상위 프로젝트 폴더 (현재 작업 중인 폴더)
│── app/                           # GitHub에서 가져온 Kotlin 프로젝트
│   ├── google-services.json      
│── Dockerfile                     # Docker 빌드 설정 파일
│── docker-compose.yml             # Docker 실행 자동화 파일
│── gradle/                        # Gradle Wrapper 관련 폴더
│── .gitignore                     # Git 무시 파일
│── README.md                      # 프로젝트 설명
│── build.gradle                   # 프로젝트 빌드 설정
│── gradle.properties              # Gradle 속성 파일
│── gradlew                        # Gradle 실행 파일 (Linux/macOS)
│── gradlew.bat                    # Gradle 실행 파일 (Windows)
│── settings.gradle                # Gradle 설정 파일

2-1. Dockerfile 작성 (빌드 환경 만들기)

  • 목표: Android SDK, Gradle, JDK 등이 포함된 컨테이너 환경 구축
  • 작업 내용:
    • Android SDK 및 빌드 도구 설치
    • Kotlin 프로젝트를 컨테이너에서 실행할 수 있도록 환경 구성
    •  효과: 어디서든 동일한 환경에서 앱을 빌드할 수 있음

Dockerfile 및 docker-compose.yml을 project-root/에 저장

  • Dockerfile은 프로젝트 전체를 포함해야 하므로 최상위 디렉토리(project-root/)에 위치
  • docker-compose.yml도 최상위 디렉토리에 위치해야 docker-compose up 실행 가능

📌 Dockerfile

# Start with a Debian base image
FROM debian:bullseye-slim

# Install required packages including wget, unzip, and openjdk
RUN apt-get update && apt-get install -y \
    wget \
    unzip \
    openjdk-17-jdk \
    && wget https://dl.google.com/android/repository/commandlinetools-linux-6609375_latest.zip -O /android-sdk.zip \
    && mkdir -p /opt/android-sdk && unzip /android-sdk.zip -d /opt/android-sdk \
    && rm /android-sdk.zip \
    # Check the directory structure after unzip
    && ls /opt/android-sdk \
    # Check if cmdline-tools-linux directory exists, if not, move the correct folder
    && if [ -d "/opt/android-sdk/cmdline-tools-linux" ]; then mv /opt/android-sdk/cmdline-tools-linux /opt/android-sdk/cmdline-tools; fi \
    && if [ -d "/opt/android-sdk/tools" ]; then mv /opt/android-sdk/tools /opt/android-sdk/cmdline-tools; fi \
    && ls /opt/android-sdk/cmdline-tools \
    # Set ANDROID_SDK_HOME to ensure sdkmanager can create settings in the correct location
    && export ANDROID_SDK_HOME=/opt/android-sdk/.android \
    # Ensure sdkmanager can find the SDK root
    && export SDK_ROOT=/opt/android-sdk \
    # Accept licenses and install Android SDK components with explicit sdk_root
    && yes | /opt/android-sdk/cmdline-tools/bin/sdkmanager --sdk_root=/opt/android-sdk --licenses \
    && /opt/android-sdk/cmdline-tools/bin/sdkmanager --sdk_root=/opt/android-sdk "platform-tools" "platforms;android-30" "build-tools;30.0.3"

# Set ANDROID_HOME and PATH
ENV ANDROID_HOME=/opt/android-sdk
ENV PATH=$PATH:$ANDROID_HOME/platform-tools:$ANDROID_HOME/cmdline-tools/bin

# Set working directory to /app
WORKDIR /app

# Copy the entire project to the container
COPY . .

# Copy google-services.json to the appropriate location in the container
COPY google-services.json /app/app/google-services.json

# Run gradlew to build the project
RUN chmod +x gradlew && ./gradlew --no-daemon assembleDebug

# Keep the container running
CMD ["tail", "-f", "/dev/null"]

 

📌 google-services.json

{
  "project_info": {
    "project_number": "816514819246",
    "firebase_url": "https://gbsb-74caa-default-rtdb.firebaseio.com",
    "project_id": "gbsb-74caa",
    "storage_bucket": "gbsb-74caa.appspot.com"
  },
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "1:816514819246:android:f87e9655c251acf0e4793f",
        "android_client_info": {
          "package_name": "com.example.gbsb"
        }
      },
      "oauth_client": [
        {
          "client_id": "816514819246-13cp254klmqm4ktgoe31r86n6sk9cg8s.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "com.example.gbsb",
            "certificate_hash": "402b4c39736f11a698cd5a3c5c3c1aec5897e9ac"
          }
        },
        {
          "client_id": "816514819246-5re14fnj5npf2jucd85r23kq7eranhu0.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "com.example.gbsb",
            "certificate_hash": "efa7bf65545ef1d11327efe423b73693b738ab7f"
          }
        },
        {
          "client_id": "816514819246-mbffc676on2ee341qeqt91dsfhisag9u.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "com.example.gbsb",
            "certificate_hash": "525c44affa083b51e97f3be954f870165c062ce6"
          }
        },
        {
          "client_id": "816514819246-o8vm8uegnhhutl3pi1mn92vb2cti8qar.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "com.example.gbsb",
            "certificate_hash": "4756f3db9505b4a31e78e84040336dba631264d0"
          }
        },
        {
          "client_id": "816514819246-q123n7kf1jda0ql7p748nkubrqbvkio5.apps.googleusercontent.com",
          "client_type": 3
        }
      ],
      "api_key": [
        {
          "current_key": "AIzaSyBfmp3UE79qHUqIHJHW7B_ZUZ9WziCiGVg"
        }
      ],
      "services": {
        "appinvite_service": {
          "other_platform_oauth_client": [
            {
              "client_id": "816514819246-6ig0fvmg0m6n41c21rb4u7j5fg8r90dd.apps.googleusercontent.com",
              "client_type": 3
            }
          ]
        }
      }
    }
  ],
  "configuration_version": "1"
}

3. Docker Compose 설정 (자동 실행)

  • 목표: docker build & docker run 과정을 자동화
  • 작업 내용:
    • docker-compose.yml을 작성하여 한 줄 명령어로 실행
    • APK가 정상적으로 빌드되는지 테스트
    •  효과: 한 줄 명령어로 앱 빌드 가능, 개발 속도 향상

📌 docker-compose.yml

services:
  android-build:
    build: .
    container_name: android-app
    volumes:
      - ./app/build/outputs/apk/debug:/output

📂 추가 파일 구성

project-root/                      # 최상위 프로젝트 폴더 (현재 작업 중인 폴더)
│── app/                           # GitHub에서 가져온 Kotlin 프로젝트
│   ├── google-services.json      
│── Dockerfile                     # Docker 빌드 설정 파일
│── docker-compose.yml             # Docker 실행 자동화 파일

4. 로컬에서 Docker로 앱 빌드 테스트

  • 위 Dockerfile을 기반으로 이미지를 빌드하고 컨테이너에서 앱을 빌드
  • APK 파일이 정상적으로 생성되는지 확인

1) docker-compose.yml을 사용하지 않고, 이미지를 빌드 후 컨테이너 생성 및 실행

docker build -t android-app .
docker run -it --name android-app android-app
# Docker 이미지 빌드
docker build -t android-builder .

# 컨테이너 실행 및 빌드
docker run --rm -v $(pwd):/app android-builder
# docker run 실행 후 생성된 APK 파일을 로컬 머신으로 복사하여 확인
# docker run --rm -v $(pwd):/app android-builder ./gradlew assembleDebug

 

2) docker-compose.yml을 사용해 명령어 한 줄로 빌드

docker compose up --build -d

root@docker-project:~# docker exec -it android-app bash
  • app/build/outputs/apk/debug/app-debug.apk 파일을 확인

5. APK 파일 로컬로 복사

  • APK 파일을 로컬로 복사한 후, 해당 파일을 Android 기기에 설치할 수 있음
root@docker-project:~# docker cp android-app:/app/app/build/outputs/apk/debug/app-debug.apk ./app-debug.apk


APK 파일 설치

1. 안드로이드 기기 연결

https://developer.android.com/studio/run/device?_gl=1*13t0nsd*_up*MQ..*_ga*ODE3NDY0NTUxLjE3NDI5MTY1OTQ.*_ga_6HH9YJMN9M*MTc0MjkxNjU5My4xLjAuMTc0MjkxNjYyNS4wLjAuMTkwNTczNTc3OQ..&hl=ko

 

하드웨어 기기에서 앱 실행  |  Android Studio  |  Android Developers

Android 디버그 브리지(ADB) 연결을 통한 테스트 및 디버깅을 위해 개발 환경 및 Android 기기를 설정하는 방법을 알아보세요.

developer.android.com

  • USB 디버깅 활성화: 안드로이드 기기에서 개발자 옵션을 활성화하고, USB 디버깅을 활성화해야 합니다.
    1. 설정 > 휴대전화 정보로 이동하고, 빌드 번호를 7번 클릭하여 개발자 모드를 활성화합니다.
    2. 설정 > 시스템 > 개발자 옵션으로 이동하여 USB 디버깅을 활성화합니다.
  • USB 케이블로 연결: Android 기기를 USB 케이블로 PC에 연결합니다. 연결 후, adb devices 명령어를 실행하면 기기가 표시되어야 합니다.

2. ADB 데몬 확인

  • adb devices를 실행하여 기기가 제대로 연결됐는지 확인하세요. 만약 여전히 기기가 보이지 않으면, adb 데몬을 수동으로 시작할 수 있습니다:
  • adb start-server
  • 기기 확인: 다시 한 번 adb devices 명령어를 실행하여 기기가 목록에 나타나는지 확인하세요.
root@docker-project:~# apt install -y adb
root@docker-project:~# adb devices

# 연결 전

https://stackoverflow.com/questions/12044162/android-adb-doesnt-work-at-ubuntu-in-vmware-workstation

 

Android adb doesn't work at Ubuntu in VMWare Workstation

My host machine runs with Ubuntu 12.04 64bit. On the host adb works normal. But in the VM (Ubuntu 12.04 32bit / VMWare Workstation 8.0.4) adb shows either no device or device offline. Starting adb as

stackoverflow.com

ADB 관련 udev 규칙 추가:

root@docker-project:~# vi /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="plugdev"
root@docker-project:~# sudo service udev restart
root@docker-project:~# sudo adb kill-server
root@docker-project:~# sudo adb start-server
root@docker-project:~# adb install /root/app-debug.apk

  • 설치 준비 완료
# 1. 내폰실험
  • 폰에서 권한 승인 전후 
# 2. 학우 폰 실험

3. APK 파일 설치

기기가 연결된 후, APK 파일을 설치 명령어

root@docker-project:~# adb install /root/app-debug.apk
# APK 다운
# 앱 실행

6. Docker Registry에 빌드 환경 저장 (선택)

  • 만든 빌드 환경을 Docker Hub 등에 푸시하여 다른 환경에서도 동일한 빌드를 진행
# Docker Hub에 푸시
docker tag android-builder mydockerhub/android-builder docker push mydockerhub/android-builder

🎯 최종 결과물

 GitHub에서 Kotlin 프로젝트를 wget으로 코드 다운로드
 Docker 컨테이너에서 Kotlin Android 앱 빌드
 docker-compose up 한 줄 명령어로 APK 생성 가능

🚀 최종 요약 (순서 & 효과)

단계 목표 효과
1️⃣ GitHub에서 코드 가져오기 최신 코드 다운로드 항상 최신 상태 유지
2️⃣ Dockerfile 작성 Android 앱 빌드 환경 구축 일관된 환경에서 실행 가능
3️⃣ Docker Compose 설정 docker build & run 자동화 한 줄 실행으로 쉽게 빌드

이 과정을 통해 Docker를 활용한 완전 자동 빌드 & 배포 환경을 구축할 수 있습니다! 🚀


🚀 빌드된 앱을 브라우저에서 볼 수 있을까?

👀 아니, 브라우저에서 직접 확인할 수는 없어!
왜냐하면, 이 과정은 웹 서비스가 아니라 Android APK 파일을 만드는 과정이기 때문이야.

📌 배포라는 개념은 무엇인가?

  • 웹 서비스라면 서버에 올려서 브라우저에서 접속할 수 있도록 함
  • Android 앱이라면 APK를 생성해서 사용자가 설치할 수 있도록 함
    (예: Play Store에 올리거나, 직접 APK를 공유해서 설치)

📌 그렇다면 배포는 어떻게 해야 할까?

빌드된 APK 파일을 사용자에게 제공하려면 다음과 같은 방식이 있어:

1️⃣ GitHub Actions로 자동 업로드 (현재 설정됨)

  • GitHub Actions에서 빌드된 app-debug.apk를 다운로드 가능

2️⃣ Firebase App Distribution 사용 (권장)

  • APK를 Firebase에 올려서 테스터들에게 배포 가능
  • (방법: ./gradlew appDistributionUploadDebug 실행)

3️⃣ Google Play Store에 업로드

  • 릴리즈 APK를 생성해서 Google Play Store에 올리면 배포 가능

🔥 결론

  • docker-compose up --build 하면 APK가 자동 빌드됨
  • 빌드 확인: ls app/build/outputs/apk/debug/
  • 배포는 APK를 직접 공유하거나, Firebase/Play Store에 업로드하는 과정
  • 브라우저에서 직접 확인할 수 있는 게 아니라, APK를 설치해야 실행 가능