๐Ÿณ Docker + ECR + Lambda๋กœ ํฌ๋กค๋ง ๋„์ „!

์˜ค๋™ํ›ˆยท2025๋…„ 5์›” 2์ผ
1

AWS Cloud

๋ชฉ๋ก ๋ณด๊ธฐ
9/9
post-thumbnail

1. ๋™๊ธฐ

ํฌ๋กค๋ง์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•˜์ง€๋งŒ, ๊ทธ ์ค‘์—์„œ๋„ Docker + ECR + Lambda ์กฐํ•ฉ์„ ์„ ํƒํ•œ ๋ฐ์—๋Š” ๋ช…ํ™•ํ•œ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜๋ฃจ์— ํ•œ ๋ฒˆ๋งŒ ๋™์ž‘์‹œํ‚ฌ ์˜ˆ์ •์ด์—ˆ๊ณ , ๋™์ž‘ ์‹œ๊ฐ„์€ 1์‹œ๊ฐ„ ๋‚ด์™ธ๋กœ ๋งˆ๋ฌด๋ฆฌ ๋  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…์ž…๋‹ˆ๋‹ค.

  • EC2 - ์ƒ์‹œ ์„œ๋ฒ„ ์šด์˜์ด ๊ฐ€๋Šฅํ•˜๋‚˜ ๋น„์šฉ ๋ถ€๋‹ด์ด ํผ
  • Lambda + EventBridge - ์ •ํ•ด์ง„ ์‹œ๊ฐ„์—๋งŒ ๋ฆฌ์†Œ์Šค ์‚ฌ์šฉ โ†’ ๋น„์šฉ ํšจ์œจ์ ์ด๊ณ  ๊ด€๋ฆฌ ๊ฐ„ํŽธ

๐Ÿ‘‰ Lambda + EventBridge ์กฐํ•ฉ์ด ์ตœ์†Œํ•œ์˜ ๋น„์šฉ์œผ๋กœ ์•ˆ์ •์ ์ธ ํฌ๋กค๋ง ์ž‘์—… ์ˆ˜ํ–‰ ๊ฐ€๋Šฅ!

โœ… Docker + ECR์„ ์„ ํƒํ•œ ์ด์œ 
Lambda์—์„œ ์‚ฌ์šฉํ•˜๋Š” Layer๋Š” ์••์ถ• ๊ธฐ์ค€ 50MB, ์••์ถ• ํ•ด์ œ ์‹œ 250MB์˜ ์šฉ๋Ÿ‰ ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์ €ํฌ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” Chrome ๋“œ๋ผ์ด๋ฒ„๋Š” 1GB ์ด์ƒ์˜ ์šฉ๋Ÿ‰์ด ํ•„์š”ํ•˜์—ฌ Lambda Layer๋กœ๋Š” ํƒ‘์žฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด, Docker Image๋Š” ์ตœ๋Œ€ 10GB๊นŒ์ง€ ํ—ˆ์šฉ๋˜์–ด Lambda์—์„œ๋„ ๋Œ€์šฉ๋Ÿ‰ ํฌ๋กค๋ง ํ™˜๊ฒฝ ๊ตฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜์—ฌ ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์„ ํƒํ–ˆ์Šต๋‹ˆ๋‹ค.

2. ๊ตฌ์„ฑ ์š”์†Œ ๋ฐ Github ๋งํฌ

๐Ÿ“ ์ฝ”๋“œ ์ „์ฒด๋Š” ์•„๋ž˜ Github ์ €์žฅ์†Œ ์ฐธ๊ณ 
๐Ÿ”— lambda-selenium-docker ๊ตฌ์„ฑ ํŒŒ์ผ ๋ณด๊ธฐ

2-1. Dockerfile ๊ตฌ์„ฑ ์š”์•ฝ

โœ… ๊ณตํ†ต ๊ตฌ์„ฑ

  • chrome, chromedriver โ†’ /opt/ ๊ฒฝ๋กœ์— ์„ค์น˜
  • ์‹คํ–‰ํ•  ํŒŒ์ผ๋“ค โ†’ /var/task/์— ์œ„์น˜ํ•ด์•ผ Lambda์—์„œ ์ธ์‹ ๊ฐ€๋Šฅ

