[Docker] SeleniumBase + UndetectedChromeDriver 환경 도커이미지 빌드하기

2025. 7. 14. 23:42Docker

 

저번 포스팅에서 cloudflare turnstile을 우회하기 위해 seleniumBase + undetected Chrome Driver 조합을 사용했었습니다.

이번 포스팅에선 해당 환경을 도커 이미지로 구성하고 ec2에서 실행시키는 방법을 알아보겠습니다. 

 

도커파일 작성하기

seleniumBase + undetectedChromeDriver가 동작가능한 환경을 도커파일로 구성합니다.

# 파이썬 이미지
FROM python:3.11-slim

# 시스템 필수 패키지 설치 (wget, gnupg, ca-certificates)
RUN apt-get update && apt-get install -y --no-install-recommends \
    wget \
    gnupg \
    gnupg1 \
    gnupg2 \
    ca-certificates && rm -rf /var/lib/apt/lists/*

# chrome browser 설치
RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list \
    && apt-get update && apt-get install -y --no-install-recommends google-chrome-stable && rm -rf /var/lib/apt/lists/*

# chrome 실행에 필요한 라이브러리 설치
RUN apt-get update && apt-get install -y --no-install-recommends \
    libnss3 \
    libgconf-2-4 \
    libappindicator3-1 \
    fonts-liberation && rm -rf /var/lib/apt/lists/*

# 환경 변수 설정 (seleniumBase가 Chrome을 찾도록)
ENV CHROME_BIN=/usr/bin/google-chrome
ENV PATH=$PATH:/usr/bin/google-chrome

# 타임존 설정 (Asia/Seoul)
RUN apt-get update && apt-get install -y tzdata && \
    ln -fs /usr/share/zoneinfo/Asia/Seoul /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata

# 프로젝트에 필요한 파이썬 패키지 설치
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 코드 복사
COPY . .

# 포트 설정 (Flask)
EXPOSE 5000

# 실행 명령
CMD ["python", "app.py"]

 

python 3.11-slim을 베이스 이미지로 사용합니다. 

기본적으로 용량이 가볍고, 크롬과 필요한 종속성만 추가할 수 있어 최적화에 유리합니다.

FROM python:3.11-slim

 

Chrome 설치를 위한 공식 키 및 저장소 등록에 필요한 도구들을 설치합니다.

RUN apt-get update && apt-get install -y --no-install-recommends \
    wget \
    gnupg \
    gnupg1 \
    gnupg2 \
    ca-certificates && rm -rf /var/lib/apt/lists/*

 

공식 저장소를 통해 안정적인 최신 Chrome 브라우저를 설치합니다.

SeleniumBase에서 undetected-chromedriver 사용 시 크롬 브라우저가 필수입니다.

RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
    && echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list \
    && apt-get update && apt-get install -y --no-install-recommends google-chrome-stable && rm -rf /var/lib/apt/lists/*

 

Headless Chrome이 GUI 없이 실행되도록 필요한 필수 라이브러리들을 설치합니다.

RUN apt-get update && apt-get install -y --no-install-recommends \
    libnss3 \
    libgconf-2-4 \
    libappindicator3-1 \
    fonts-liberation && rm -rf /var/lib/apt/lists/*

 

seleniumBase 등에서 Chrome 실행 경로를 찾기 위해 환경 변수를 설정합니다.

ENV CHROME_BIN=/usr/bin/google-chrome
ENV PATH=$PATH:/usr/bin/google-chrome

 

로그 타임스탬프나 스케줄링 시 정확한 시간을 위해 Asia/Seoul 기준으로 타임존을 고정합니다.

RUN apt-get update && apt-get install -y tzdata && \
    ln -fs /usr/share/zoneinfo/Asia/Seoul /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata

 

프로젝트의 의존 패키지를 설치하고, 소스코드를 컨테이너에 복사합니다.

COPY requirements.txt .
RUN pip install ...
COPY . .

 

현재 도커이미지로 빌드할 코드는 Flask 기반 코드로 작성되어 있습니다. 

따라서 Flask 서버가 내부 포트 5000으로 실행되도록 설정하며, 외부에서 포트 매핑을 통해 접근할 수 있게 합니다.

또한 도커이미지가 실행될 시 실행될 명령어를 정의해줍니다.

저의 경우엔 app.py 파일이 실행되도록 설정해놓았습니다.

EXPOSE 5000
CMD ["python", "app.py"]

 

 

 

이미지 빌드하기

우선 컴퓨터에 도커가 설치되지 않았다면 설치를 해줍니다.

https://docs.docker.com/desktop/setup/install/mac-install/

 

Mac

Install Docker Desktop for Mac to get started. This guide covers system requirements, where to download, and instructions on how to install and update.

docs.docker.com

 

그 다음 터미널을 통해 도커 이미지로 빌드하고 싶은 프로젝트 코드가 있는 위치로 이동합니다.

 

현재 seleniumBase를 이용하기 위해선 크롬브라우저 설치가 필요한데 크롬을 설치하려면 amd64 기반으로 빌드해야합니다.

Apple Silicon (M1/M2/M3) 기반 Mac에서는 기본이 arm64이기 때문에 --platform=linux/amd64 옵션을 붙여서 Chrome이 설치되도록 빌드해줍니다.

docker build --platform linux/amd64 -t <이미지 이름> .

 

 

ECR에 push 하기

우선 AWS ECR에 로그인 해줍니다. (AWS cli가 설치되어있다는 가정하에 진행합니다.)

aws ecr get-login-password --region <리전> | \
docker login --username AWS --password-stdin <AWS 계정_ID>.dkr.ecr.<리전>.amazonaws.com/<ECR 리포지토리이름>

 

AWS ECR 리포지토리를 생성합니다. 

aws ecr create-repository --repository-name <리포지토리 이름>

 

다음과 같은 응답이 왔다면 생성에 성공한 것입니다.

{
    "repository": {
        "repositoryArn": ~~ ,
        "registryId": ~~ ,
        "repositoryName": ~~ ,
        "repositoryUri": ~~ ,
        "createdAt": "2025-07-10T15:23:30.515000+09:00",
        "imageTagMutability": "MUTABLE",
        "imageScanningConfiguration": {
            "scanOnPush": false
        },
        "encryptionConfiguration": {
            "encryptionType": "AES256"
        }
    }
}

 

이제 로컬에서 빌드한 도커 이미지를 AWS ECR에 푸시하려면, 먼저 해당 이미지에 ECR 레지스트리 주소 형식의 태그를 붙여야 합니다.

docker tag <로컬 도커이미지 이름>:latest \
<AWS 계정_ID>.dkr.ecr.<AWS 리전>.amazonaws.com/<ECR 리포지토리이름>:latest

 

이제 ECR에 빌드한 이미지를 push 합니다.

docker push <AWS 계정_ID>.dkr.ecr.<리전>.amazonaws.com/<ECR 리포지토리이름>:latest

 

 

EC2에서 실행하기

우선 생성한 EC2 인스턴스에 접속해 다음과 같이 명령어를 수행합니다.

sudo apt update
sudo apt install -y unzip curl

# AWS CLI v2 설치
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

 

AWS cli가 잘 설치되었는지 이 명령어로 확인합니다.

aws --version

 

그 후 로그인하기 위해서 "aws configure" 명령어를 입력하고 계정정보를 차례대로 입력해줍니다.

aws configure

이후 아래와 같이 입력:

AWS Access Key ID: xxxxxxxxxxxxxxxxx

AWS Secret Access Key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Default region name: ap-northeast-2

Default output format: json

 

이제 ec2인스턴스에서 도커이미지를 실행시켜야하기 때문에 도커를 설치해줍니다.

Ubuntu의 기본 패키지 매니저인 apt를 통해 도커를 설치합니다. -y 옵션을 사용하면 중간에 물어보는 확인 없이 자동으로 설치됩니다.

sudo apt install -y docker.io

 

설치된 도커 데몬을 즉시 실행합니다. 이 과정을 거쳐야 docker run, docker pull 등의 명령어를 사용할 수 있습니다.

sudo systemctl start docker

 

EC2 인스턴스를 재부팅하더라도 Docker 데몬이 자동으로 실행되도록 설정합니다. 서버가 꺼졌다 켜져도 Docker 서비스를 수동으로 실행할 필요가 없도록 해줍니다.

sudo systemctl enable docker

 

기본적으로 도커 명령어는 root 또는 sudo 권한이 필요합니다. 위 명령어는 현재 사용자($USER)를 docker 그룹에 추가하여, 앞으로 sudo 없이도 도커 명령어를 사용할 수 있도록 권한을 부여합니다.

sudo usermod -aG docker $USER

 

해당 명령어를 입력해 오류 없이 실행된다면 Docker가 정상적으로 설치 및 설정된 것입니다.

docker ps

 

이제 ECR에 저장된 이미지를 가져옵니다.

docker pull <AWS 계정_ID>.dkr.ecr.<리전>.amazonaws.com/<ECR 리포지토리이름>:<태그>

 

해당 이미지를 기반으로 도커 컨테이너를 실행합니다.

옵션 설명
-d  컨테이너를 백그라운드에서 실행하는 옵션입니다.
<외부 접속 포트>:<연결시킬 내부 포트> 예를 들어 3000:5000일 경우 EC2 인스턴스의 3000번 포트를 컨테이너 내부의 5000번 포트에 매핑합니다.
즉, 외부에서 EC2:3000으로 접근하면 Flask 앱(5000번 포트)에 연결됩니다.
이렇게 외부 접속 포트를 설정해놓고 이용하려면 ec2 인스턴스 보안 탭에서 인바운드 규칙에 3000번 포트를 열어놓아야 합니다.
docker run -d -p <외부 접속 포트>:<연결시킬 내부 포트> <ECR 리포지토리 URI>/<이미지 이름>:latest

 

 

만들어놓은 헬스체크 api 라던가 테스트 api가 있다면 열어놓은 포트를 통해 도커 컨테이너가 잘 실행되고 있는지 확인할 수 있습니다.

http://<EC2 인스턴스 퍼블릭 IPv4 주소>:<포트>/health-check

 

 

+ 현재는 수동으로 "도커이미지 빌드 -> ecr에 push -> ec2에서 pull -> 실행"을 진행했지만 이 과정을 CI/CD 파이프라인으로 구성한다면 자동화할 수 있습니다. 해당 내용은 추후 포스팅에서 다뤄보겠습니다!