0

I have a docker container, and -e DEV_ENV is defined with the docker run command, and this the unit file I built to run a script...

[Unit]
Description=Script that creates environement users and databases.
After=postgresql.service

[Service]
Type=simple
User=root
Group=root
ExecStart=/usr/bin/su - postgres -c 'export DEV_ENV=$0; /usr/local/bin/psql.sh' "$DEV_ENV"
TimeoutStartSec=100

[Install]
WantedBy=default.target

I'm trying to run the following script...

#!/bin/bash
while [[ $(systemctl status postgresql.service | awk '/Active/sub("\\(","")  { print $3 }' | awk 'sub("\\)","")' ) != "running" ]]
do echo "Waiting on service to come up.";done

for i in ${DEV_ENV[*]};do EX=$(psql -lt | cut -d\| -f1 | grep ${i,,})
echo "Creating ${i}"
if [[ ! ${EX} ]];then
        psql -c "CREATE DATABASE ${i};"
        psql -c "CREATE USER $i WITH PASSWORD '${i}'; GRANT ALL PRIVILEGES ON DATABASE $i TO ${i};"
fi;done

I know the script runs, I put in checks at beginning and end of the script. Unfortunately the Unit file fails because the $DEV_ENV variable is not being passed.

I can run the following manually and it works.

/usr/bin/su - postgres -c 'export DEV_ENV=$0; /usr/local/bin/psql.sh' "$DEV_ENV"

How do I properly pass the environment variable to the postgres shell?

4
  • Is the command in the unit file even being executed in an environment where the DEV_ENV variable has a meaningful value?
    – Kusalananda
    Dec 19, 2019 at 19:23
  • @Kusalananda I'm not sure what you are asking. The variable has a value, it's an Environment variable, but the value is not being passed to the postgres shell via the command.
    – Chupacabra
    Dec 19, 2019 at 20:33
  • Where do you define this environment variable?
    – Kusalananda
    Dec 19, 2019 at 20:34
  • This is a docker container it is defined in the Dockerfile and then additionally defined in the docker run -d -e DEV_ENV='myapi1 myapi2' ....command
    – Chupacabra
    Dec 19, 2019 at 21:17

1 Answer 1

0

Looks like it is not possible to use environment variables with Unit files when you are trying to run a script as another user. Unit file permissions were root:root and the script was being run as postgres:postgres.

I even tried using an EnvironmentFile in the Unit file, this also failed in the container. Could be because I am using a SystemD replacement from gdraheim/docker-systemctl-replacement. Maybe something else, either way the service was failing.

[Service]
EnvironmentFile=-/etc/sysconfig/dockerenv

In the end I ended up adding an ExecStartPost line to the postgresql.service file.

ExecStartPost=/bin/bash -c /usr/local/bin/psql.sh

The dockerenv file was being created on boot with a startup script using the following...

#Create EnvironmentFile for postgres user when running psql.sh
echo "DEV_ENV=\"${DEV_ENV}\"
PUID=${PUID}
GUID=${GUID}" > /etc/sysconfig/dockerenv

Then the psql.sh script retrieves the variable values in there when it runs.

#!/bin/bash
date
POS_ENV=$(cat /etc/sysconfig/dockerenv | awk -F= '/DEV_ENV/ { print $2 }' | awk 'gsub("\"","")') 
while [[ $(systemctl status postgresql.service | awk '/Active/sub("\\(","")  { print $3 }' | awk 'sub("\\)","")' ) != "running" ]]
do echo "Waiting on service to come up.";done

for i in ${POS_ENV[*]};do EX=$(psql -lt | cut -d\| -f1 | grep ${i,,})
echo "Creating ${i}"
if [[ ! ${EX} ]];then
        psql -c "CREATE DATABASE ${i};"
        psql -c "CREATE USER $i WITH PASSWORD '${i}'; GRANT ALL PRIVILEGES ON DATABASE $i TO ${i};"
fi;done

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.