Python Version ๋ณ„ Lambda Image ์œ ์˜์‚ฌํ•ญ

Python ๋ฒ„์ „์šด์˜์ฒด์ œํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์žํŠน์ง•
3.9 ~ 3.11Amazon Linux 2yum๊ธฐ์กด ์„ค์น˜ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌ
3.12 ~ 3.13Amazon Linux 2023dnfyum ๋ฏธ์ง€์› โ†’ dnf ์‚ฌ์šฉ ํ•„์ˆ˜, ํŒจํ‚ค์ง€ ์ƒ์ด

ํŒŒ์ผ ์„ค๋ช…

  • chrome-deps.txt: chrome ์„ค์น˜์šฉ ํŒจํ‚ค์ง€ ๋ฆฌ์ŠคํŠธ
  • install-browser.sh: ํฌ๋กฌ ๋ฐ ๋“œ๋ผ์ด๋ฒ„ ์„ค์น˜ ์Šคํฌ๋ฆฝํŠธ
  • requirements.txt: pip ํŒจํ‚ค์ง€ ๋ชฉ๋ก
  • crawler.py: Selenium ์‹คํ–‰ ์ฝ”๋“œ

3. Docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ

์šฐ์„  2๋ฒˆ์— ๋‚˜์™€์žˆ๋Š” Github์— ์žˆ๋Š” ํŒŒ์ผ์„ ๋ฐ›์•„, crawler.py ํŒŒ์ผ์„ ๊ธฐํ˜ธ์— ๋งž๊ฒŒ ์ˆ˜์ •ํ•˜์‹œ๊ณ  ์ง„ํ–‰ํ•ด ์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

Lambda์šฉ ์•„ํ‚คํ…์ฒ˜ ์„ค์ •

Docker ๋นŒ๋“œ ์‹œ linux/x86_64 ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์–ด์•ผ ๋žŒ๋‹ค ๋‚ด์—์„œ ํฌ๋กฌ์ด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
์ €๋Š” crawler๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ƒ์„ฑ๋˜๋„๋ก ๋นŒ๋“œ๋ฅผ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

$ docker build --platform linux/x86_64 -t crawler -f Dockerfile .

๊ธฐ๋Šฅ ์—…๋ฐ์ดํŠธ ์ดํ›„ ์บ์‹œ ์ดˆ๊ธฐํ™” ํ•„์š” ์‹œ(์ฐธ๊ณ )

๋งŒ์•ฝ ๊ธฐ๋Šฅ ์—…๋ฐ์ดํŠธ๋ฅผ ํ–ˆ์Œ์—๋„ Docker Image๊ฐ€ ๋™์ผํ•˜๊ฒŒ ๋นŒ๋“œ๋œ๋‹ค๋ฉด --no-cache ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด ์žฌ์‹œ๋„ ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

$ docker build --no-cache --platform linux/x86_64 -t crawler -f Dockerfile .

4. AWS ECR ์—…๋กœ๋“œ

1. IAM ๊ณ„์ • ์ƒ์„ฑ ๋ฐ aws configure

AWS ํ™ˆํŽ˜์ด์ง€์—์„œ IAM ๊ณ„์ •์„ ์ƒ์„ฑํ•ด ์ฃผ๋ฉด, access_key, secret_key ์ •๋ณด๋ฅผ ๋ฐœ๊ธ‰๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ์ƒ์„ฑํ•œ IAM ๊ณ„์ • ์ •๋ณด๋ฅผ ๋กœ์ปฌ์—์„œ๋„ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก aws configure ๋ช…๋ น์–ด๋กœ ์„ธํŒ…ํ•ด ์ค๋‹ˆ๋‹ค.

# Access Key, Secret Key, ๋ฆฌ์ „ ๋“ฑ ์ž…๋ ฅ

$ aws configure
AWS Access Key ID [None]:
AWS Secret Access Key [None]: 
Default region name [None]:
Default output format [None]:

