![프로그래밍 방식으로 docker-desktop 구성 설정](https://rvso.com/image/1703323/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D%20%EB%B0%A9%EC%8B%9D%EC%9C%BC%EB%A1%9C%20docker-desktop%20%EA%B5%AC%EC%84%B1%20%EC%84%A4%EC%A0%95.png)
나 또 왔어. 나 좀 도와줄 수 있는지 보자...
일반적으로 0에서 docker-desktop을 설치하면 일부 구성 파일이 다음과 같이 설정됩니다.
C:\Users\AppData\Roaming\Docker\setting.json
거의 항상 수동 단계를 수행해야 합니다. 애플리케이션을 열고 설문 조사를 수행한 다음 설정을 변경하고 저장 및 적용한 다음 닫고 다시 로그인합니다.
저는 터미널에서 docker-desktop을 사용하는 데 더 관심이 많습니다. 일반적으로 명령을 실행하여 네트워크를 생성하고 다음을 기반으로 컨테이너를 생성합니다.docker-compose
제가 찾고 있는 문제 또는 도움은 설정을 업데이트하고 데스크톱 애플리케이션을 닫았다가 다시 여는 프로그래밍 부분인 docker-desktop을 수행하는 데 도움을 줄 수 있는지 여부입니다.
여기에 오기 전에 C#으로 뭔가를 시도했지만 불안정한 것으로 나타났습니다.
https://stackoverflow.com/questions/78048247/check-wait-for-the-invoked-application-to-be-open
PowerShell을 사용하여 이것이 달성될 수 있다고 확신하지만 이에 대해 많이 알지 못합니다.
Docker 게시물 포럼 관련:https://forums.docker.com/t/programmatic-manipulation-and-management-of-docker-desktop/140018
Powershell에서는 다음을 수행했습니다.
# Defines the configuration dictionary
$settingsToReplace = @{
'"exposeDockerAPIOnTCP2375": false,' = '"exposeDockerAPIOnTCP2375": true,'
'"updateHostsFile": false,' = '"updateHostsFile": true,'
'"licenseTermsVersion": 0,' = '"licenseTermsVersion": 2,'
}
# Defines the path to the configuration file
$settingsPath = "$env:APPDATA\Docker\settings.json"
# Read the contents of the configuration file
$settingsContent = Get-Content $settingsPath -Raw
# Replaces the values in the file content
foreach ($key in $settingsToReplace.Keys) {
$settingsContent = $settingsContent -replace [regex]::Escape($key), $settingsToReplace[$key]
}
# Write the modified content back to the file
$settingsContent | Set-Content $settingsPath
# Close Docker Desktop
Stop-Process -Name "Docker Desktop*" -ErrorAction SilentlyContinue
# Wait until Docker Desktop has completely closed
$timeout = 60 # seconds
$processName = "Docker Desktop"
$timeoutReached = $false
$startTime = Get-Date
# Wait until Docker Desktop has completely closed or the timeout has been reached
while ((Get-Process -Name $processName -ErrorAction SilentlyContinue) -and (-not $timeoutReached)) {
# Verifica si el proceso de Docker Desktop se ha cerrado
if (-not (Get-Process -Name $processName -ErrorAction SilentlyContinue)) {
Write-Host "Docker Desktop has closed before the time limit was reached."
break
}
# Check if the time limit has been reached
if ((Get-Date) - $startTime -ge [TimeSpan]::FromSeconds($timeout)) {
$timeoutReached = $true
}
# Wait 1 second before checking again
Start-Sleep -Seconds 1
}
# Check if the timeout has been reached
if ($timeoutReached) {
Write-Host "Docker Desktop did not close properly. Please manually close the application and run the script again."
} else {
Write-Host "Docker Desktop has closed successfully. Continuing..."
}
# Open Docker Desktop
$docker = [System.Environment]::GetEnvironmentVariable('ProgramFiles') + '\Docker\Docker\Docker Desktop.exe'
Start-Process -FilePath $docker
# Wait until Docker Desktop has fully opened
$processName = "Docker Desktop"
while (-not (Get-Process -Name $processName -ErrorAction SilentlyContinue)) {
Start-Sleep -Seconds 1
}
Write-Host "continue"
하지만 docker-desktop이 다시 불안정해지는 것을 감지했습니다. 업데이트 호스트 파일에 대한 설정이 settings.json에 적용되지만 docker-desktop에는 채팅되지 않습니다.
업데이트:
"불안정"의 정확한 증상은 무엇입니까?
답변:스크립트를 사용하여 Docker-Desktop을 열면 Docker-Desktop 사용자 인터페이스가 차단되는 지점까지 천천히 느려지고 마우스 클릭에 응답하지 않습니다.
Docker 데스크톱을 다시 시작한 후 변경 사항이 적용되었는지 어떻게 테스트합니까?
답변:설정 탭은 docker-desktop에서 열리고 변경 사항이 적용되지 않은 것처럼 계속됩니다. 하지만 변경 사항은 settings.json 파일에 반영됩니다.
업데이트 #2
내가 하고 있는 일을 요약해 보겠습니다. docker 데스크톱을 불안정하게 만드는 요인을 평가하기 위해 C#을 따로 남겨두었습니다. 이것은 제가 배포 중인 완전한 powershell 스크립트이며, settings.json에 필요한 변경 사항이 포함되어 있습니다. 스크립트는 올바르게 작동하지만, 30초 후에 해당 docker-desktop UI가 열리면 UI 컨트롤을 클릭하려고 할 때 완전히 불안정하거나 약간 깜박입니다.
$ErrorActionPreference = 'Continue'
Set-Service -Name "com.docker.service" -StartupType Automatic -ErrorAction SilentlyContinue
Stop-Service -Name "com.docker.service" -ErrorAction SilentlyContinue
Get-Process 'Docker Desktop' -ErrorAction Ignore | Stop-Process -Force -ErrorAction Stop
Wait-Process -Name 'Docker Desktop' -ErrorAction SilentlyContinue
$settingsToUpdate = @{
exposeDockerAPIOnTCP2375 = $true
updateHostsFile = $true
licenseTermsVersion = 2
noWindowsContainers = $true
runWinServiceInWslMode = $false
useResourceSaver = $false
}
$settingsPath = "$env:APPDATA\Docker\settings.json"
$settingsContent = Get-Content $settingsPath -Raw
$settingsObject = $settingsContent | ConvertFrom-Json
$trackUpdates = 0
foreach ($update in $settingsToUpdate.GetEnumerator()) {
if ($target = $settingsObject.psobject.Properties.Match($update.Key)) {
if ($target.Value -ne $update.Value) {
Add-Member -InputObject $settingsObject -MemberType NoteProperty -Name $update.Key -Value $update.Value -Force
$trackUpdates++
}
}
}
if ($trackUpdates -eq 0) {
Write-Host "No new settings applied"
} else {
$settingsObject | ConvertTo-Json | Set-Content $settingsPath
Write-Host "Settings updated and saved successfully"
}
Start-Service -Name "com.docker.service" -ErrorAction SilentlyContinue
while ((Get-Service -Name "com.docker.service").Status -ne "Running") {
Write-Host (Get-Service -Name "com.docker.service").Status
Start-Sleep -Seconds 1
}
if((Get-Service -Name "com.docker.service").Status -eq "Running"){
Write-Host (Get-Service -Name "com.docker.service").Status
}
$dockerDesktopFilePath = $env:ProgramFiles | Join-Path -ChildPath 'Docker\Docker\Docker Desktop.exe'; Start-Process -FilePath $dockerDesktopFilePath
$ipcTimeout = New-TimeSpan -Seconds 20
$waitUntil = [datetime]::Now.Add($ipcTimeout)
$pipeOpen = $false
Write-Host 'Probing docker engine I/O pipe'
do {
Start-Sleep -Milliseconds 100
$pipeOpen = Test-Path -LiteralPath \\.\pipe\docker_engine
} until ($pipeOpen -or ($waitUntil -le [datetime]::Now))
if (-not $pipeOpen) {
Write-Warning "Failed to observe named IPC pipe docker_engine within timeout"
return
}
$responseTimeout = New-TimeSpan -Seconds 5
$waitUntil = [datetime]::Now.Add($responseTimeout)
Write-Host 'Querying docker server info'
do {
Start-Sleep -Milliseconds 500
$dockerInfoOutput = docker info 2>&1
$dockerInfoSuccess = $?
} until ($dockerInfoSuccess -or ($waitUntil -le [datetime]::Now))
if (-not $dockerInfoSuccess) {
Write-Warning "docker info failed within timeout"
return
}
Write-Host 'Docker Desktop Is Runing Now'
업데이트 #3
그래서 문제는 애플리케이션을 여는 방법이 아니라 닫는 방법입니다…
친구가 이 스크립트를 실행하려고 합니다.
$ServiceName = "com.docker.service"
$ProcessName = "Docker Desktop"
$arrService = Get-Service -Name $ServiceName
if ($arrService.Status -ne 'Running') {
Stop-Service -Name $ServiceName
}
if (Get-Process $ProcessName -ErrorAction SilentlyContinue) {
Stop-Process -Name $ProcessName
Wait-Process -Name $ProcessName
}
내 경우에는 서비스가 실행되지 않을 것이므로 코드의 상단 부분은 중요하지 않습니다. 작업 관리자에서 Docker 데스크톱과 관련하여 4개 또는 각각 6개의 프로세스가 실행되고 있는 것을 볼 수 있습니다. 그래서 Stop-Process 명령은 "Docker Desktop" 프로세스를 즉시 종료했습니다. 그러나 "Docker Desktop Backend" 및 "Docker Desktop Extensions" 프로세스 2개가 여전히 실행 중입니다. 바로가기를 더블클릭하여 Docker Desktop을 시작한 후 Docker 엔진이 일시정지되어 애플리케이션이 안정적으로 실행되지 않는 것을 확인할 수 있었습니다. 그런 다음 모든 프로세스를 종료하고 아무런 문제 없이 Docker Desktop을 다시 열 수 있었습니다. 이제부터는 다른 모든 것을 스스로 알아내야 합니다.
Docker-Desktop을 닫을 때 얼마나 많은 프로세스를 닫아야 하는지 명확하지 않습니다. 닫으려면 와일드카드가 필요한 것 같습니다. "Docker-Desktop*"
또는 "Docker Desktop*"
또는 "*Docker*"
이로 인해 계속 실행되어야 하는 프로세스가 닫힐 수 있습니다.
한편 어젯밤 0에서 #64를 설치했을 때 흥미로운 점을 발견했습니다.
Docker가 실행 중이고 처음으로 설정으로 이동하여 호스트 파일을 업데이트하는 옵션을 선택한 경우 updateHostsFile 속성만 변경되는 것은 아닙니다. 다른 2개도 변경됩니다. noWindowsContainers, runWinServiceInWslMode 및 Windows 11/10 home을 사용하는 경우 일반 도커 구성을 망칩니다. 이러한 옵션은 Hiper-V와 함께 PRO 버전을 사용하는 경우에만 활성화해야 하기 때문입니다.
따라서 이러한 이유로 updateHostsFile을 프로그래밍 방식으로 활성화하면 아무런 효과가 없습니다. 다른 두 개를 활성화하지 않으면 긍정적인 결과도 얻지 못할 것입니다.
일이 복잡하고 복잡합니다. PowerShell을 통해 관리하는 것이 더 간단할 것입니다…
답변1
프로그래밍 방식으로 수행할 최종 스크립트:
- Docker 서비스 및 프로세스를 중지합니다.
- settings.json을 업데이트합니다.
- Docker 데스크탑을 다시 여십시오.
https://gist.github.com/arcanisgk/d78acd5d51ab263d9467fb2da97781ca
불안정성 문제는 docker에 포함된 모든 프로세스가 닫히지 않았기 때문에 발생했습니다. 분명히 동일하게 닫혀야 하는 일련의 추가 프로세스(서비스 아님)가 있거나 이로 인해 불안정성이 발생할 수 있습니다.
$ErrorActionPreference = 'Continue'
Stop-Service -Name "com.docker.*" -ErrorAction SilentlyContinue
Set-Service -Name "com.docker.service" `
-StartupType Automatic `
-ErrorAction SilentlyContinue
$processesToStop = @(
'Docker Desktop',
'com.docker.backend',
'com.docker.extensions'
)
$processesToStop | ForEach-Object {
Get-Process -Name $_ -ErrorAction Ignore |
Stop-Process -Force -ErrorAction Ignore
}
$settingsToUpdate = @{
exposeDockerAPIOnTCP2375 = $true
updateHostsFile = $true
licenseTermsVersion = 2
noWindowsContainers = $false # Required to enable read updateHostsFile
runWinServiceInWslMode = $true # Required to enable read updateHostsFile
useResourceSaver = $false
}
$settingsPath = "$env:APPDATA\Docker\settings.json"
$settingsContent = Get-Content $settingsPath -Raw
$settingsObject = $settingsContent | ConvertFrom-Json
$trackUpdates = 0
foreach ($update in $settingsToUpdate.GetEnumerator()) {
if ($target = $settingsObject.psobject.Properties.Match($update.Key)) {
if ($target.Value -ne $update.Value) {
Write-Host $update.Key
Add-Member `
-InputObject $settingsObject `
-MemberType NoteProperty `
-Name $update.Key `
-Value $update.Value `
-Force
$trackUpdates++
}
}
}
if ($trackUpdates -eq 0) {
Write-Host "No new settings applied"
} else {
$settingsObject | ConvertTo-Json | Set-Content $settingsPath
Write-Host "Settings updated and saved successfully"
}
Start-Service -Name "com.docker.service" -ErrorAction SilentlyContinue
while ((Get-Service -Name "com.docker.service").Status -ne "Running") {
Write-Host (Get-Service -Name "com.docker.service").Status
Start-Sleep -Seconds 1
}
if((Get-Service -Name "com.docker.service").Status -eq "Running"){
Write-Host "Service: com.docker.service is now:"
Write-Host (Get-Service -Name "com.docker.service").Status
}
$dockerDesktopFilePath = $env:ProgramFiles |
Join-Path -ChildPath 'Docker\Docker\Docker Desktop.exe'
Start-Process -FilePath $dockerDesktopFilePath
$ipcTimeout = New-TimeSpan -Seconds 20
$waitUntil = [datetime]::Now.Add($ipcTimeout)
$pipeOpen = $false
Write-Host 'Probing docker engine I/O pipe'
do {
Start-Sleep -Milliseconds 100
$pipeOpen = Test-Path -LiteralPath \\.\pipe\docker_engine
}
until ($pipeOpen -or ($waitUntil -le [datetime]::Now))
if (-not $pipeOpen) {
Write-Warning "Failed to observe named IPC pipe docker_engine within timeout"
return
}
$responseTimeout = New-TimeSpan -Seconds 5
$waitUntil = [datetime]::Now.Add($responseTimeout)
Write-Host 'Querying docker server info'
do {
Start-Sleep -Milliseconds 500
$dockerInfoOutput = docker info 2>&1
$dockerInfoSuccess = $?
}
until ($dockerInfoSuccess -or ($waitUntil -le [datetime]::Now))
if (-not $dockerInfoSuccess) {
Write-Warning "docker info failed within timeout"
return
}
Write-Host 'Docker Desktop Is Runing Now'