Skip to content

Commit 0eae677

Browse files
authored
Merge pull request #33 from litencatt/do-not-assign-reserved-port-numbers
Do not assign reserved port numbers
2 parents eb6405a + 40b7387 commit 0eae677

File tree

5 files changed

+721
-27
lines changed

5 files changed

+721
-27
lines changed

README.md

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,25 @@ gopose up --port-range 9000-9999
8888
gopose up --port-range 8000-8999,9000-9999
8989
```
9090

91-
#### Exclusion Settings
91+
#### Reserved Ports Configuration
9292

9393
```bash
94-
# Exclude specific services
95-
gopose up --exclude-services redis,postgres
94+
# Reserve specific ports (will never be assigned even if unused)
95+
# Use configuration file for persistent settings
96+
```
9697

97-
# Exclude privileged ports
98-
gopose up --exclude-privileged
98+
You can reserve specific ports in `.gopose.yaml` to prevent them from being assigned:
9999

100-
# Exclude reserved ports
101-
gopose up --exclude-ports 8080,8443,9000
100+
```yaml
101+
port:
102+
reserved: [8080, 8443, 9000, 9090] # These ports will never be assigned
102103
```
103104
105+
**Important**: Reserved ports are guaranteed to be skipped during port allocation, regardless of whether they are currently in use or not. This is useful for:
106+
- Preventing conflicts with services you plan to start later
107+
- Reserving ports for manual debugging or testing
108+
- Avoiding specific ports that may be used by other tools or services
109+
104110
#### Output and Logging Settings
105111
106112
```bash
@@ -129,6 +135,8 @@ port:
129135
range:
130136
start: 8000
131137
end: 9999
138+
# Reserved ports: These ports will NEVER be assigned, even if they are not in use
139+
# Useful for preventing conflicts with services you plan to start later
132140
reserved: [8080, 8443, 9000, 9090]
133141
exclude_privileged: true
134142

@@ -152,6 +160,16 @@ resolver:
152160
port_proximity: true
153161
```
154162
163+
#### Configuration Priority
164+
165+
Configuration settings are applied in the following order (later values override earlier ones):
166+
167+
1. Default configuration (built-in)
168+
2. Configuration file (`.gopose.yaml`)
169+
3. CLI options (e.g., `--port-range`)
170+
171+
**Note**: Reserved ports from the configuration file are always preserved, even when using CLI options to override the port range.
172+
155173
### Output Example
156174

157175
```
@@ -241,6 +259,62 @@ time=2025-06-10T23:31:03.780+09:00 level=INFO msg="Docker Composeを実行" comp
241259
Attaching to web-1
242260
```
243261
262+
## Reserved Ports
263+
264+
The `reserved` configuration allows you to specify ports that should never be assigned by gopose, regardless of whether they are currently in use.
265+
266+
### Use Cases
267+
268+
- **Future services**: Reserve ports for services you plan to start later
269+
- **Manual debugging**: Keep specific ports available for manual testing
270+
- **External tools**: Avoid conflicts with ports used by other development tools
271+
- **Consistency**: Ensure certain ports remain free across different environments
272+
273+
### Example Configuration
274+
275+
```yaml
276+
# .gopose.yaml
277+
port:
278+
range:
279+
start: 8000
280+
end: 8100
281+
reserved:
282+
- 8080 # Reserved for main application
283+
- 8443 # Reserved for HTTPS proxy
284+
- 9000 # Reserved for debugging
285+
- 9090 # Reserved for monitoring tools
286+
exclude_privileged: true
287+
```
288+
289+
### Behavior
290+
291+
With the above configuration:
292+
- If gopose needs to assign ports for Docker Compose services with conflicts on ports 80 and 443
293+
- It will skip ports 8080, 8443, 9000, and 9090 (even if they are not in use)
294+
- Available ports like 8000-8079, 8081-8442, 8444-8999, 9001-9089, 9091-8100 will be considered
295+
- For example, ports 8000, 8001, etc. might be assigned instead
296+
297+
### Testing Reserved Ports
298+
299+
You can verify that reserved ports are working correctly:
300+
301+
```bash
302+
# Create a test configuration
303+
cat > .gopose.yaml << EOF
304+
port:
305+
range:
306+
start: 8000
307+
end: 8100
308+
reserved: [8000, 8001, 8002, 8050]
309+
EOF
310+
311+
# Run gopose - it will skip the reserved ports
312+
gopose up --dry-run
313+
314+
# Check the generated compose.override.yml
315+
# You should see ports starting from 8003 (skipping 8000-8002)
316+
```
317+
244318
## Network Conflict Avoidance
245319

246320
gopose automatically detects subnet conflicts with existing Docker networks and assigns safe alternative subnets.

README_JA.md

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,25 @@ gopose up --port-range 9000-9999
8888
gopose up --port-range 8000-8999,9000-9999
8989
```
9090