์ด์ œ ์œ„์— ์ž…๋ ฅํ•œ IAM ๊ณ„์ •์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‚ด ์ •๋ณด๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋ถˆ๋Ÿฌ์™€์ง€๋Š”์ง€ ์ฒดํฌํ•ด ์ค๋‹ˆ๋‹ค.

$ export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
$ echo "export ACCOUNT_ID=${ACCOUNT_ID}" | tee -a ~/.bash_profile

e.g) export ACCOUNT_ID=905418424719

ACCOUNT_ID๊ฐ€ ๋‚˜์˜จ๋‹ค๋ฉด ์ •์ƒ์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด ~/.bash_profile์— ์ €์žฅ๋˜์–ด ํ„ฐ๋ฏธ๋„์„ ์ƒˆ๋กœ ์—ฐ ๊ฒฝ์šฐ์—๋„ ACCOUNT_ID๊ฐ€ ์ž๋™์œผ๋กœ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค.

2. AWS ECR Private Repositories ์ƒ์„ฑ

AWS ECR ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ด๋ฆ„, URI, ์ƒ์„ฑ ๋‚ ์งœ๋“ฑ์˜ ์ •๋ณด๋“ค์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, ECR Push ๋˜๋Š” Lambda์— ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” URI ์ •๋ณด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋ฆ„ ์˜ˆ์‹œ - lambda-crawler-docker
  • URI ํ˜•์‹ - $ACCOUNT_ID.dkr.ecr."๋ฆฌ์ „๋ช…".amazonaws.com/"๋ฆฌํฌ์ง€ํ† ๋ฆฌ ์ด๋ฆ„"

3. Docker image repository ๋ณ€๊ฒฝ

Docker Image ์ด๋ฆ„ ํ™•์ธ

3๋ฒˆ ํ•ญ๋ชฉ์—์„œ ์„ค์ •ํ•œ Docker Image ์ด๋ฆ„์„ ํ™•์ธํ•ด ์ค๋‹ˆ๋‹ค.
์ œ๊ฐ€ ์„ค์ •ํ•œ Docker image ์ด๋ฆ„์€ crawler ์ž…๋‹ˆ๋‹ค.

$ docker images

REPOSITORY       TAG    IMAGE ID     CREATED    SIZE
crawler        latest 179972fa2472 5 hours ago 1.75GB

Docker Image์— ECR URI Tag ์ถ”๊ฐ€

crawler๋ผ๋Š” ๋กœ์ปฌ Docker Image๋ฅผ 905418424719.dkr.ecr.ap-northeast-2.amazonaws.com/lambda-crawler-docker๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์žฌํƒœ๊น… ํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด ์ด์ œ ์ด ์ด๋ฏธ์ง€๋Š” AWS ECR์— ํ‘ธ์‹œํ•  ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

$ docker tag crawler 905418424719.dkr.ecr.ap-northeast-2.amazonaws.com/lambda-crawler-docker

Docker Image ์ด๋ฆ„ ์žฌํ™•์ธ

๊ทธ๋Ÿฌ๋ฉด ๋™์ผํ•œ IMAGE ID๋ฅผ ๊ฐ€์ง„ ์ด๋ฏธ์ง€๊ฐ€ ๋‘ ๊ฐœ์˜ REPOSITORY ์ด๋ฆ„์œผ๋กœ ๋ณด์—ฌ์ง‘๋‹ˆ๋‹ค.

$ docker images

REPOSITORY                                                               TAG     IMAGE ID     CREATED    SIZE
crawler                                                                 latest 179972fa2472 5 hours ago 1.75GB
905418424719.dkr.ecr.ap-northeast-2.amazonaws.com/lambda-crawler-docker latest 179972fa2472 5 hours ago 1.75GB

4. ECR Image Push

ECR Docker Login

Docker Client๋ฅผ ์ธ์ฆํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋„๋ก ๋กœ๊ทธ์ธํ•˜๋Š” ๋‹จ๊ณ„์ž…๋‹ˆ๋‹ค.

