Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove sensitive information from environment variables in postgres docker container

I want to make a postgres database image but don't want to expose password and username which are stored as environment variable when produced using docker-compose.yml file. Basically, I don't want anyone to exec into the container and find out the variables.

One way is to use docker-secrets, but I don't want to to use docker swarm because my containers would be running on a single host.

my docker-compose file -

    version: "3"
    services:
       db:
         image: postgres:10.0-alpine
      environment:
         POSTGRES_USER: 'user'
         POSTGRES_PASSWORD: 'pass'
         POSTGRES_DB: 'db'

Things I have tried -

1) unset the environment variable at the end of entrypoint-entrypoint.sh

        for f in /docker-entrypoint-initdb.d/*; do
            case "$f" in
            *.sh)     echo "$0: running $f"; . "$f" ;;
            *.sql)    echo "$0: running $f"; "${psql[@]}" -f "$f"; echo ;;
            *.sql.gz) echo "$0: running $f"; gunzip -c "$f" | "${psql[@]}"; echo ;;
            *)        echo "$0: ignoring $f" ;;
            esac
            echo
        done
        unset POSTGRES_USER

nothing happened though. :(

2) init.sql inside docker-entrypoint-initdb.d, to create db, user and pass without using env. I shared the volume, as -

```
   volumes:
       - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
```

and, on my host, inside docker-entrypoint-initdb.d, I saved an init.sql as -

CREATE DATABASE docker_db;CREATE USER docker_user with encrypted password 'pass';GRANT ALL PRIVILEGES ON DATABASE docker_db TO docker_user;

I moved inside the running container and this file was there but, no user or database was created as mentioned in the file.

I have been stuck on this for past two days, any help is much appreciated.

like image 677
Shirish Bajpai Avatar asked Sep 18 '19 07:09

Shirish Bajpai


2 Answers

use args without values to build the image in your Dockerfile:

ARG PASSWORD 

and build it using

export PASSWORD="MYPASS" && docker build ...

in this way the ARG is not there when running the container

here is a complete example:

dockerfile:

FROM postgres:10.0-alpine

ARG my_user
ARG my_pass

Compose:

version: "3"
services:
       db:
         build:
           context: .
           args:
            - my_user
            - my_pass       
         environment:
           - POSTGRES_USER=${my_user}
           - POSTGRES_PASSWORD=${my_pass}
           - POSTGRES_DB=db

run it:

export my_user=test && export my_pass=test1cd && docker-compose up -d --build

now if you login to the container and try echo $my_pass you get an empty string

result :

docker exec -ti 3b631d907153 bash

bash-4.3# psql -U test db
psql (10.0)
Type "help" for help.

db=#
like image 177
LinPy Avatar answered Oct 06 '22 15:10

LinPy


update

Before using docker secrets in Compose, take into consideration this SO question and that github answer.


You can use docker secrets in Compose.

As stated in the relevant section of the docker postgresql docs:

As an alternative to passing sensitive information via environment variables, _FILE may be appended to some of the previously listed environment variables, causing the initialization script to load the values for those variables from files present in the container. In particular, this can be used to load passwords from Docker secrets stored in /run/secrets/<secret_name> files.

Therefore your compose file can read:

version: "3"
services:
  db:
    image: postgres:10.0-alpine
  environment:
    POSTGRES_USER_FILE: /run/secrets/user
    POSTGRES_PASSWORD_FILE: /run/secrets/pass
    POSTGRES_DB_FILE: /run/secrets/db
  secrets:
    - user
    - pass
    - db

secrets:
  user:
    file: user.txt
  pass:
    file: pass.txt
  db: 
    file: db.txt
like image 36
raratiru Avatar answered Oct 06 '22 16:10

raratiru