From 9b5b73a3aae954718fb9fa59d8a48b71451719ee Mon Sep 17 00:00:00 2001 From: Adam Farden Date: Sat, 29 Sep 2018 15:26:18 +0200 Subject: [PATCH 1/2] Initial commit of Windows containers --- Dockerfile-windows.template | 80 ++++++++++++++++++++++ docker-entrypoint.cmd | 132 ++++++++++++++++++++++++++++++++++++ update.sh | 34 ++++++++++ 3 files changed, 246 insertions(+) create mode 100644 Dockerfile-windows.template create mode 100644 docker-entrypoint.cmd diff --git a/Dockerfile-windows.template b/Dockerfile-windows.template new file mode 100644 index 0000000000..9d9726e4ad --- /dev/null +++ b/Dockerfile-windows.template @@ -0,0 +1,80 @@ +#### +#### Pretty Good Command Line Interface (PGCLI) +#### +FROM microsoft/windowsservercore:1803 as prepare + +# Set the variables for PGCLI +ENV PGC_VER %%PGC_VERSION%% +ENV PGC_REPO %%PGC_REPOSITORY%% + +##### Use PowerShell for the installation +SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] + +### Required for PGCLI +ENV PYTHONIOENCODING UTF-8 + +### Download PGCLI +RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \ + Invoke-WebRequest $('{0}/bigsql-pgc-{1}.zip' -f $env:PGC_REPO,$env:PGC_VER) -OutFile 'C:\\BigSQL.zip' ; \ + Expand-Archive 'C:\\BigSQL.zip' -DestinationPath 'C:\\' ; \ + Remove-Item -Path 'C:\\BigSQL.zip' + +### Update PGCLI +RUN Invoke-Expression -Command $('C:\\bigsql\\pgc set GLOBAL REPO {0}' -f$env:PGC_REPO) ; \ + Invoke-Expression -Command 'C:\\bigsql\\pgc update --silent' ; \ + Remove-Item -Path 'C:\\bigsql\\conf\\pgc.pid' + +#### +#### Download PostgreSQL +#### +FROM prepare as download + +### Set the PostgreSQL version we will install +### This is set here to allow us to reuse the abover layers +ENV PGC_DB %%PGC_DB_VERSION%% + +### Download PostgreSQL +RUN Invoke-Expression -Command $('C:\\bigsql\\pgc install --silent {0}' -f $env:PGC_DB) ; \ + Invoke-Expression -Command 'C:\\bigsql\\pgc clean' ; \ + Remove-Item -Path 'C:\\bigsql\\conf\\pgc.pid' + +### Make the sample config easier to munge (and "correct by default") +RUN $SAMPLE_FILE = $('C:\\bigsql\\{0}\\share\\postgresql\\postgresql.conf.sample' -f $env:PGC_DB) ; \ + $SAMPLE_CONF = Get-Content $SAMPLE_FILE ; \ + $SAMPLE_CONF = $SAMPLE_CONF -Replace '#listen_addresses = ''localhost''','listen_addresses = ''*''' ; \ + $SAMPLE_CONF | Set-Content $SAMPLE_FILE + +#### +#### PostgreSQL on Windows Nano Server +#### +FROM microsoft/nanoserver:1803 + +RUN mkdir "C:\\docker-entrypoint-initdb.d" + +#### Copy over the PGCLI +COPY --from=prepare "C:\\bigsql" "C:\\bigsql" + +### Set the PostgreSQL version we will install +### This is set here to allow us to reuse the abover layers +ENV PGC_DB %%PGC_DB_VERSION%% + +### Required for PGCLI +ENV PYTHONIOENCODING="UTF-8" \ + PYTHONPATH="C:\\bigsql\\${PGC_DB}\\python\\site-packages" \ + GDAL_DATA="C:\\bigsql\\${PGC_DB}\\share\\gdal" + +#### Copy over PostgeSQL +COPY --from=download "C:\\bigsql\\${PGC_DB}" "C:\\bigsql\\${PGC_DB}" + +#### In order to set system PATH, ContainerAdministrator must be used +USER ContainerAdministrator +RUN setx /M PATH "C:\\bigsql\\%PGC_DB%\\bin;%PATH%" +USER ContainerUser +ENV PGDATA "C:\\bigsql\\data\\${PGC_DB}" +RUN mkdir "%PGDATA%" + +COPY docker-entrypoint.cmd "C:\\" +ENTRYPOINT ["C:\\docker-entrypoint.cmd"] + +EXPOSE 5432 +CMD ["postgres"] diff --git a/docker-entrypoint.cmd b/docker-entrypoint.cmd new file mode 100644 index 0000000000..dad0302a60 --- /dev/null +++ b/docker-entrypoint.cmd @@ -0,0 +1,132 @@ +@echo off +SETLOCAL EnableDelayedExpansion + +:: Batch file has no concept of a function, only goto +goto :start + +:: usage: CALL :file_env VARIABLE [DEFAULT] +:: ie: CALL :file_env 'XYZ_DB_PASSWORD' 'example' +:: (will allow for "%XYZ_DB_PASSWORD_FILE%" to fill in the value of +:: "%XYZ_DB_PASSWORD%" from a file, especially for Docker's secrets feature) +:file_env +:: Reset all values +set cmdVar= +set fileVar= +set default= +set value= +:: Start the 'function' +set cmdVar=%~1 +set fileVar=%cmdVar%_FILE +set default=%~2 +:: No concept of AND in batch scripts +:: Instead we use nested if +if NOT [!%cmdVar%!] == [] ( + if NOT [!%fileVar%!] == [] ( + :: Instead of exiting, just use the environment value + echo Warning: both %cmdVar% and %fileVar% are set, %fileVar% will be ignored + ) +) +:: set as the default value +set value=%default% +if NOT [!%cmdVar%!] == [] ( + :: override with the environment value + set value=!%cmdVar%! +) +:: No concept of ELIF in batch scripts +:: we use nested if with opposite test +if [!%cmdVar%!] == [] ( + if NOT [!%fileVar%!] == [] ( + :: override with the file value + set /p value= NUL + +:: look specifically for PG_VERSION, as it is expected in the DB dir +if NOT exist "%PGDATA%\PG_VERSION" ( + + call :file_env POSTGRES_USER, postgres + call :file_env POSTGRES_PASSWORD + call :file_env POSTGRES_INITDB_ARGS + + if NOT [!POSTGRES_PASSWORD!] == [] ( + echo !POSTGRES_PASSWORD!> "C:\.pgpass" + set POSTGRES_INITDB_ARGS=!POSTGRES_INITDB_ARGS! --pwfile="C:\.pgpass" + ) + + if NOT [%POSTGRES_INITDB_WALDIR%] == [] ( + set POSTGRES_INITDB_ARGS=!POSTGRES_INITDB_ARGS! --waldir %POSTGRES_INITDB_WALDIR% + ) + + call initdb -U "!POSTGRES_USER!" -E UTF8 --no-locale -D "%PGDATA%" !POSTGRES_INITDB_ARGS! + if exist "C:\.pgpass" ( + call del "C:\.pgpass" + ) + + if NOT [!POSTGRES_PASSWORD!] == [] ( + set authMethod=md5 + echo authMethod: !authMethod! + ) else ( + echo **************************************************** + echo WARNING: No password has been set for the database. + echo This will allow anyone with access to the + echo Postgres port to access your database. In + echo Docker's default configuration, this is + echo effectively any other container on the same + echo system. + echo Use "-e POSTGRES_PASSWORD=password" to set + echo it in "docker run". + echo **************************************************** + set authMethod=trust + echo authMethod: !authMethod! + ) + echo.>> "%PGDATA%\pg_hba.conf" + echo host all all all !authMethod!>> "%PGDATA%\pg_hba.conf" + + :: internal start of server in order to allow set-up using psql-client + :: does not listen on external TCP/IP and waits until start finishes + call pg_ctl -U "!POSTGRES_USER!" -D "%PGDATA%" -w start + + call :file_env POSTGRES_DB !POSTGRES_USER! + + set psqlParam=^-v ON_ERROR_STOP=1 --username "!POSTGRES_USER!" --no-password + + :: Create a database with its name as the user name, override %PGDATABASE% + if NOT [!POSTGRES_DB!] == [postgres] ( + echo CREATE DATABASE :"db"; | call psql !psqlParam! --dbname postgres --set db="!POSTGRES_DB!" + ) + set psqlParam=^-v ON_ERROR_STOP=1 --username "!POSTGRES_USER!" --no-password --dbname "!POSTGRES_DB!" + + :: Execute any batch scripts for this new DB + for %%f in (C:\docker-entrypoint-initdb.d\*.cmd) do ( + echo cmd: running %%f + call "%%f" + ) + :: Execute any SQL scripts for this new DB + for %%f in (C:\docker-entrypoint-initdb.d\*.sql) do ( + echo psql: running %%f + call psql !psqlParam! -f "%%f" + ) + + pg_ctl -U "!POSTGRES_USER!" -D "%PGDATA%" -m fast -w stop + + echo PostgreSQL init process complete; ready for start up. +) + +:: start the database +call %* diff --git a/update.sh b/update.sh index 8664ff1fef..d18236ca4f 100755 --- a/update.sh +++ b/update.sh @@ -99,6 +99,40 @@ for version in "${versions[@]}"; do travisEnv="\n - VERSION=$version VARIANT=$variant$travisEnv" done + for variant in windows; do + if [ ! -d "$version/$variant" ]; then + continue + fi + + pgcVersion='3.3.7' + pgcRepository='https://s3.amazonaws.com/pgcentral' + + cp docker-entrypoint.cmd "$version/$variant/docker-entrypoint.cmd" + cp Dockerfile-windows.template "$version/$variant/Dockerfile" + + case "$version" in + 9.4) + pgcDbVersion='pg94' + ;; + 9.5) + pgcDbVersion='pg95' + ;; + 9.6) + pgcDbVersion='pg96' + ;; + 10) + pgcDbVersion='pg10' + ;; + 11) + pgcDbVersion='pg11' + ;; + esac + sed -e 's|%%PGC_VERSION%%|'"$pgcVersion"'|g' \ + -e 's|%%PGC_REPOSITORY%%|'"$pgcRepository"'|g' \ + -e 's|%%PGC_DB_VERSION%%|'"$pgcDbVersion"'|g' \ + "Dockerfile-$variant.template" > "$version/$variant/Dockerfile" + done + travisEnv="\n - VERSION=$version FORCE_DEB_BUILD=1$travisEnv" travisEnv="\n - VERSION=$version$travisEnv" done From 64dccb7d928f91fcf1cf8284732fc7795ac75ca9 Mon Sep 17 00:00:00 2001 From: Adam Farden Date: Thu, 23 May 2019 18:03:57 +0200 Subject: [PATCH 2/2] Update Windows containers to EnterpriseDB --- Dockerfile-windows.template | 88 ++++++++++++++++--------------------- update.sh | 29 +++++++----- 2 files changed, 56 insertions(+), 61 deletions(-) diff --git a/Dockerfile-windows.template b/Dockerfile-windows.template index 9d9726e4ad..1478ed030e 100644 --- a/Dockerfile-windows.template +++ b/Dockerfile-windows.template @@ -1,76 +1,62 @@ #### -#### Pretty Good Command Line Interface (PGCLI) +#### Download and prepare PostgreSQL for Windows #### -FROM microsoft/windowsservercore:1803 as prepare - -# Set the variables for PGCLI -ENV PGC_VER %%PGC_VERSION%% -ENV PGC_REPO %%PGC_REPOSITORY%% +FROM mcr.microsoft.com/windows/servercore:1809 as prepare ##### Use PowerShell for the installation SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] -### Required for PGCLI -ENV PYTHONIOENCODING UTF-8 - -### Download PGCLI -RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 ; \ - Invoke-WebRequest $('{0}/bigsql-pgc-{1}.zip' -f $env:PGC_REPO,$env:PGC_VER) -OutFile 'C:\\BigSQL.zip' ; \ - Expand-Archive 'C:\\BigSQL.zip' -DestinationPath 'C:\\' ; \ - Remove-Item -Path 'C:\\BigSQL.zip' - -### Update PGCLI -RUN Invoke-Expression -Command $('C:\\bigsql\\pgc set GLOBAL REPO {0}' -f$env:PGC_REPO) ; \ - Invoke-Expression -Command 'C:\\bigsql\\pgc update --silent' ; \ - Remove-Item -Path 'C:\\bigsql\\conf\\pgc.pid' - -#### -#### Download PostgreSQL -#### -FROM prepare as download - -### Set the PostgreSQL version we will install -### This is set here to allow us to reuse the abover layers -ENV PGC_DB %%PGC_DB_VERSION%% - -### Download PostgreSQL -RUN Invoke-Expression -Command $('C:\\bigsql\\pgc install --silent {0}' -f $env:PGC_DB) ; \ - Invoke-Expression -Command 'C:\\bigsql\\pgc clean' ; \ - Remove-Item -Path 'C:\\bigsql\\conf\\pgc.pid' +### Download EnterpriseDB and remove cruft +RUN $URL1 = '%%EDB_REPOSITORY%%/postgresql-%%EDB_VERSION%%-windows-x64-binaries.zip' ; \ + Invoke-WebRequest -Uri $URL1 -OutFile 'C:\\EnterpriseDB.zip' ; \ + Expand-Archive 'C:\\EnterpriseDB.zip' -DestinationPath 'C:\\' ; \ + Remove-Item -Path 'C:\\EnterpriseDB.zip' ; \ + Remove-Item -Recurse -Force –Path 'C:\\pgsql\\doc' ; \ + Remove-Item -Recurse -Force –Path 'C:\\pgsql\\include' ; \ + Remove-Item -Recurse -Force –Path 'C:\\pgsql\\pgAdmin*' ; \ + Remove-Item -Recurse -Force –Path 'C:\\pgsql\\StackBuilder' ### Make the sample config easier to munge (and "correct by default") -RUN $SAMPLE_FILE = $('C:\\bigsql\\{0}\\share\\postgresql\\postgresql.conf.sample' -f $env:PGC_DB) ; \ +RUN $SAMPLE_FILE = 'C:\\pgsql\\share\\postgresql.conf.sample' ; \ $SAMPLE_CONF = Get-Content $SAMPLE_FILE ; \ $SAMPLE_CONF = $SAMPLE_CONF -Replace '#listen_addresses = ''localhost''','listen_addresses = ''*''' ; \ $SAMPLE_CONF | Set-Content $SAMPLE_FILE +# Install Visual C++ Redistributable Package +RUN $URL2 = '%%EDB_VCREDIST%%' ; \ + Invoke-WebRequest -Uri $URL2 -OutFile 'C:\\vcredist.exe' ; \ + Start-Process 'C:\\vcredist.exe' -Wait \ + -ArgumentList @( \ + '/install', \ + '/passive', \ + '/norestart' \ + ) + +# Copy relevant DLLs to PostgreSQL +RUN if (Test-Path 'C:\\windows\\system32\\msvcp120.dll') { \ + Write-Host('Visual C++ 2013 Redistributable Package') ; \ + Copy-Item 'C:\\windows\\system32\\msvcp120.dll' -Destination 'C:\\pgsql\\bin\\msvcp120.dll' ; \ + Copy-Item 'C:\\windows\\system32\\msvcr120.dll' -Destination 'C:\\pgsql\\bin\\msvcr120.dll' ; \ + } else { \ + Write-Host('Visual C++ 2017 Redistributable Package') ; \ + Copy-Item 'C:\\windows\\system32\\vcruntime140.dll' -Destination 'C:\\pgsql\\bin\\vcruntime140.dll' ; \ + } + #### #### PostgreSQL on Windows Nano Server #### -FROM microsoft/nanoserver:1803 +FROM mcr.microsoft.com/windows/nanoserver:1809 RUN mkdir "C:\\docker-entrypoint-initdb.d" -#### Copy over the PGCLI -COPY --from=prepare "C:\\bigsql" "C:\\bigsql" - -### Set the PostgreSQL version we will install -### This is set here to allow us to reuse the abover layers -ENV PGC_DB %%PGC_DB_VERSION%% - -### Required for PGCLI -ENV PYTHONIOENCODING="UTF-8" \ - PYTHONPATH="C:\\bigsql\\${PGC_DB}\\python\\site-packages" \ - GDAL_DATA="C:\\bigsql\\${PGC_DB}\\share\\gdal" - -#### Copy over PostgeSQL -COPY --from=download "C:\\bigsql\\${PGC_DB}" "C:\\bigsql\\${PGC_DB}" +#### Copy over PostgreSQL +COPY --from=prepare "C:\\pgsql" "C:\\pgsql" #### In order to set system PATH, ContainerAdministrator must be used USER ContainerAdministrator -RUN setx /M PATH "C:\\bigsql\\%PGC_DB%\\bin;%PATH%" +RUN setx /M PATH "C:\\pgsql\\bin;%PATH%" USER ContainerUser -ENV PGDATA "C:\\bigsql\\data\\${PGC_DB}" +ENV PGDATA "C:\\pgsql\\data" RUN mkdir "%PGDATA%" COPY docker-entrypoint.cmd "C:\\" diff --git a/update.sh b/update.sh index d18236ca4f..adb7db8c00 100755 --- a/update.sh +++ b/update.sh @@ -104,32 +104,41 @@ for version in "${versions[@]}"; do continue fi - pgcVersion='3.3.7' - pgcRepository='https://s3.amazonaws.com/pgcentral' + edbRepository='https://get.enterprisedb.com/postgresql' cp docker-entrypoint.cmd "$version/$variant/docker-entrypoint.cmd" cp Dockerfile-windows.template "$version/$variant/Dockerfile" case "$version" in 9.4) - pgcDbVersion='pg94' + edbVersion='9.4.22-1' + # Visual C++ 2013 Redistributable Package + edbVCRedist='https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe' ;; 9.5) - pgcDbVersion='pg95' + edbVersion='9.5.17-1' + # Visual C++ 2013 Redistributable Package + edbVCRedist='https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe' ;; 9.6) - pgcDbVersion='pg96' + edbVersion='9.6.13-1' + # Visual C++ 2013 Redistributable Package + edbVCRedist='https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe' ;; 10) - pgcDbVersion='pg10' + edbVersion='10.8-1' + # Visual C++ 2013 Redistributable Package + edbVCRedist='https://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe' ;; 11) - pgcDbVersion='pg11' + edbVersion='11.3-1' + # Visual C++ 2017 Redistributable Package + edbVCRedist='https://download.visualstudio.microsoft.com/download/pr/11100230/15ccb3f02745c7b206ad10373cbca89b/VC_redist.x64.exe' ;; esac - sed -e 's|%%PGC_VERSION%%|'"$pgcVersion"'|g' \ - -e 's|%%PGC_REPOSITORY%%|'"$pgcRepository"'|g' \ - -e 's|%%PGC_DB_VERSION%%|'"$pgcDbVersion"'|g' \ + sed -e 's|%%EDB_VERSION%%|'"$edbVersion"'|g' \ + -e 's|%%EDB_REPOSITORY%%|'"$edbRepository"'|g' \ + -e 's|%%EDB_VCREDIST%%|'"$edbVCRedist"'|g' \ "Dockerfile-$variant.template" > "$version/$variant/Dockerfile" done