Deploying postgresql docker with ssl certificate and key with volumes Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Import SQL dump into PostgreSQL databaseUsing SSH keys inside docker containerWhat is the (best) way to manage permissions for Docker shared volumes?docker container ssl certificatesHow to mount host volumes into docker containers in Dockerfile during buildGetting Server Certificate/SSL in ServletSSL: how to get access to HTTPS in docker containerMounting pgsql volume in Dockerdockerized postgresql with volumesAdding ca-certificates to a Tomcat Docker container run with a designated user

Why do early math courses focus on the cross sections of a cone and not on other 3D objects?

How can I prevent/balance waiting and turtling as a response to cooldown mechanics

What does Turing mean by this statement?

Why is std::move not [[nodiscard]] in C++20?

In musical terms, what properties are varied by the human voice to produce different words / syllables?

What is the chair depicted in Cesare Maccari's 1889 painting "Cicerone denuncia Catilina"?

How does light 'choose' between wave and particle behaviour?

Flight departed from the gate 5 min before scheduled departure time. Refund options

A proverb that is used to imply that you have unexpectedly faced a big problem

Does the Mueller report show a conspiracy between Russia and the Trump Campaign?

GDP with Intermediate Production

Putting class ranking in CV, but against dept guidelines

Moving a wrapfig vertically to encroach partially on a subsection title

Test print coming out spongy

What are the main differences between Stargate SG-1 cuts?

Printing attributes of selection in ArcPy?

White walkers, cemeteries and wights

Are the endpoints of the domain of a function counted as critical points?

The Nth Gryphon Number

Resize vertical bars (absolute-value symbols)

Differences to CCompactSize and CVarInt

Is there hard evidence that the grant peer review system performs significantly better than random?

How many time has Arya actually used Needle?

What is the origin of 落第?



Deploying postgresql docker with ssl certificate and key with volumes



Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!Import SQL dump into PostgreSQL databaseUsing SSH keys inside docker containerWhat is the (best) way to manage permissions for Docker shared volumes?docker container ssl certificatesHow to mount host volumes into docker containers in Dockerfile during buildGetting Server Certificate/SSL in ServletSSL: how to get access to HTTPS in docker containerMounting pgsql volume in Dockerdockerized postgresql with volumesAdding ca-certificates to a Tomcat Docker container run with a designated user



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I'm trying to deploy a postgresql container. I'm trying to put ssl certificate and key in the container using volumes, but I can't get the permissions right. The files need to be readable by the container's postgres user, but also have limited permissions(600).



Is it possible using volumes, or will I have to override the Dockerfile for this?



Thanks.