91-
#### 除外設定
91+
#### 予約ポート設定
9292

9393
```bash
94-
# 特定のサービスを除外
95-
gopose up --exclude-services redis,postgres
94+
# 特定のポートを予約(未使用でも割り当てられません)
95+
# 永続的な設定には設定ファイルを使用します
96+
```
9697

97-
# 特権ポートを除外
98-
gopose up --exclude-privileged
98+
`.gopose.yaml`で特定のポートを予約して、割り当てられないようにできます:
9999

100-
# 予約ポートを除外
101-
gopose up --exclude-ports 8080,8443,9000
100+
```yaml
101+
port:
102+
reserved: [8080, 8443, 9000, 9090] # これらのポートは絶対に割り当てられません
102103
```
103104
105+
**重要**: 予約ポートは、現在使用中かどうかに関わらず、ポート割り当て時に確実にスキップされます。これは以下の用途に便利です:
106+
- 後で起動する予定のサービスとの衝突を防ぐ
107+
- 手動でのデバッグやテスト用にポートを確保
108+
- 他のツールやサービスが使用する可能性のある特定のポートを避ける
109+
104110
#### 出力とログ設定
105111
106112
```bash
@@ -129,6 +135,8 @@ port:
129135
range:
130136
start: 8000
131137
end: 9999
138+
# 予約ポート: これらのポートは未使用でも絶対に割り当てられません
139+
# 後で起動する予定のサービスとの衝突を防ぐのに便利です
132140
reserved: [8080, 8443, 9000, 9090]
133141
exclude_privileged: true
134142

@@ -152,6 +160,16 @@ resolver:
152160
port_proximity: true
153161
```
154162
163+
#### 設定の優先順位
164+
165+
設定は以下の順序で適用されます(後のものが優先されます):
166+
167+
1. デフォルト設定(組み込み)
168+
2. 設定ファイル(`.gopose.yaml`)
169+
3. CLIオプション(例:`--port-range`)
170+
171+
**注意**: 設定ファイルの予約ポートは、CLIオプションでポート範囲を上書きしても常に保持されます。
172+
155173
### 出力例
156174

157175
```
@@ -241,6 +259,62 @@ time=2025-06-10T23:31:03.780+09:00 level=INFO msg="Docker Composeを実行" comp
241259
Attaching to web-1
242260
```
243261
262+
## 予約ポート機能
263+
264+
`reserved`設定を使用すると、現在使用中かどうかに関わらず、goposeが絶対に割り当ててはいけないポートを指定できます。
265+
266+
### ユースケース
267+
268+
- **将来のサービス**: 後で起動する予定のサービス用にポートを予約
269+
- **手動デバッグ**: 手動テスト用に特定のポートを利用可能な状態に保つ
270+
- **外部ツール**: 他の開発ツールが使用するポートとの衝突を回避
271+
- **一貫性**: 異なる環境間で特定のポートを確実に空けておく
272+
273+
### 設定例
274+
275+
```yaml
276+
# .gopose.yaml
277+
port:
278+
range:
279+
start: 8000
280+
end: 8100
281+
reserved:
282+
- 8080 # メインアプリケーション用に予約
283+
- 8443 # HTTPSプロキシ用に予約
284+
- 9000 # デバッグ用に予約
285+
- 9090 # 監視ツール用に予約
286+
exclude_privileged: true
287+
```
288+
289+
### 動作
290+
291+
上記の設定では:
292+
- goposeがポート80と443で衝突があるDocker Composeサービスにポートを割り当てる必要がある場合
293+
- ポート8080、8443、9000、9090は(未使用であっても)スキップされます
294+
- 8000-8079、8081-8442、8444-8999、9001-9089、9091-8100などの利用可能なポートが検討されます
295+
- 例えば、8000、8001などのポートが割り当てられる可能性があります
296+
297+
### 予約ポートのテスト
298+
299+
予約ポートが正しく動作していることを確認できます:
300+
301+
```bash
302+
# テスト用設定を作成
303+
cat > .gopose.yaml << EOF
304+
port:
305+
range:
306+
start: 8000
307+
end: 8100
308+
reserved: [8000, 8001, 8002, 8050]
309+
EOF
310+
311+
# goposeを実行 - 予約ポートがスキップされます
312+
gopose up --dry-run
313+
314+
# 生成されたcompose.override.ymlを確認
315+
# 8003から始まるポートが表示されるはずです(8000-8002はスキップ)
316+
```
317+
244318
## ネットワーク衝突回避機能
245319