$ aws ecr get-login-password --region "ap-northeast-2" | docker login --username AWS --password-stdin 905418424719.dkr.ecr.ap-northeast-2.amazonaws.com/lambda-crawler-docker

Image Push ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ

์œ„ ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ์•„๋ž˜์™€ ๊ฐ™์ด ๊ถŒํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ๋ฐœ์ƒํ•œ ์ด์œ ๋Š” IAM ๊ณ„์ •์— ์•„๋ฌด๋Ÿฐ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ecr:GetAuthorizationToken ๊ถŒํ•œ์€ docker login ํ•  ๋•Œ ECR์—์„œ ์ธ์ฆ ํ† ํฐ์„ ๋ฐœ๊ธ‰๋ฐ›๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ถŒํ•œ์ž…๋‹ˆ๋‹ค.
์ฆ‰, ECR ๋กœ๊ทธ์ธ ์ž์ฒด๋ฅผ ํ•  ์ˆ˜ ์—†๋Š” ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::905418424719:user/ecr_iam is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken action
Error: Cannot perform an interactive login from a non TTY device

์˜ค๋ฅ˜ ํ•ด๊ฒฐ์„ ์œ„ํ•ด IAM ๊ณ„์ • ๊ถŒํ•œ ์ถ”๊ฐ€

์ด์ „์— ์ƒ์„ฑํ•œ IAM ๊ณ„์ •์— ์ ‘์†ํ•˜์—ฌ ์•„๋ž˜ ๊ถŒํ•œ์„ ์ถ”๊ฐ€ํ•ด ์ค๋‹ˆ๋‹ค.
Login, Image Push, Pull, Repository ๋ณด๊ธฐ ๋“ฑ์„ ํ•˜๊ธฐ ์œ„ํ•œ ๊ถŒํ•œ์ž…๋‹ˆ๋‹ค.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
              "ecr:GetAuthorizationToken",
              "ecr:BatchCheckLayerAvailability",
              "ecr:GetDownloadUrlForLayer",
              "ecr:GetRepositoryPolicy",
              "ecr:DescribeRepositories",
              "ecr:ListImages",
              "ecr:BatchGetImage",
              "ecr:PutImage",
              "ecr:InitiateLayerUpload",
              "ecr:UploadLayerPart",
              "ecr:CompleteLayerUpload"
            ],
            "Resource": "*"
        }
    ]
}

ECR Docker Login

๊ถŒํ•œ ๋ถ€์—ฌ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ์ด์ œ๋Š” ์•„๋ž˜ ๋ช…๋ น์–ด ์ž…๋ ฅ ์‹œ ์„ฑ๊ณต์ ์œผ๋กœ ๋กœ๊ทธ์ธ์ด ๋˜์‹ค๊ฒ๋‹ˆ๋‹ค.

$ aws ecr get-login-password --region "ap-northeast-2" | docker login --username AWS --password-stdin 905418424719.dkr.ecr.ap-northeast-2.amazonaws.com/lambda-crawler-docker

Login Succeeded

Docker Image Push

๋˜ํ•œ ๊ถŒํ•œ ๋ถ€์—ฌ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด Push ๋ช…๋ น๋„ ์„ฑ๊ณต์ ์œผ๋กœ ๋˜์‹ค๊ฒ๋‹ˆ๋‹ค.

# ๊ฐ์ž ECR URI๋กœ ๋ณ€๊ฒฝํ•ด ์ฃผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค.

$ docker push 905418424719.dkr.ecr.ap-northeast-2.amazonaws.com/lambda-crawler-docker
Using default tag: latest
The push refers to repository [905418424719.dkr.ecr.ap-northeast-2.amazonaws.com/lambda-crawler-docker]
5f70bf18a086: Pushed 
ebacb58d496a: Pushed 
f310bac807bc: Pushed 
7616ce0b8029: Pushed 
1b16eae0ab65: Pushed 
b5a6332d1ae3: Pushed 
aff961962f64: Pushed 
feeb3f35672c: Pushed 
22b878155803: Pushed 
b07d597978b2: Pushed 
13a69907ade8: Pushed 
6a9b57324378: Pushed 
bdd4095bce79: Pushed 
608834524d4b: Pushed 
f4b46dc2d7e0: Pushed 
latest: digest: sha256:a7cbc7cf9844e0347236962623ce83f95dcddf350a90932ac8db3e173cfdba5b size: 3469