share|improve this question




























    0















    I'm trying to deploy a postgresql container. I'm trying to put ssl certificate and key in the container using volumes, but I can't get the permissions right. The files need to be readable by the container's postgres user, but also have limited permissions(600).



    Is it possible using volumes, or will I have to override the Dockerfile for this?



    Thanks.










    share|improve this question
























      0












      0








      0








      I'm trying to deploy a postgresql container. I'm trying to put ssl certificate and key in the container using volumes, but I can't get the permissions right. The files need to be readable by the container's postgres user, but also have limited permissions(600).



      Is it possible using volumes, or will I have to override the Dockerfile for this?



      Thanks.










      share|improve this question














      I'm trying to deploy a postgresql container. I'm trying to put ssl certificate and key in the container using volumes, but I can't get the permissions right. The files need to be readable by the container's postgres user, but also have limited permissions(600).



      Is it possible using volumes, or will I have to override the Dockerfile for this?



      Thanks.







      postgresql docker ssl permissions






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 8 at 23:04









      Charles LangloisCharles Langlois

      545413




      545413






















          1 Answer
          1






          active

          oldest

          votes


















          1














          It is possible to mount the key and certificate into the postgres container, and for postgres to use them from there. But you will have to face the issue with the owner and permissions of the server.key.



          From the PostgreSQL Documentation on this subject:




          On Unix systems, the permissions on server.key must disallow any
          access to world or group; achieve this by the command chmod 0600
          server.key. Alternatively, the file can be owned by root and have
          group read access (that is, 0640 permissions).




          This means that you have to:



          1. Set the owner of the server.key file to either root or postgres.

          2. Depending on the owner of the server.key file, you will have to set respectively 600 or 640 permissions on it. (Update: It is implied here, that the group owner of the file, is a group that contains the postgres user, like the default postgresgroup)

          If you are working from a Windows host, you will have a hard time with this. Because the permissions on any file in the volume that you map into the container will be -rwxr-xr-x (755), and the owner will be root. And you will not be able to change this as long as the file is mounted from your windows volumes. If you try using chmod on the file, it will just fail silently.



          If you on the other hand are on a linux host, this can be done with minimum effort. The permissions from the host system will be preserved into the image. And the ownership will too, litterally. By this I mean, that the numerical owner and group owner of the server.key will be preserved when they are volume mapped into the container. Between the host and the container, they share the linux ACL, so they are just observing the same properties of the files. (Owner, group owner, permissions). So if your local linux user on the host machine has UID:GID 1000:1000, and you create the server.key file, then the UID:GID of the file will also be set to 1000:1000. If you then map the file into the container, and observe it from inside - it will also just see 1000:1000. This means, that we can control the UID:GID from both inside and outside the container, when mapped from a linux host.



          Note. There does not have to be a user with the UID that you assign as owner on a file, it is allowed to set non existent UID:GID owners of files.



          In the postgres alpine derivative image, the postgres user/group has UID:GID 70:70. On the debian derivative the postgres UID:GID is 999:999. And not supprising, root has 0:0 on both of them.



          This means either have to:



          1. Change the UID:GID of the file server.key after we start the container, when the volume is already mounted.

          2. Change the UID:GID of the file server.key before we start the container

          Since setting this after the container starts, would imply tampering with the startup scripting of the postgres image - let's opt to set them before we start the container. In the local filesystem where you are mounting them from.



          Setting 600 permissions and postgres as owner of the server.key



          In case you are going with the alpine derivative, you need to change the owner/group to 70:70. If you are using the debian derivative, then 999:999.



          There may not be a user on your host with for example UID: 70, but that is not a problem.



          Example:



          chown 70:70 server.key # 70:70 for alpine, 999:999 for debian
          chmod 600 server.key


          Setting 640 permissions and root as owner of the server.key



          This example is also for the alpine image



          Example:



          chown 0:70 server.key
          chmod 640 server.key


          At this point you are good to go. You just need to map the key and certificate into the container, and start postgres like always.



          Solution (linux/unix/macOS)



          I will include a script snippet here, that will do all of this for you for the alpine derivative. This example will set the root owner of the server.key and the postgres group owner.



          # generate the server.key and server.crt
          openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req
          openssl rsa -in privkey.pem -passin pass:abcd -out server.key
          openssl req -x509 -in server.req -text -key server.key -out server.crt

          # set postgres (alpine) user as owner of the server.key and permissions to 600
          chown 0:70 server.key
          chmod 640 server.key

          # start a postgres docker container, mapping the .key and .crt into the image.
          docker run -d --name postgres
          -v "$PWD/server.crt:/var/lib/postgresql/server.crt:ro"
          -v "$PWD/server.key:/var/lib/postgresql/server.key:ro"
          postgres:11-alpine
          -c ssl=on
          -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key


          I hope this clears things up?



          Source of the key generating key and certificate is this gist.



          Building the image yourself (Windows solution)



          I will include a small guide to how you can build an image yourself, so that you can have a postgres database container with ssl. This will work on Windows aswell.



          Here's the Dockerfile that will do it for you:



          Dockerfile



          FROM postgres:11-alpine

          # On Windows root will own the files, and they will have permissions 755
          COPY server.key /var/lib/postgresql/server.key
          COPY server.crt /var/lib/postgresql/server.crt

          # update the privileges on the .key, no need to touch the .crt
          RUN chmod 600 /var/lib/postgresql/server.key
          RUN chown postgres:postgres /var/lib/postgresql/server.key


          Build the image with:



          docker build -t mypg:01 .


          And run with:



          docker run -d --name postgres mypg:01 
          -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key





          share|improve this answer

























          • Thanks, I'm using linux both for local development and server deployment. I'll try going the root route. I don't feel comfortable relying on the current value of uid/gid of the postgres users in the container.

            – Charles Langlois
            Mar 10 at 3:04











          • I can't get it to work using root as owner and 0640 as permissions. The database fails with ` FATAL: could not load private key file "/etc/postgresql/server.key": Permission denied`.

            – Charles Langlois
            Mar 11 at 14:13











          • Aww... looks like I jumped the gun on the "setting root owner of the server.key". Apparently, the postgres user has to be in the group that is assigned the group owner of the file. So that root:root is not permitted on the file. That means that you have to use user 70 for doing this (for alpine, 999 for debian). I updated the solution in my answer to reflect this. I hope you can accept that as the answer here? Since it still is possible to do this. Best regards.

            – Andreas Lorenzen
            Mar 11 at 20:34











          • I'll accept your answer, but I think I'll prefer to use a custom Dockerfile which COPY --chown and RUN chmod 600 certificate files. Thanks!

            – Charles Langlois
            Mar 12 at 14:25











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55072221%2fdeploying-postgresql-docker-with-ssl-certificate-and-key-with-volumes%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          It is possible to mount the key and certificate into the postgres container, and for postgres to use them from there. But you will have to face the issue with the owner and permissions of the server.key.



          From the PostgreSQL Documentation on this subject:




          On Unix systems, the permissions on server.key must disallow any
          access to world or group; achieve this by the command chmod 0600
          server.key. Alternatively, the file can be owned by root and have
          group read access (that is, 0640 permissions).




          This means that you have to:



          1. Set the owner of the server.key file to either root or postgres.

          2. Depending on the owner of the server.key file, you will have to set respectively 600 or 640 permissions on it. (Update: It is implied here, that the group owner of the file, is a group that contains the postgres user, like the default postgresgroup)

          If you are working from a Windows host, you will have a hard time with this. Because the permissions on any file in the volume that you map into the container will be -rwxr-xr-x (755), and the owner will be root. And you will not be able to change this as long as the file is mounted from your windows volumes. If you try using chmod on the file, it will just fail silently.



          If you on the other hand are on a linux host, this can be done with minimum effort. The permissions from the host system will be preserved into the image. And the ownership will too, litterally. By this I mean, that the numerical owner and group owner of the server.key will be preserved when they are volume mapped into the container. Between the host and the container, they share the linux ACL, so they are just observing the same properties of the files. (Owner, group owner, permissions). So if your local linux user on the host machine has UID:GID 1000:1000, and you create the server.key file, then the UID:GID of the file will also be set to 1000:1000. If you then map the file into the container, and observe it from inside - it will also just see 1000:1000. This means, that we can control the UID:GID from both inside and outside the container, when mapped from a linux host.



          Note. There does not have to be a user with the UID that you assign as owner on a file, it is allowed to set non existent UID:GID owners of files.



          In the postgres alpine derivative image, the postgres user/group has UID:GID 70:70. On the debian derivative the postgres UID:GID is 999:999. And not supprising, root has 0:0 on both of them.



          This means either have to:



          1. Change the UID:GID of the file server.key after we start the container, when the volume is already mounted.

          2. Change the UID:GID of the file server.key before we start the container

          Since setting this after the container starts, would imply tampering with the startup scripting of the postgres image - let's opt to set them before we start the container. In the local filesystem where you are mounting them from.



          Setting 600 permissions and postgres as owner of the server.key



          In case you are going with the alpine derivative, you need to change the owner/group to 70:70. If you are using the debian derivative, then 999:999.



          There may not be a user on your host with for example UID: 70, but that is not a problem.



          Example:



          chown 70:70 server.key # 70:70 for alpine, 999:999 for debian
          chmod 600 server.key


          Setting 640 permissions and root as owner of the server.key



          This example is also for the alpine image



          Example:



          chown 0:70 server.key
          chmod 640 server.key


          At this point you are good to go. You just need to map the key and certificate into the container, and start postgres like always.



          Solution (linux/unix/macOS)



          I will include a script snippet here, that will do all of this for you for the alpine derivative. This example will set the root owner of the server.key and the postgres group owner.



          # generate the server.key and server.crt
          openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req
          openssl rsa -in privkey.pem -passin pass:abcd -out server.key
          openssl req -x509 -in server.req -text -key server.key -out server.crt

          # set postgres (alpine) user as owner of the server.key and permissions to 600
          chown 0:70 server.key
          chmod 640 server.key

          # start a postgres docker container, mapping the .key and .crt into the image.
          docker run -d --name postgres
          -v "$PWD/server.crt:/var/lib/postgresql/server.crt:ro"
          -v "$PWD/server.key:/var/lib/postgresql/server.key:ro"
          postgres:11-alpine
          -c ssl=on
          -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key


          I hope this clears things up?



          Source of the key generating key and certificate is this gist.



          Building the image yourself (Windows solution)



          I will include a small guide to how you can build an image yourself, so that you can have a postgres database container with ssl. This will work on Windows aswell.



          Here's the Dockerfile that will do it for you:



          Dockerfile



          FROM postgres:11-alpine

          # On Windows root will own the files, and they will have permissions 755
          COPY server.key /var/lib/postgresql/server.key
          COPY server.crt /var/lib/postgresql/server.crt

          # update the privileges on the .key, no need to touch the .crt
          RUN chmod 600 /var/lib/postgresql/server.key
          RUN chown postgres:postgres /var/lib/postgresql/server.key


          Build the image with:



          docker build -t mypg:01 .


          And run with:



          docker run -d --name postgres mypg:01 
          -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key





          share|improve this answer

























          • Thanks, I'm using linux both for local development and server deployment. I'll try going the root route. I don't feel comfortable relying on the current value of uid/gid of the postgres users in the container.

            – Charles Langlois
            Mar 10 at 3:04











          • I can't get it to work using root as owner and 0640 as permissions. The database fails with ` FATAL: could not load private key file "/etc/postgresql/server.key": Permission denied`.

            – Charles Langlois
            Mar 11 at 14:13











          • Aww... looks like I jumped the gun on the "setting root owner of the server.key". Apparently, the postgres user has to be in the group that is assigned the group owner of the file. So that root:root is not permitted on the file. That means that you have to use user 70 for doing this (for alpine, 999 for debian). I updated the solution in my answer to reflect this. I hope you can accept that as the answer here? Since it still is possible to do this. Best regards.

            – Andreas Lorenzen
            Mar 11 at 20:34











          • I'll accept your answer, but I think I'll prefer to use a custom Dockerfile which COPY --chown and RUN chmod 600 certificate files. Thanks!

            – Charles Langlois
            Mar 12 at 14:25















          1














          It is possible to mount the key and certificate into the postgres container, and for postgres to use them from there. But you will have to face the issue with the owner and permissions of the server.key.



          From the PostgreSQL Documentation on this subject:




          On Unix systems, the permissions on server.key must disallow any
          access to world or group; achieve this by the command chmod 0600
          server.key. Alternatively, the file can be owned by root and have
          group read access (that is, 0640 permissions).




          This means that you have to:



          1. Set the owner of the server.key file to either root or postgres.

          2. Depending on the owner of the server.key file, you will have to set respectively 600 or 640 permissions on it. (Update: It is implied here, that the group owner of the file, is a group that contains the postgres user, like the default postgresgroup)

          If you are working from a Windows host, you will have a hard time with this. Because the permissions on any file in the volume that you map into the container will be -rwxr-xr-x (755), and the owner will be root. And you will not be able to change this as long as the file is mounted from your windows volumes. If you try using chmod on the file, it will just fail silently.



          If you on the other hand are on a linux host, this can be done with minimum effort. The permissions from the host system will be preserved into the image. And the ownership will too, litterally. By this I mean, that the numerical owner and group owner of the server.key will be preserved when they are volume mapped into the container. Between the host and the container, they share the linux ACL, so they are just observing the same properties of the files. (Owner, group owner, permissions). So if your local linux user on the host machine has UID:GID 1000:1000, and you create the server.key file, then the UID:GID of the file will also be set to 1000:1000. If you then map the file into the container, and observe it from inside - it will also just see 1000:1000. This means, that we can control the UID:GID from both inside and outside the container, when mapped from a linux host.



          Note. There does not have to be a user with the UID that you assign as owner on a file, it is allowed to set non existent UID:GID owners of files.



          In the postgres alpine derivative image, the postgres user/group has UID:GID 70:70. On the debian derivative the postgres UID:GID is 999:999. And not supprising, root has 0:0 on both of them.



          This means either have to:



          1. Change the UID:GID of the file server.key after we start the container, when the volume is already mounted.

          2. Change the UID:GID of the file server.key before we start the container

          Since setting this after the container starts, would imply tampering with the startup scripting of the postgres image - let's opt to set them before we start the container. In the local filesystem where you are mounting them from.



          Setting 600 permissions and postgres as owner of the server.key



          In case you are going with the alpine derivative, you need to change the owner/group to 70:70. If you are using the debian derivative, then 999:999.



          There may not be a user on your host with for example UID: 70, but that is not a problem.



          Example:



          chown 70:70 server.key # 70:70 for alpine, 999:999 for debian
          chmod 600 server.key


          Setting 640 permissions and root as owner of the server.key



          This example is also for the alpine image



          Example:



          chown 0:70 server.key
          chmod 640 server.key


          At this point you are good to go. You just need to map the key and certificate into the container, and start postgres like always.



          Solution (linux/unix/macOS)



          I will include a script snippet here, that will do all of this for you for the alpine derivative. This example will set the root owner of the server.key and the postgres group owner.



          # generate the server.key and server.crt
          openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req
          openssl rsa -in privkey.pem -passin pass:abcd -out server.key
          openssl req -x509 -in server.req -text -key server.key -out server.crt

          # set postgres (alpine) user as owner of the server.key and permissions to 600
          chown 0:70 server.key
          chmod 640 server.key

          # start a postgres docker container, mapping the .key and .crt into the image.
          docker run -d --name postgres
          -v "$PWD/server.crt:/var/lib/postgresql/server.crt:ro"
          -v "$PWD/server.key:/var/lib/postgresql/server.key:ro"
          postgres:11-alpine
          -c ssl=on
          -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key


          I hope this clears things up?



          Source of the key generating key and certificate is this gist.



          Building the image yourself (Windows solution)



          I will include a small guide to how you can build an image yourself, so that you can have a postgres database container with ssl. This will work on Windows aswell.



          Here's the Dockerfile that will do it for you:



          Dockerfile



          FROM postgres:11-alpine

          # On Windows root will own the files, and they will have permissions 755
          COPY server.key /var/lib/postgresql/server.key
          COPY server.crt /var/lib/postgresql/server.crt

          # update the privileges on the .key, no need to touch the .crt
          RUN chmod 600 /var/lib/postgresql/server.key
          RUN chown postgres:postgres /var/lib/postgresql/server.key


          Build the image with:



          docker build -t mypg:01 .


          And run with:



          docker run -d --name postgres mypg:01 
          -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key





          share|improve this answer

























          • Thanks, I'm using linux both for local development and server deployment. I'll try going the root route. I don't feel comfortable relying on the current value of uid/gid of the postgres users in the container.

            – Charles Langlois
            Mar 10 at 3:04











          • I can't get it to work using root as owner and 0640 as permissions. The database fails with ` FATAL: could not load private key file "/etc/postgresql/server.key": Permission denied`.

            – Charles Langlois
            Mar 11 at 14:13











          • Aww... looks like I jumped the gun on the "setting root owner of the server.key". Apparently, the postgres user has to be in the group that is assigned the group owner of the file. So that root:root is not permitted on the file. That means that you have to use user 70 for doing this (for alpine, 999 for debian). I updated the solution in my answer to reflect this. I hope you can accept that as the answer here? Since it still is possible to do this. Best regards.

            – Andreas Lorenzen
            Mar 11 at 20:34











          • I'll accept your answer, but I think I'll prefer to use a custom Dockerfile which COPY --chown and RUN chmod 600 certificate files. Thanks!

            – Charles Langlois
            Mar 12 at 14:25













          1












          1








          1







          It is possible to mount the key and certificate into the postgres container, and for postgres to use them from there. But you will have to face the issue with the owner and permissions of the server.key.



          From the PostgreSQL Documentation on this subject:




          On Unix systems, the permissions on server.key must disallow any
          access to world or group; achieve this by the command chmod 0600
          server.key. Alternatively, the file can be owned by root and have
          group read access (that is, 0640 permissions).




          This means that you have to:



          1. Set the owner of the server.key file to either root or postgres.

          2. Depending on the owner of the server.key file, you will have to set respectively 600 or 640 permissions on it. (Update: It is implied here, that the group owner of the file, is a group that contains the postgres user, like the default postgresgroup)

          If you are working from a Windows host, you will have a hard time with this. Because the permissions on any file in the volume that you map into the container will be -rwxr-xr-x (755), and the owner will be root. And you will not be able to change this as long as the file is mounted from your windows volumes. If you try using chmod on the file, it will just fail silently.



          If you on the other hand are on a linux host, this can be done with minimum effort. The permissions from the host system will be preserved into the image. And the ownership will too, litterally. By this I mean, that the numerical owner and group owner of the server.key will be preserved when they are volume mapped into the container. Between the host and the container, they share the linux ACL, so they are just observing the same properties of the files. (Owner, group owner, permissions). So if your local linux user on the host machine has UID:GID 1000:1000, and you create the server.key file, then the UID:GID of the file will also be set to 1000:1000. If you then map the file into the container, and observe it from inside - it will also just see 1000:1000. This means, that we can control the UID:GID from both inside and outside the container, when mapped from a linux host.



          Note. There does not have to be a user with the UID that you assign as owner on a file, it is allowed to set non existent UID:GID owners of files.



          In the postgres alpine derivative image, the postgres user/group has UID:GID 70:70. On the debian derivative the postgres UID:GID is 999:999. And not supprising, root has 0:0 on both of them.



          This means either have to:



          1. Change the UID:GID of the file server.key after we start the container, when the volume is already mounted.

          2. Change the UID:GID of the file server.key before we start the container

          Since setting this after the container starts, would imply tampering with the startup scripting of the postgres image - let's opt to set them before we start the container. In the local filesystem where you are mounting them from.



          Setting 600 permissions and postgres as owner of the server.key



          In case you are going with the alpine derivative, you need to change the owner/group to 70:70. If you are using the debian derivative, then 999:999.



          There may not be a user on your host with for example UID: 70, but that is not a problem.



          Example:



          chown 70:70 server.key # 70:70 for alpine, 999:999 for debian
          chmod 600 server.key


          Setting 640 permissions and root as owner of the server.key



          This example is also for the alpine image



          Example:



          chown 0:70 server.key
          chmod 640 server.key


          At this point you are good to go. You just need to map the key and certificate into the container, and start postgres like always.



          Solution (linux/unix/macOS)



          I will include a script snippet here, that will do all of this for you for the alpine derivative. This example will set the root owner of the server.key and the postgres group owner.



          # generate the server.key and server.crt
          openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req
          openssl rsa -in privkey.pem -passin pass:abcd -out server.key
          openssl req -x509 -in server.req -text -key server.key -out server.crt

          # set postgres (alpine) user as owner of the server.key and permissions to 600
          chown 0:70 server.key
          chmod 640 server.key

          # start a postgres docker container, mapping the .key and .crt into the image.
          docker run -d --name postgres
          -v "$PWD/server.crt:/var/lib/postgresql/server.crt:ro"
          -v "$PWD/server.key:/var/lib/postgresql/server.key:ro"
          postgres:11-alpine
          -c ssl=on
          -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key


          I hope this clears things up?



          Source of the key generating key and certificate is this gist.



          Building the image yourself (Windows solution)



          I will include a small guide to how you can build an image yourself, so that you can have a postgres database container with ssl. This will work on Windows aswell.



          Here's the Dockerfile that will do it for you:



          Dockerfile



          FROM postgres:11-alpine

          # On Windows root will own the files, and they will have permissions 755
          COPY server.key /var/lib/postgresql/server.key
          COPY server.crt /var/lib/postgresql/server.crt

          # update the privileges on the .key, no need to touch the .crt
          RUN chmod 600 /var/lib/postgresql/server.key
          RUN chown postgres:postgres /var/lib/postgresql/server.key


          Build the image with:



          docker build -t mypg:01 .


          And run with:



          docker run -d --name postgres mypg:01 
          -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key





          share|improve this answer















          It is possible to mount the key and certificate into the postgres container, and for postgres to use them from there. But you will have to face the issue with the owner and permissions of the server.key.



          From the PostgreSQL Documentation on this subject:




          On Unix systems, the permissions on server.key must disallow any
          access to world or group; achieve this by the command chmod 0600
          server.key. Alternatively, the file can be owned by root and have
          group read access (that is, 0640 permissions).




          This means that you have to:



          1. Set the owner of the server.key file to either root or postgres.

          2. Depending on the owner of the server.key file, you will have to set respectively 600 or 640 permissions on it. (Update: It is implied here, that the group owner of the file, is a group that contains the postgres user, like the default postgresgroup)

          If you are working from a Windows host, you will have a hard time with this. Because the permissions on any file in the volume that you map into the container will be -rwxr-xr-x (755), and the owner will be root. And you will not be able to change this as long as the file is mounted from your windows volumes. If you try using chmod on the file, it will just fail silently.



          If you on the other hand are on a linux host, this can be done with minimum effort. The permissions from the host system will be preserved into the image. And the ownership will too, litterally. By this I mean, that the numerical owner and group owner of the server.key will be preserved when they are volume mapped into the container. Between the host and the container, they share the linux ACL, so they are just observing the same properties of the files. (Owner, group owner, permissions). So if your local linux user on the host machine has UID:GID 1000:1000, and you create the server.key file, then the UID:GID of the file will also be set to 1000:1000. If you then map the file into the container, and observe it from inside - it will also just see 1000:1000. This means, that we can control the UID:GID from both inside and outside the container, when mapped from a linux host.



          Note. There does not have to be a user with the UID that you assign as owner on a file, it is allowed to set non existent UID:GID owners of files.



          In the postgres alpine derivative image, the postgres user/group has UID:GID 70:70. On the debian derivative the postgres UID:GID is 999:999. And not supprising, root has 0:0 on both of them.



          This means either have to:



          1. Change the UID:GID of the file server.key after we start the container, when the volume is already mounted.

          2. Change the UID:GID of the file server.key before we start the container

          Since setting this after the container starts, would imply tampering with the startup scripting of the postgres image - let's opt to set them before we start the container. In the local filesystem where you are mounting them from.



          Setting 600 permissions and postgres as owner of the server.key



          In case you are going with the alpine derivative, you need to change the owner/group to 70:70. If you are using the debian derivative, then 999:999.



          There may not be a user on your host with for example UID: 70, but that is not a problem.



          Example:



          chown 70:70 server.key # 70:70 for alpine, 999:999 for debian
          chmod 600 server.key


          Setting 640 permissions and root as owner of the server.key



          This example is also for the alpine image



          Example:



          chown 0:70 server.key
          chmod 640 server.key


          At this point you are good to go. You just need to map the key and certificate into the container, and start postgres like always.



          Solution (linux/unix/macOS)



          I will include a script snippet here, that will do all of this for you for the alpine derivative. This example will set the root owner of the server.key and the postgres group owner.



          # generate the server.key and server.crt
          openssl req -new -text -passout pass:abcd -subj /CN=localhost -out server.req
          openssl rsa -in privkey.pem -passin pass:abcd -out server.key
          openssl req -x509 -in server.req -text -key server.key -out server.crt

          # set postgres (alpine) user as owner of the server.key and permissions to 600
          chown 0:70 server.key
          chmod 640 server.key

          # start a postgres docker container, mapping the .key and .crt into the image.
          docker run -d --name postgres
          -v "$PWD/server.crt:/var/lib/postgresql/server.crt:ro"
          -v "$PWD/server.key:/var/lib/postgresql/server.key:ro"
          postgres:11-alpine
          -c ssl=on
          -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key


          I hope this clears things up?



          Source of the key generating key and certificate is this gist.



          Building the image yourself (Windows solution)



          I will include a small guide to how you can build an image yourself, so that you can have a postgres database container with ssl. This will work on Windows aswell.



          Here's the Dockerfile that will do it for you:



          Dockerfile



          FROM postgres:11-alpine

          # On Windows root will own the files, and they will have permissions 755
          COPY server.key /var/lib/postgresql/server.key
          COPY server.crt /var/lib/postgresql/server.crt

          # update the privileges on the .key, no need to touch the .crt
          RUN chmod 600 /var/lib/postgresql/server.key
          RUN chown postgres:postgres /var/lib/postgresql/server.key


          Build the image with:



          docker build -t mypg:01 .


          And run with:



          docker run -d --name postgres mypg:01 
          -c ssl=on -c ssl_cert_file=/var/lib/postgresql/server.crt
          -c ssl_key_file=/var/lib/postgresql/server.key






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Mar 11 at 20:31

























          answered Mar 9 at 0:44









          Andreas LorenzenAndreas Lorenzen

          1,076412




          1,076412












          • Thanks, I'm using linux both for local development and server deployment. I'll try going the root route. I don't feel comfortable relying on the current value of uid/gid of the postgres users in the container.

            – Charles Langlois
            Mar 10 at 3:04











          • I can't get it to work using root as owner and 0640 as permissions. The database fails with ` FATAL: could not load private key file "/etc/postgresql/server.key": Permission denied`.

            – Charles Langlois
            Mar 11 at 14:13











          • Aww... looks like I jumped the gun on the "setting root owner of the server.key". Apparently, the postgres user has to be in the group that is assigned the group owner of the file. So that root:root is not permitted on the file. That means that you have to use user 70 for doing this (for alpine, 999 for debian). I updated the solution in my answer to reflect this. I hope you can accept that as the answer here? Since it still is possible to do this. Best regards.

            – Andreas Lorenzen
            Mar 11 at 20:34











          • I'll accept your answer, but I think I'll prefer to use a custom Dockerfile which COPY --chown and RUN chmod 600 certificate files. Thanks!

            – Charles Langlois
            Mar 12 at 14:25

















          • Thanks, I'm using linux both for local development and server deployment. I'll try going the root route. I don't feel comfortable relying on the current value of uid/gid of the postgres users in the container.

            – Charles Langlois
            Mar 10 at 3:04











          • I can't get it to work using root as owner and 0640 as permissions. The database fails with ` FATAL: could not load private key file "/etc/postgresql/server.key": Permission denied`.

            – Charles Langlois
            Mar 11 at 14:13











          • Aww... looks like I jumped the gun on the "setting root owner of the server.key". Apparently, the postgres user has to be in the group that is assigned the group owner of the file. So that root:root is not permitted on the file. That means that you have to use user 70 for doing this (for alpine, 999 for debian). I updated the solution in my answer to reflect this. I hope you can accept that as the answer here? Since it still is possible to do this. Best regards.

            – Andreas Lorenzen
            Mar 11 at 20:34











          • I'll accept your answer, but I think I'll prefer to use a custom Dockerfile which COPY --chown and RUN chmod 600 certificate files. Thanks!

            – Charles Langlois
            Mar 12 at 14:25
















          Thanks, I'm using linux both for local development and server deployment. I'll try going the root route. I don't feel comfortable relying on the current value of uid/gid of the postgres users in the container.

          – Charles Langlois
          Mar 10 at 3:04





          Thanks, I'm using linux both for local development and server deployment. I'll try going the root route. I don't feel comfortable relying on the current value of uid/gid of the postgres users in the container.

          – Charles Langlois
          Mar 10 at 3:04













          I can't get it to work using root as owner and 0640 as permissions. The database fails with ` FATAL: could not load private key file "/etc/postgresql/server.key": Permission denied`.

          – Charles Langlois
          Mar 11 at 14:13





          I can't get it to work using root as owner and 0640 as permissions. The database fails with ` FATAL: could not load private key file "/etc/postgresql/server.key": Permission denied`.

          – Charles Langlois
          Mar 11 at 14:13













          Aww... looks like I jumped the gun on the "setting root owner of the server.key". Apparently, the postgres user has to be in the group that is assigned the group owner of the file. So that root:root is not permitted on the file. That means that you have to use user 70 for doing this (for alpine, 999 for debian). I updated the solution in my answer to reflect this. I hope you can accept that as the answer here? Since it still is possible to do this. Best regards.

          – Andreas Lorenzen
          Mar 11 at 20:34





          Aww... looks like I jumped the gun on the "setting root owner of the server.key". Apparently, the postgres user has to be in the group that is assigned the group owner of the file. So that root:root is not permitted on the file. That means that you have to use user 70 for doing this (for alpine, 999 for debian). I updated the solution in my answer to reflect this. I hope you can accept that as the answer here? Since it still is possible to do this. Best regards.

          – Andreas Lorenzen
          Mar 11 at 20:34













          I'll accept your answer, but I think I'll prefer to use a custom Dockerfile which COPY --chown and RUN chmod 600 certificate files. Thanks!

          – Charles Langlois
          Mar 12 at 14:25





          I'll accept your answer, but I think I'll prefer to use a custom Dockerfile which COPY --chown and RUN chmod 600 certificate files. Thanks!

          – Charles Langlois
          Mar 12 at 14:25



















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55072221%2fdeploying-postgresql-docker-with-ssl-certificate-and-key-with-volumes%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Save data to MySQL database using ExtJS and PHP [closed]2019 Community Moderator ElectionHow can I prevent SQL injection in PHP?Which MySQL data type to use for storing boolean valuesPHP: Delete an element from an arrayHow do I connect to a MySQL Database in Python?Should I use the datetime or timestamp data type in MySQL?How to get a list of MySQL user accountsHow Do You Parse and Process HTML/XML in PHP?Reference — What does this symbol mean in PHP?How does PHP 'foreach' actually work?Why shouldn't I use mysql_* functions in PHP?

          Compiling GNU Global with universal-ctags support Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!Tags for Emacs: Relationship between etags, ebrowse, cscope, GNU Global and exuberant ctagsVim and Ctags tips and trickscscope or ctags why choose one over the other?scons and ctagsctags cannot open option file “.ctags”Adding tag scopes in universal-ctagsShould I use Universal-ctags?Universal ctags on WindowsHow do I install GNU Global with universal ctags support using Homebrew?Universal ctags with emacsHow to highlight ctags generated by Universal Ctags in Vim?

          Add ONERROR event to image from jsp tldHow to add an image to a JPanel?Saving image from PHP URLHTML img scalingCheck if an image is loaded (no errors) with jQueryHow to force an <img> to take up width, even if the image is not loadedHow do I populate hidden form field with a value set in Spring ControllerStyling Raw elements Generated from JSP tagds with Jquery MobileLimit resizing of images with explicitly set width and height attributeserror TLD use in a jsp fileJsp tld files cannot be resolved