246320
goposeは既存のDockerネットワークとのサブネット衝突を自動検出し、安全な代替サブネットを割り当てます。

cmd/up.go

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,19 @@ func parsePortRange(portRangeStr string) (types.PortRange, error) {
6262
return types.PortRange{Start: start, End: end}, nil
6363
}
6464

65-
// createPortConfig はCLIオプションからポート設定を作成します。
66-
func createPortConfig(portRangeStr string) (types.PortConfig, error) {
67-
portRange, err := parsePortRange(portRangeStr)
68-
if err != nil {
69-
return types.PortConfig{}, err
65+
// createPortConfig はCLIオプションと設定ファイルからポート設定を作成します。
66+
// baseConfigをベースとして、portRangeStrが指定されている場合のみ範囲を上書きします。
67+
func createPortConfig(portRangeStr string, baseConfig types.PortConfig) (types.PortConfig, error) {
68+
// CLIでポート範囲が指定されている場合のみ上書き
69+
if portRangeStr != "" {
70+
portRange, err := parsePortRange(portRangeStr)
71+
if err != nil {
72+
return types.PortConfig{}, err
73+
}
74+
baseConfig.Range = portRange
7075
}
7176

72-
return types.PortConfig{
73-
Range: portRange,
74-
Reserved: []int{}, // 予約済みポートは空で開始
75-
ExcludePrivileged: true, // 特権ポートは除外
76-
}, nil
77+
return baseConfig, nil
7778
}
7879

7980
// detectWorktreeProjectName は現在の git ワークツリーのトップレベルディレクトリ名を
@@ -144,8 +145,8 @@ var upCmd = &cobra.Command{
144145
return fmt.Errorf("ロガーの初期化に失敗しました: %w", err)
145146
}
146147

147-
// ポート範囲の解析
148-
portConfig, err := createPortConfig(portRange)
148+
// ポート設定の作成(設定ファイルの値をベースに、CLIオプションで上書き)
149+
portConfig, err := createPortConfig(portRange, cfg.GetPort())
149150
if err != nil {
150151
return fmt.Errorf("ポート範囲の解析に失敗しました: %w", err)
151152
}
@@ -165,7 +166,8 @@ var upCmd = &cobra.Command{
165166
types.Field{Key: "output_file", Value: outputFile},
166167
types.Field{Key: "project_name", Value: composeProjectName},
167168
types.Field{Key: "strategy", Value: strategy},
168-
types.Field{Key: "port_range", Value: fmt.Sprintf("%d-%d", portConfig.Range.Start, portConfig.Range.End)})
169+
types.Field{Key: "port_range", Value: fmt.Sprintf("%d-%d", portConfig.Range.Start, portConfig.Range.End)},
170+
types.Field{Key: "reserved_ports", Value: portConfig.Reserved})
169171

170172
// Docker Composeファイルの自動検出(指定されていない場合)
171173
if filePath == "" || filePath == "compose.yml" {

0 commit comments

Comments
 (0)