ì ì´ ìë¬ê° ì꾸 ëì¤ë
ë커를 ì°ë¤ ë³´ë©´ ìì¤í구 ì´ ë ê°ì§ë¥¼ 겪ëë¤.
- 컨í ì´ë ëì°ë ¤ëë° í¬í¸ê° ì´ë¯¸ ì ì ëë¤ê³ ë§í
- 컨í ì´ëë ì¤í ì¤ì¸ë° ì±ë¼ë¦¬ íµì ì´ ì ë¨
ë ë¤ "ì?"를 ì´í´íë©´ í´ê²°ì 5ë¶ì´ë¤. ëª¨ë¥´ê³ --forceë ì¬ììë§ ë°ë³µíë©´ í루 ë 린ë¤.
1. í¬í¸ ì¶©ë ìë¬
ìë¬ ë©ìì§ í¨í´
Error response from daemon: driver failed programming external connectivity on endpoint myapp
(xxx): Bind for 0.0.0.0:8080 failed: port is already allocated
Error starting userland proxy: listen tcp4 0.0.0.0:3306: bind: address already in use
ìì¸ 3ê°ì§
| ìì¸ | ë¹ë | ì¤ëª |
|---|---|---|
| ì´ì 컨í ì´ëê° ì£½ì§ ìê³ í¬í¸ ì ì ì¤ | â â â | docker stop ì íê³ ê·¸ë¥ í°ë¯¸ë ë«ì ê²½ì° |
| í¸ì¤í¸ íë¡ì¸ì¤(MySQL, Nginx ë±)ê° ê°ì í¬í¸ ì¬ì© | â â â | ë¡ì»¬ì MySQL ê¹ë ¤ìëë° 3306 ì°ë ¤ í ë |
| ì´ì 컨í ì´ëê° exited ìíë¡ í¬í¸ íë© | â ââ | docker psì ì ë³´ì´ì§ë§ docker ps -aì ë³´ì |
[ì´ë³´] ë¨ê³ë³ í´ê²°ë²
1ë¨ê³: ì´ë¤ íë¡ì¸ì¤ê° í¬í¸ ì°ëì§ íì¸
# macOS / Linux
lsof -i :8080
# Windows (PowerShell)
netstat -ano | findstr :8080
2ë¨ê³: ë커 컨í ì´ë íì¸
# ì¤í ì¤ì¸ 컨í
ì´ëë§
docker ps
# ì¤ë¨ë ê² í¬í¨ ì ì²´
docker ps -a
# í¹ì í¬í¸ ì°ë 컨í
ì´ë 찾기
docker ps --filter "publish=8080"
3ë¨ê³: ì ì ì¤ì¸ 컨í ì´ë ì 리
# í¹ì 컨í
ì´ë ì¤ì§
docker stop <container_id>
# ì¤ì§ + ìì
docker rm -f <container_id>
# exited ìí 컨í
ì´ë ì¼ê´ ì 리
docker container prune
[ì¤ê¸] í¬í¸ 매í ì ëµ
ê°ì í¬í¸ë¥¼ ì¨ì¼ íë ìë¹ì¤ê° ì¬ë¬ ê°ë¼ë©´, í¸ì¤í¸ í¬í¸ë¥¼ ë¤ë¥´ê² 매ííë¤.
# í¸ì¤í¸ 8081 â 컨í
ì´ë ë´ë¶ 8080
docker run -p 8081:8080 myapp
# ì¬ë¬ í¬í¸ ëì 매í
docker run -p 8080:8080 -p 443:443 myapp
docker-compose.ymlììë:
services:
app:
image: myapp
ports:
- "8081:8080" # í¸ì¤í¸:컨í
ì´ë
db:
image: mysql:8
ports:
- "3307:3306" # ë¡ì»¬ MySQLê³¼ ì¶©ë ë°©ì§
[ê³ ê¸] ëì í¬í¸ í ë¹
í ì¤í¸ íê²½ìì í¬í¸ ì¶©ëì ìì² ì°¨ë¨íë ë°©ë² â í¸ì¤í¸ í¬í¸ë¥¼ ëì»¤ê° ììì ë¹ì´ìë ê±° ì¡ê² íë¤.
# í¸ì¤í¸ í¬í¸ 미ì§ì â ìì í ë¹
docker run -p 0:8080 myapp
# í ë¹ë í¬í¸ íì¸
docker port <container_id> 8080
# ì¶ë ¥ ì: 0.0.0.0:49152
Node.jsìì íê²½ë³ìë¡ í¬í¸ ë°ì ì°ë í¨í´:
// app.js
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
2. 컨í ì´ë ê° íµì ì ëë ìë¬
ìë¬ ë©ìì§ í¨í´
Error: connect ECONNREFUSED 127.0.0.1:3306
getaddrinfo ENOTFOUND db
컨í
ì´ë Aìì 컨í
ì´ë Bì localhostë¡ ì ìíë ¤ í´ì ì기ë 문ì ë¤. 컨í
ì´ëë¼ë¦¬ localhostë ê³µì íì§ ìëë¤. ê°ì ë
립ë ë¤í¸ìí¬ ë¤ìì¤íì´ì¤ë¥¼ ê°ì§ë¤.
ìì¸ê³¼ í´ê²°ë² ì²´í¬ë¦¬ì¤í¸
| ìí© | ì못ë ì ê·¼ | ì¬ë°ë¥¸ ì ê·¼ |
|---|---|---|
| 컨í ì´ë A â B ì ì | localhost:3306 | 컨í ì´ëëª ëë ìë¹ì¤ëª |
| docker run ë¨ë ì¤í | ë¤í¸ìí¬ ë¯¸ì§ì | --network íëê·¸ë¡ ê°ì ë¤í¸ìí¬ ì¬ì© |
| docker-compose ì¬ì© | ë³ë network ì ì | ê°ì compose íì¼ ë´ë©´ ìë ì°ê²° |
[ì´ë³´] docker-composeë¡ ì»¨í ì´ë ì°ê²°
docker-compose를 ì°ë©´ ê°ì íì¼ ìì ìë¹ì¤ë¼ë¦¬ë ìë¹ì¤ëª ì¼ë¡ ë°ë¡ íµì ëë¤. ë¤í¸ìí¬ ì¤ì ë°ë¡ ì í´ë ëë¤.
# docker-compose.yml
services:
app:
image: node:20
environment:
DB_HOST: db # "localhost" ìëê³ ìë¹ì¤ëª
"db"
DB_PORT: 3306
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: mydb
Node.jsìì DB ì°ê²°:
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
host: process.env.DB_HOST || 'db', // ìë¹ì¤ëª
port: process.env.DB_PORT || 3306,
user: 'root',
password: 'secret',
database: 'mydb'
});
Python (SQLAlchemy):
import os
from sqlalchemy import create_engine
DATABASE_URL = (
f"mysql+pymysql://root:secret@"
f"{os.getenv('DB_HOST', 'db')}:"
f"{os.getenv('DB_PORT', '3306')}/mydb"
)
engine = create_engine(DATABASE_URL)
[ì¤ê¸] docker runì¼ë¡ ìë ë¤í¸ìí¬ ì°ê²°
docker-compose ìì´ ì»¨í ì´ë ì¬ë¬ ê° ì°ê²°í ë:
# 1. ê³µì© ë¤í¸ìí¬ ìì±
docker network create mynet
# 2. DB 컨í
ì´ë를 í´ë¹ ë¤í¸ìí¬ì ë¶ì¬ ì¤í
docker run -d \
--name mydb \
--network mynet \
-e MYSQL_ROOT_PASSWORD=secret \
mysql:8
# 3. ì± ì»¨í
ì´ëë ê°ì ë¤í¸ìí¬ë¡ ì¤í
docker run -d \
--name myapp \
--network mynet \
-e DB_HOST=mydb \
-p 8080:8080 \
myapp:latest
Java (Spring Boot) application.yml:
spring:
datasource:
url: jdbc:mysql://${DB_HOST:mydb}:${DB_PORT:3306}/mydb
username: root
password: secret
[ê³ ê¸] ë¤í¸ìí¬ ëë²ê¹
# 컨í
ì´ëê° ì´ë¤ ë¤í¸ìí¬ì ë¶ì´ìë
docker inspect myapp | grep -A 20 "Networks"
# í¹ì ë¤í¸ìí¬ì ì°ê²°ë 컨í
ì´ë 목ë¡
docker network inspect mynet
# 컨í
ì´ë ììì ì§ì í í
ì¤í¸
docker exec -it myapp ping mydb
# 컨í
ì´ë ììì í¬í¸ ì´ë ¤ìë íì¸
docker exec -it myapp nc -zv mydb 3306
# ìì debug 컨í
ì´ëë¡ ë¤í¸ìí¬ ì§ë¨
docker run --rm --network mynet nicolaka/netshoot nmap -p 3306 mydb
Nginx ì¤ì ìì upstreamì 컨í ì´ëëª ì¼ë¡:
# nginx.conf
upstream backend {
server app:8080; # 컨í
ì´ë/ìë¹ì¤ëª
}
server {
listen 80;
location / {
proxy_pass http://backend;
}
}
í¸ë¬ë¸ìí ì²´í¬ë¦¬ì¤í¸
í¬í¸ ì¶©ë ë°ì ì
| ì²´í¬ í목 | ëª ë ¹ì´ |
|---|---|
| ì¤í ì¤ì¸ 컨í ì´ë íì¸ | docker ps |
| ì¤ë¨ í¬í¨ ì ì²´ íì¸ | docker ps -a |
| í¸ì¤í¸ í¬í¸ ì ì íì¸ | lsof -i :PORT (mac/linux) |
| 문ì 컨í ì´ë ê°ì ìì | docker rm -f CONTAINER_ID |
| ë¶íìí 컨í ì´ë ì¼ê´ ì 리 | docker container prune |
| í¬í¸ ë¤ë¥´ê² ì¬ë§¤í | docker run -p HOST:CONTAINER |
컨í ì´ë ì°ê²° ì ë ë
| ì²´í¬ í목 | ëª ë ¹ì´ |
|---|---|
| ê°ì ë¤í¸ìí¬ì¸ì§ íì¸ | docker network inspect NETWORK |
| 컨í ì´ëëª /ìë¹ì¤ëª ì¼ë¡ ì ìíëì§ íì¸ | localhost â ìë¹ì¤ëª
|
| 컨í ì´ë ë´ë¶ìì í í ì¤í¸ | docker exec -it APP ping DB |
| í¬í¸ ì´ë ¤ìë íì¸ | docker exec -it APP nc -zv DB PORT |
| 컨í ì´ë ë¡ê·¸ íì¸ | docker logs CONTAINER_ID |
| ë¤í¸ìí¬ ì¬ìì± í ì¬ì°ê²° | docker network create + --network |
ì주 íë ì¤ì ìì½
1. docker stop ëì í°ë¯¸ëë§ ë«ëë¤
â 컨í
ì´ëë ì´ìì í¬í¸ ê³ì ì ì . docker stop ëë docker-compose down ìµê´í.
2. 컨í
ì´ë ììì localhostë¡ ë¤ë¥¸ 컨í
ì´ë ì ê·¼
â ê° ì»¨í
ì´ëë ë
립 ë¤í¸ìí¬. ìë¹ì¤ëª
ì´ë 컨í
ì´ëëª
ì¼ë¡ ì ê·¼.
3. exited 컨í
ì´ëê° í¬í¸ ì¡ê³ ìë ì¤ ëª¨ë¦
â docker ps -aë¡ exited í¬í¨í´ì íì íì¸.
4. depends_onë§ ë¯¿ê³ DB ì¤ë¹ëë¤ê³ ì°©ê°
â depends_onì 컨í
ì´ë ìì ììë§ ë³´ì¥. DBê° ì¤ì ë¡ ready ìíì¸ì§ë ë³ê°. healthcheckë wait ë¡ì§ íì.
# healthcheckë¡ DB ì¤ë¹ íì¸
services:
db:
image: mysql:8
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 5s
timeout: 10s
retries: 5
app:
depends_on:
db:
condition: service_healthy # DB healthy íì¸ í ìì
ë커 ê´ë ¨ ìë¬ë ëë¶ë¶ ì´ ë ê°ì§ìì ì¨ë¤. í¬í¸ ì¶©ëì´ë©´ docker ps -aë¶í°, ì°ê²° ì ëë©´ ë¤í¸ìí¬ì í¸ì¤í¸ëª
ë¶í° íì¸íë©´ 길ì ìì§ ìëë¤.
댓글 없음:
댓글 쓰기