TIL

GitHub Actions + Docker ๋ฐฐํฌ ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…: .env ํŒŒ์ผ์ด ์ปจํ…Œ์ด๋„ˆ์— ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š” ์ด์œ ?

inz1234 2025. 3. 21. 22:48

๐Ÿšจ  TroubleShotting

๋ฌธ์ œ ๋ฐœ์ƒ์˜ ๋ฐฐ๊ฒฝ - As Is

ํ”„๋กœ์ ํŠธ๋ฅผ GitHub Actions์™€ Docker๋ฅผ ํ™œ์šฉํ•ด EC2์— ๋ฐฐํฌํ•˜๋Š” ๊ณผ์ •์—์„œ, .env ํŒŒ์ผ์ด ๋„์ปค ์ปจํ…Œ์ด๋„ˆ์— ์ •์ƒ์ ์œผ๋กœ ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.

๋‹จ์ˆœํžˆ .env ํŒŒ์ผ ํ•˜๋‚˜์˜ ๋ฌธ์ œ์˜€์ง€๋งŒ, ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๊ณผ์ •์—์„œ ๋นŒ๋“œํƒ€์ž„๊ณผ ๋Ÿฐํƒ€์ž„, ๊ทธ๋ฆฌ๊ณ  webpack.config.js์—์„œ์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ฒ˜๋ฆฌ๊นŒ์ง€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ๊ฐœ๋…์„ ์ œ๋Œ€๋กœ ์ดํ•ดํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋‚ด๊ฐ€ ๊ฒช์€ ๋ฌธ์ œ์˜ ์›์ธ๊ณผ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•, ๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ํ†ตํ•ด ์ •๋ฆฌํ•œ ๋ฐฐํฌ ํ๋ฆ„์„ ๊ธฐ๋กํ•ด๋ณธ๋‹ค.


โ—๏ธ ๋ฌธ์ œ

  •  GitHub Actions์—์„œ .env ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๊ณ  EC2์— ๋ณต์‚ฌํ–ˆ์Œ์—๋„
  • ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—๋Š” .env ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์•˜์Œ
[ec2-user@ipxxxx ~]$ docker exec -it app cat /usr/src/app/.env
cat: can't open '/usr/src/app/.env': No such file or directory
  • ๋ฐฐํฌ๋œ ํŽ˜์ด์ง€์—์„œ ๋ฐฑ์—”๋“œ๋กœ ์š”์ฒญ์„ ํ•  ์‹œ, requestUrl ๋‚ด API_URL ์ฃผ์†Œ๊ฐ€ undefined๊ฐ€ ๋˜์–ด ์š”์ฒญ ์‹คํŒจ


2. ์›์ธ ๋ถ„์„

โœ… ์›์ธ 1. GitHub Actions(deploy.yaml)์™€ Dockerfile์˜ ์‹คํ–‰ ํ๋ฆ„์— ๋Œ€ํ•œ ๊ฐœ๋… ๋ถ€์กฑ

  • deploy.yaml์€ GitHub Actions์—์„œ ์‹คํ–‰๋˜๋Š” YAML ์Šคํฌ๋ฆฝํŠธ์ด๊ณ ,
    ๊ทธ ์ค‘ docker build ๋‹จ๊ณ„์—์„œ Dockerfile์ด ์‹คํ–‰๋จ
  • ๋”ฐ๋ผ์„œ .env ํŒŒ์ผ์€ Docker build ์ด์ „์— ๋งŒ๋“ค์–ด์ ธ ์žˆ์–ด์•ผ ๋ณต์‚ฌ ๊ฐ€๋Šฅํ•จ!
  • ์ด์ „ deploy.yaml ํŒŒ์ผ์—์„œ .env ์ƒ์„ฑ ๋ช…๋ น์„ docker build ์ด์ „์— ํ–ˆ์–ด์•ผ ํ•˜๋Š”๋ฐ, ์ดํ›„์— ํ•˜๊ณ  ์žˆ์—ˆ์Œ
  • ๋ณต์‚ฌํ•  .env ํŒŒ์ผ ์ž์ฒด๊ฐ€ ์—†์—ˆ์œผ๋ฏ€๋กœ - undefined ๋ฐ˜ํ™˜