4. Lambda ํ•จ์ˆ˜ ์ƒ์„ฑ

Lambda ํ•จ์ˆ˜ ์ƒ์„ฑ

4๋ฒˆ ํ•ญ๋ชฉ์—์„œ ์—…๋กœ๋“œํ•œ ECR URI ๋ฅผ ๊ฐ€์ง€๊ณ  Lambda ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ด ์ค๋‹ˆ๋‹ค.

Lambda ๊ตฌ์„ฑ ๋ณ€๊ฒฝ

Lambda ํ•จ์ˆ˜๋Š” ์ตœ๋Œ€ 15๋ถ„ ๋™์ž‘ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
๋‹ค๋งŒ, ์ฒ˜์Œ ์ƒ์„ฑ ์‹œ ์ดˆ๊ธฐ ์„ธํŒ…์€ 3์ดˆ๋กœ ๋˜์–ด ์žˆ๊ณ  ๋ฉ”๋ชจ๋ฆฌ์™€ ์ž„์‹œ ์Šคํ† ๋ฆฌ์ง€ ํ• ๋‹น๋Ÿ‰๋„ ๋‚ฎ์•„ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ์ œํ•œ์‹œ๊ฐ„ 14๋ถ„ 59์ดˆ, ๋ฉ”๋ชจ๋ฆฌ 2048MB, ์ž„์‹œ ์Šคํ† ๋ฆฌ์ง€ 5120MB๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.

Lambda ํ•จ์ˆ˜ ํ…Œ์ŠคํŠธ

ํ…Œ์ŠคํŠธ ํƒญ์—์„œ ํ…Œ์ŠคํŠธ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์ง„ํ–‰ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ €๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
Chrome ์‹คํ–‰ ๊ณผ์ • ์ค‘์— crashed๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๋‚ด์šฉ์ด์—ˆ๊ณ  ์ถ”์ •๋˜๋Š” ์›์ธ์„ ํ•˜๋‚˜์”ฉ ํŒŒ์•…ํ•ด ๊ฐ€๋ฉฐ ํ…Œ์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณตํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ค๋ฅ˜ ๋‚ด์šฉ

{
  "errorMessage": "Message: unknown error: Chrome failed to start: crashed.\n  (chrome not reachable)\n  (The process started from chrome location /opt/chrome/chrome is no longer running, so ChromeDriver is assuming that Chrome has crashed.)\nStacktrace:\n#0 0x55a053875759 <unknown>\n#1 0x55a05380ecf3 <unknown>\n#2 0x55a0535eddc3 <unknown>\n#3 0x55a0536125ed <unknown>\n#4 0x55a05360db03 <unknown>\n#5 0x55a053647779 <unknown>\n#6 0x55a053641ef3 <unknown>\n#7 0x55a05361827b <unknown>\n#8 0x55a053619455 <unknown>\n#9 0x55a05383d870 <unknown>\n#10 0x55a05384f8b0 <unknown>\n#11 0x55a05384f5bc <unknown>\n#12 0x55a05384fe32 <unknown>\n#13 0x55a05383eb9b <unknown>\n#14 0x55a0538500b6 <unknown>\n#15 0x55a0538304dd <unknown>\n#16 0x55a053867888 <unknown>\n#17 0x55a053867a12 <unknown>\n#18 0x55a053881c2e <unknown>\n#19 0x7f353e0ae44b <unknown>\n#20 0x7f353cbc152f <unknown>\n",
  "errorType": "WebDriverException",
  "requestId": "599f599b-7765-4bf5-9f79-efa5c5436a5e",
  "stackTrace": [
    "  File \"/var/task/crawler.py\", line 9, in handler\n    suc_cnt, err_cnt = crawler_target()\n",
    "  File \"/var/task/crawler.py\", line 33, in crawler_target\n    driver = webdriver.Chrome(service=service, options=chrome_options)\n",
    "  File \"/var/lang/lib/python3.9/site-packages/selenium/webdriver/chrome/webdriver.py\", line 45, in __init__\n    super().__init__(\n",
    "  File \"/var/lang/lib/python3.9/site-packages/selenium/webdriver/chromium/webdriver.py\", line 66, in __init__\n    super().__init__(command_executor=executor, options=options)\n",
    "  File \"/var/lang/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py\", line 212, in __init__\n    self.start_session(capabilities)\n",
    "  File \"/var/lang/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py\", line 299, in start_session\n    response = self.execute(Command.NEW_SESSION, caps)[\"value\"]\n",
    "  File \"/var/lang/lib/python3.9/site-packages/selenium/webdriver/remote/webdriver.py\", line 354, in execute\n    self.error_handler.check_response(response)\n",
    "  File \"/var/lang/lib/python3.9/site-packages/selenium/webdriver/remote/errorhandler.py\", line 229, in check_response\n    raise exception_class(message, screen, stacktrace)\n"
  ]
}

