저는 보안 전문가가 아닙니다.
하지만 개발자라면 보안을 고려하지 않을 수 없겠죠.
제가 사용했던 기존의 방법입니다.
application.yaml파일을 github repository secret으로 두었기 때문에 언뜻 보면 안전해 보입니다.
하지만 잘 보시면 application.yaml을 만든 후 도커 푸시를 진행하죠..
private docker를 사용하지 않는다면, repo 와 image 이름을 아는 누구나 제 image를 pull하고 열어볼 수 있습니다.
그렇기 때문에 저는 완전히 public한 장소에 저의 모든 환경변수를 넣은 것이죠.
저희가 수정할 방법입니다.
ec2에 .env 파일을 만들고, docker-compose up 시에 env를 설정하여 받으면 됩니다.
그림을 보시면 image에는 환경변수가 들어가질 않았죠.
.env를 docker-compose up 시에 넣어준 뒤에 사용할 수 있습니다.
자 그럼 어떻게 할 수 있을까요?
1. application.yaml
spring:
servlet:
multipart:
max-request-size: 30MB
max-file-size: 30MB
jpa:
show-sql: true
generate-ddl: true
hibernate:
ddl-auto: update
default_batch_fetch_size: 100
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
hikari:
maximum-pool-size: 10
properties:
hibernate:
format-sql: true
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
mvc:
pathmatch:
matching-strategy: ant-path-matcher
main:
allow-bean-definition-overriding: true
redis:
host: ${REDIS_HOST}
port: 6379
레포지토리에 public하게 push되는 application.yaml입니다.
중요한 환경변수들은 ${}의 포맷으로 가려져있죠.
2. .env
DB_URL=imnotgonnaleakthis
DB_USERNAME=mydbusernameisprivate
DB_PASSWORD=thisismyprivatedbpassword
.env에는 실제로 사용하는 중요한 환경변수들을 key-value쌍으로 저장해둡니다.
위의 application.yaml에서 변수를 불러오는 소스입니다.
(이 파일은 당연히 노출시키지 않습니다. gitignore 처리 하세요)
그리고 .env 파일은 깃헙 레포지토리 시크릿에 ENV_VARS로 등록해줍니다.
3. docker-compose.yaml
version: '3'
services:
web:
container_name: web
image: repick/repick-web
env_file: # 이부분 추가 바랍니다
- .env # 이부분 추가 바랍니다
expose:
- 8080
ports:
- 8080:8080
tty: true
environment:
- TZ=Asia/Seoul
logging:
driver: awslogs
options:
awslogs-group: "repickLogGroup"
awslogs-region: "ap-northeast-2"
awslogs-stream: "repickLogStream"
nginx:
container_name: nginx
image: repick/repick-nginx
ports:
- 80:80
depends_on:
- web
docker-compose.yaml에서 env_file : -.env 부분을 추가해줍니다!
그래야 환경변수를 인식하고 넣어준답니다.
4. gradle.yml ( 여러분의 워크플로우 )
name: Deploy Development Server
## develop 브랜치에 push가 되면 실행됩니다
on:
push:
branches: [ "develop" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
## 여러분이 사용하는 버전을 사용하세요
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
distribution: 'temurin'
## gradle build
- name: Build with Gradle
run: ./gradlew bootJar
## 웹 이미지 빌드 및 도커허브에 push
- name: web docker build and push
run: |
docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
docker build -t my-repo/my-web-image .
docker push my-repo/my-web-image
docker build -f dockerfile-nginx -t my-repo/my-nginx-image .
docker push my-repo/my-nginx-image
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ubuntu
key: ${{ secrets.KEY }}
script: |
## 여러분이 원하는 경로로 이동합니다.
cd /home/ubuntu/
## .env 파일을 생성합니다.
sudo touch .env
echo "${{ secrets.ENV_VARS }}" | sudo tee .env > /dev/null
## docker-compose.yaml 파일을 생성합니다.
sudo touch docker-compose.yaml
echo "${{ vars.DOCKER_COMPOSE }}" | sudo tee docker-compose.yaml > /dev/null
## docker-compose를 실행합니다.
sudo chmod 666 /var/run/docker.sock
sudo docker rm -f $(docker ps -qa)
sudo docker pull my-repo/my-web-image
sudo docker pull my-repo/my-nginx-image
docker-compose -f docker-compose.yaml --env-file ./.env up -d
docker image prune -f
이렇게 워크플로우를 작성하였는데요, 보다시피 ENV_VARS를 읽어서 .env에 저장해줍니다.
그런 후 docker-compose -f docker-compose.yaml --env-file ./.env up -d 로 env파일을 읽어서 실행시키도록 합니다.
(현재 디렉토리의 .env파일을 default로 읽는다고 합니다. 하지만 명시적으로 적어주었습니다)
자 이렇게 해서 docker image에 환경변수를 노출시키지 않았습니다!
여러분들도 안전한 코딩 되시기 바랍니다.
'Server' 카테고리의 다른 글
Github Actions: ssh-aciton IPv6 지원 (1) | 2024.03.17 |
---|---|
[Terraform] state locking을 위한 s3, ddb 설정하기 (0) | 2024.02.23 |
[서버] Github Actions: 다양한 명령 내리기 (0) | 2023.11.29 |
[Slack API] 슬랙 API를 통한 요청 가이드 - 외부 요청 차단 (2) (0) | 2023.08.17 |
[Slack API] 슬랙 API를 통한 요청 가이드 (1) (0) | 2023.08.16 |