Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker save images twice the size when using powershell - saving raw byte streams

Docker version 18.03.1-ce, build 9ee9f40

I'm using powershell to build a big project on windows.

When issuing the command

docker save docker.elastic.co/kibana/kibana > deploy/kibana.docker

I'm getting an file 1.4Gb.

Same command run in CMD produces 799Mb image.

Same command run in bash produces 799Mb image.

CMD and Bash takes less than a minute to save an image, while Powershell takes about 10 minutes.

I did not manage to find any normal explanation of this phenomenon in docker or MS docs.

Right now the "solution" is

Write-Output "Saving images to files"
cmd /c .\deploy-hack.cmd

But I want to find the actual underlying reason for this.

like image 918
NewRK Avatar asked Jul 17 '18 19:07

NewRK


1 Answers

PowerShell doesn't support outputting / passing raw byte streams through - any output from an external program such as docker is parsed line by line, into strings and the strings are then re-encoded on output to a file (if necessary).
It is the overhead of parsing, decoding and re-encoding that explains the performance degradation.

Windows PowerShell's > redirection operator produces UTF16-LE ("Unicode") files by default (whereas PowerShell Core uses UTF8), i.e., files that use (at least) 2 bytes per character. Therefore, it produces files that are twice the size of raw byte input[1], because each byte is interpreted as a character that receives a 2-byte representation in the output.

Your best bet is to use docker save with the -o / --output option to specify the output file (see the docs):

docker save docker.elastic.co/kibana/kibana -o deploy/kibana.docker

[1] Strictly speaking, how PowerShell interprets output from external programs depends on the value of [console]::OutputEncoding, which, if set to UTF8 (chcp 65001 on Windows), could situationally interpret multiple bytes as a single character. However, on Windows PowerShell the default is determined by the (legacy) system locale's OEM code page, which is always a single-byte encoding.

like image 152
mklement0 Avatar answered Nov 08 '22 23:11

mklement0