โœ… ์›์ธ 2. .dockerignore ํŒŒ์ผ์— .env๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์—ˆ์Œ

  • .env ํŒŒ์ผ์„ ์ƒ์„ฑํ•ด๋„ Docker ์ด๋ฏธ์ง€์— ๋ณต์‚ฌ๋˜์ง€ ์•Š์Œ
  • ๊ฒฐ๊ณผ์ ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์—์„œ .env ํŒŒ์ผ์ด ๋ณด์ด์ง€ ์•Š์Œ - undefined ๋ฐ˜ํ™˜

2. ํ•ด๊ฒฐ๋ฐฉ์•ˆ

โœ… .dockerignore์—์„œ .env ์ œ์™ธ

# .dockerignore
.env  โŒ

โœ… .env ํŒŒ์ผ์˜ 2๊ฐ€์ง€ ๋ณต์‚ฌ ๋ฐฉ๋ฒ•

๐Ÿ”ง ๋ฐฉ๋ฒ• 1. Dockerfile์—์„œ .env๋ฅผ ์ง์ ‘ ๋ณต์‚ฌ(docker ์ด๋ฏธ์ง€ ๋นŒ๋“œ ์‹œ ๋ณต์‚ฌ)

# 1. Build ๋‹จ๊ณ„
FROM node:22 AS build
...

# # โœ… .env ํŒŒ์ผ ์ถ”๊ฐ€
# COPY .env ./

...
CMD ["nginx", "-g", "daemon off;"]

๐Ÿ”ง ๋ฐฉ๋ฒ• 2. EC2์— ๋ณต์‚ฌ ํ›„ ์ปจํ…Œ์ด๋„ˆ๋กœ ์˜ฎ๊น€

์ด ๋ฐฉ๋ฒ•์€ .env๋ฅผ Docker ์ด๋ฏธ์ง€์— ํฌํ•จํ•˜์ง€ ์•Š์•„ ๋ณด์•ˆ์ƒ์œผ๋กœ๋„ ๋” ์•ˆ์ „ํ•˜์ง€ ์•Š์„๊นŒ..? ์‹ถ์–ด์„œ ์‹คํ–‰ํ•ด๋ณธ ๋ฐฉ๋ฒ• ๐Ÿ”œ ์ด ๋ฐฉ๋ฒ•๋„ ์„ฑ๊ณต!

# deploy.yaml
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
	...
    - name: Prepare .env
        run: |
          # โœ… 1) env ํŒŒ์ผ ์ƒ์„ฑ
          echo "API_URL=${{ secrets.API_URL }}" > .env 
          echo "๐Ÿ“„ .env file contents:"
          cat .env
          ...
 	- name: Copy .env to EC2
        run: |
          # โœ… 2) EC2๋กœ ๋ณต์‚ฌ
          echo "${{ secrets.EC2_KEY }}" > ec2.pem
          chmod 600 ec2.pem
          scp -i ec2.pem -o StrictHostKeyChecking=no .env ${{ secrets.EC2_USERNAME }}@${{ secrets.EC2_HOST }}:/home/${{ secrets.EC2_USERNAME }}/.env
          
          # โœ… 3) ์ปจํ…Œ์ด๋„ˆ ์‹คํ–‰ ํ›„ ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ .env ๋ณต์‚ฌํ•  ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
          docker exec golaping-app mkdir -p /usr/src/app
	
          # โœ… 4) ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์— EC2์˜ .env ํŒŒ์ผ ๋ณต์‚ฌ
        docker cp /home/${{ secrets.EC2_USERNAME }}/.env golaping-app:/usr/src/app/.env   
          ...

