<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Docker Compose on 얼쑤 · Team Edo</title><link>https://team-edo.github.io/tags/docker-compose/</link><description>Recent content in Docker Compose on 얼쑤 · Team Edo</description><generator>Hugo</generator><language>ko-kr</language><lastBuildDate>Mon, 09 Nov 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://team-edo.github.io/tags/docker-compose/index.xml" rel="self" type="application/rss+xml"/><item><title>백엔드 무중단 배포</title><link>https://team-edo.github.io/posts/2026/11/docker-compose-blue-green-drain/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0000</pubDate><guid>https://team-edo.github.io/posts/2026/11/docker-compose-blue-green-drain/</guid><description>&lt;p>백엔드 컨테이너 하나를 새 버전으로 교체하면, 이전 컨테이너가 내려간 시점과 새 컨테이너가 요청을 받을 수 있는 시점 사이에 공백이 생긴다. 이 공백을 없애려면 순서를 바꿔야 한다. &lt;strong>이전 버전이 요청을 받는 동안 새 버전을 준비하고, 연결을 넘긴 뒤에도 이미 받은 요청과 작업을 마칠 때까지 이전 버전을 살려 둔다.&lt;/strong> 얼쑤는 기존 Docker Compose와 Nginx에 이 순서를 적용했다.&lt;/p>
&lt;h2 id="같은-호스트에-백엔드-슬롯-두-개를-뒀다">같은 호스트에 백엔드 슬롯 두 개를 뒀다&lt;/h2>
&lt;p>슬롯은 백엔드 한 인스턴스를 실행하는 자리다. Compose에 블루와 그린을 정의하고, 두 슬롯이 같은 런타임 설정을 쓰도록 했다. 배포할 때 비활성 슬롯에 새 버전의 JAR을 붙인다. 두 슬롯은 같은 MySQL을 사용한다. 사용자는 평소와 같은 HTTPS 주소로 접속하고, Nginx가 활성 슬롯으로 요청을 보낸다.&lt;/p></description></item><item><title>서버 두 대로 어디까지 장애를 견딜 수 있을까</title><link>https://team-edo.github.io/posts/2026/11/two-host-availability/</link><pubDate>Mon, 09 Nov 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/11/two-host-availability/</guid><description>&lt;p>운영 서버 한 대가 꺼졌다고 가정해 보겠습니다. 두 번째 서버에서 앱이 떠 있어도 사용자가 쓰던 주소가 그 서버로 향하고, 앱이 기존 데이터를 읽고 새 데이터를 저장할 수 있어야 서비스가 돌아옵니다. 얼쑤에서는 서버 두 대를 유지하고 추가 유료 인프라를 전제하지 않는 조건으로 Docker Compose를 확장하는 안과 가벼운 Kubernetes 배포판인 K3s를 쓰는 안을 비교했습니다. 비교 기준은 각 도구가 앱 실행, 접속, 쓰기 복구 중 어디까지 맡을 수 있는가였습니다.&lt;/p></description></item><item><title>Play 배포판의 App Links가 빠진 이유</title><link>https://team-edo.github.io/posts/2026/11/android-app-links-signing/</link><pubDate>Tue, 03 Nov 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/11/android-app-links-signing/</guid><description>&lt;p>얼쑤에서 Android 소셜 로그인은 외부 브라우저를 열고, 인증 뒤 App Links로 앱에 돌아오는 흐름을 사용했습니다. Play에서 설치한 일반 앱이 브라우저에서 돌아오지 못해 운영 서버의 &lt;code>assetlinks.json&lt;/code>을 읽었습니다. 서버는 기동 상태가 정상이었고, 연결 문서에는 QA 패키지 한 항목만 있었습니다. 우선 Play 설치판에 해당하는 연결 항목을 복구했습니다.&lt;/p>
&lt;h2 id="설치한-앱에-찍힌-서명이-필요했다">Play 앱 서명 지문 확인&lt;/h2>
&lt;p>App Links의 연결 문서에는 패키지 이름과 서명 인증서 지문이 함께 들어갑니다. 직접 빌드해 설치한 앱과 Play가 배포한 앱의 서명이 다르면, 한 쪽을 확인한 지문으로 다른 쪽까지 연결됐다고 볼 수 없습니다. Play에서 받은 설치본에 해당하는 지문은 Play Console의 앱 서명 정보에 나옵니다.&lt;/p></description></item><item><title>Docker 내부망으로 연결한 분석 서버</title><link>https://team-edo.github.io/posts/2026/10/analysis-service-network-boundary/</link><pubDate>Thu, 29 Oct 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/10/analysis-service-network-boundary/</guid><description>&lt;p>얼쑤의 백엔드는 녹음 분석을 요청할 때 파일을 읽을 수 있는 서명 URL을 넘깁니다. 분석 서버는 그 주소에서 녹음을 내려받아 채점합니다. 이 서버를 운영에 추가할 때 외부에서 직접 호출할 수 있는 포트가 필요한지 먼저 살폈습니다. 앱은 이미 백엔드로 녹음을 올리고 결과를 조회하고 있어서, 분석 서버는 백엔드에서만 호출하면 됐습니다.&lt;/p>
&lt;h2 id="녹음-주소를-받는-api의-접근-범위">녹음 URL을 받는 API의 접근 범위&lt;/h2>
&lt;p>당시 분석 API는 호출자를 인증하거나 다운로드 목적지의 호스트를 제한하지 않았습니다. URL이 HTTP나 HTTPS로 시작하는지는 확인했지만, 사설 주소도 그 조건을 충족합니다. 외부 호출자가 이 API에 요청을 보낼 수 있다면 서버가 대신 내부 주소에 접속하게 할 수 있습니다. 응답 차이만으로도 어떤 주소에 연결이 됐는지 짐작할 여지가 생깁니다.&lt;/p></description></item><item><title>Jenkins가 새 Compose 파일을 못 읽은 이유</title><link>https://team-edo.github.io/posts/2026/10/atomic-compose-install-permissions/</link><pubDate>Thu, 29 Oct 2026 00:00:00 +0900</pubDate><guid>https://team-edo.github.io/posts/2026/10/atomic-compose-install-permissions/</guid><description>&lt;p>운영 Compose 파일을 바꾼 뒤 Jenkins 배포가 설정 검사에서 멈췄습니다. 같은 파일을 root로 검사하니 통과했고, Jenkins 계정으로 실행하니 읽기 권한이 없었습니다. 파일은 &lt;code>root:root&lt;/code> 소유에 모드가 &lt;code>0600&lt;/code>이었습니다. 파일의 내용은 그대로 두고 Jenkins 그룹에 읽기 권한을 복구하자 같은 커밋의 재실행이 배포까지 성공했습니다. 이후 같은 문제가 다시 생겨 배포 네 건이 연속으로 실패했습니다.&lt;/p>
&lt;h2 id="바뀔-파일을-실제-계정으로-먼저-읽었다">Jenkins 계정으로 교체 전 검사&lt;/h2>
&lt;p>같은 파일시스템에서 새 파일을 준비한 뒤 이름을 바꾸면, 읽는 쪽에는 완성된 파일만 보입니다. 이때 새 경로의 권한은 옛 파일에서 이어지는 값이 아니라 교체해 넣는 파일이 가진 값입니다.&lt;/p></description></item></channel></rss>