์˜ค๋ฅ˜ ์ˆ˜์ •ํ•œ ๋‚ด์šฉ

1. chrome_options binary ํŒŒ์ผ ์œ„์น˜ ๋ˆ„๋ฝ

ํฌ๋กค๋งํ•˜๋Š” ํŒŒ์ด์ฌ ํŒŒ์ผ ๋‚ด ์˜ต์…˜์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ ์œ„์น˜๋ฅผ ๋ˆ„๋ฝํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ž˜์„œ ์ฐพ์„ ์ˆ˜ ์—†์—ˆ๊ณ  ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

chrome_options.binary_location = "/opt/chrome/chrome"

2. headless ๋“ฑ ์˜ต์…˜ ๋ˆ„๋ฝ

1๋ฒˆ ๋‚ด์šฉ์„ ์ˆ˜์ •ํ•œ ํ›„, ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ์ง€๋งŒ ๋˜ ๋‹ค์‹œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.
headless ๋ฅผ ๋น„๋กฏํ•œ no-sandbox, disable-dev-shm-usage ์˜ต์…˜์„ ๋ˆ„๋ฝํ–ˆ์Šต๋‹ˆ๋‹ค..ใ…Žใ…Ž

๋งฅ์—์„œ ํ…Œ์ŠคํŠธํ•  ๋•Œ๋Š” ํ™”๋ฉด์„ ๋ณด๋ฉฐ ํ…Œ์ŠคํŠธํ•ด์„œ ์•„๋ž˜ ์˜ต์…˜๋“ค์„ ์ œ๊ฑฐํ•˜์˜€๋Š”๋ฐ,
Lambda์—์„œ๋Š” GUI๊ฐ€ ์—†๋Š” ์„œ๋ฒ„ ํ™˜๊ฒฝ์ด์–ด์„œ ํ•ด๋‹น ์˜ต์…˜์ด ์—†์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

chrome_options.add_argument('--headless')
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")

์˜ต์…˜ ์„ค๋ช…

  • --headless - ๋ธŒ๋ผ์šฐ์ € UI ์—†์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ Chrome์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • --no-sandbox - Chrome์˜ ๋ณด์•ˆ ์ƒŒ๋“œ๋ฐ•์Šค๋ฅผ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.
  • --disable-dev-shm-usage - /dev/shm (๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ)๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋Œ€์‹  ๋””์Šคํฌ ๊ธฐ๋ฐ˜์˜ ์ž„์‹œ ์ €์žฅ์†Œ(/tmp)๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

Lambda ํ•จ์ˆ˜ ์žฌํ…Œ์ŠคํŠธ

๋ฐ์ดํ„ฐ๊ฐ€ ์ ์€ ํŽ˜์ด์ง€ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜์˜€๋Š”๋ฐ, ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‚˜์ด๋œŒ~


์ฐธ๊ณ ์ž๋ฃŒ ๐Ÿ“ฉ

profile
์‚ฝ์งˆ์˜ ๊ธฐ๋ก๋“ค๐Ÿฅ

0๊ฐœ์˜ ๋Œ“๊ธ€