๐Ÿ’ก ์ƒˆ๋กญ๊ฒŒ ์•Œ๊ฒŒ๋œ ์ 

๋นŒ๋“œํƒ€์ž„ vs ๋Ÿฐํƒ€์ž„ ๋ณต์Šต

๐Ÿ“ฆ  ๋นŒ๋“œํƒ€์ž„ - Webpack์ด ๋ฒˆ๋“ค๋ง์„ ์ˆ˜ํ–‰ํ•  ๋•Œ, JS ์ฝ”๋“œ๊ฐ€ ๋ฒˆ๋“ค๋ง๋˜๊ณ  ์ตœ์ข… HTML/JS ํŒŒ์ผ์ด ์ƒ์„ฑ๋˜๋Š” ์‹œ์ 
- ex) pnpm build ์‹œ์ 
 โžก๏ธ ์ด๋•Œ .env ๊ฐ’์„ webpack.config.js์—์„œ dotenv๋กœ .env ํŒŒ์ผ์„ ์ฝ๊ณ ,
 DefinePlugin์œผ๋กœ process.env.API_URL ๊ฐ™์€ ๊ฐ’์„ ์‹ค์ œ JS ์ฝ”๋“œ ๋‚ด ๋ฌธ์ž์—ด๋กœ ์น˜ํ™˜
โš™๏ธ  ๋Ÿฐํƒ€์ž„ - ์›น ๋ธŒ๋ผ์šฐ์ €๋‚˜ Node.js์—์„œ ์‹ค์ œ JS ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ์‹œ์ 
- ์•ฑ ๋‚ด JS ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘ .env ๊ฐ’์„ ์ฐธ์กฐํ•  ๋•Œ
 โžก๏ธ .env ํŒŒ์ผ์ด ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์— ์กด์žฌํ•ด์•ผ, ์‹คํ–‰ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋„๋ก ์ค€๋น„๋จ

๋ฐฐํฌ ์ „์ฒด ํ๋ฆ„์ •๋ฆฌ

[GitHub Actions - deploy.yaml]
 1. .env ์ƒ์„ฑ
 2. pnpm build (for ๋นŒ๋“œ: webpack.config.js ์‹คํ–‰ - .env ์ฐธ์กฐ)
 3. docker build (for ๋Ÿฐํƒ€์ž„: COPY .env ./)
 4. docker push

[EC2]
 5. docker pull
 6. docker run (์‹คํ–‰ ์‹œ -e API_URL=... ๋กœ ์ „๋‹ฌ ๊ฐ€๋Šฅ)

๐Ÿšฉ๋งˆ๋ฌด๋ฆฌ

์ด๋ฒˆ ๋ฌธ์ œ๋Š” ๋‹จ์ˆœํžˆ .env๊ฐ€ ์ปจํ…Œ์ด๋„ˆ์— ๋ณต์‚ฌ๋˜์ง€ ์•Š๋Š” ๋ฌธ์ œ์˜€์ง€๋งŒ,

๊ทธ ๊ณผ์ •์—์„œ ๋นŒ๋“œํƒ€์ž„ vs ๋Ÿฐํƒ€์ž„์˜ ์ฐจ์ด,
GitHub Actions(deploy.yaml)์™€ Dockerfile์˜ ์‹คํ–‰ ์ˆœ์„œ,
webpack์—์„œ์˜ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์ฃผ์ž… ๋ฐฉ์‹ ๋“ฑ ์ค‘์š”ํ•œ ๊ฐœ๋…๋“ค์„ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

์ด์ œ๋Š” ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ „๋‹ฌํ• ์ง€ ์„ ํƒํ•  ์ˆ˜ ์žˆ๊ณ , ๊ฐ ๋ฐฉ๋ฒ•์ด ์–ด๋–ค ์‹œ์ ์—์„œ ์ž‘๋™ํ•˜๋Š”์ง€๋„ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.