Skip to content

Commit

Permalink
Use env interpolation in config (PostgREST#826)
Browse files Browse the repository at this point in the history
  • Loading branch information
begriffs authored May 25, 2017
1 parent 3e28a3c commit 1e2fd39
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 35 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).

- #742, Add connection retrying on startup and SIGHUP - @steve-chavez
- #652, Add and/or params for complex boolean logic - @steve-chavez
- #808, Env var interpolation in config file (helps Docker) - @begriffs

### Fixed

- #822, Treat blank string JWT secret as no secret - @begriffs

## [0.4.1.0] - 2017-04-25

### Added
Expand Down
15 changes: 15 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ RUN wget http://github.com/begriffs/postgrest/releases/download/v${POSTGREST_VER
mv postgrest /usr/local/bin/postgrest && \
rm postgrest-${POSTGREST_VERSION}-ubuntu.tar.xz

COPY postgrest.conf /etc/postgrest.conf


ENV PGRST_DB_URI= \
PGRST_DB_SCHEMA=public \
PGRST_DB_ANON_ROLE= \
PGRST_DB_POOL=100 \
PGRST_SERVER_HOST=*4 \
PGRST_SERVER_PORT=3000 \
PGRST_SERVER_PROXY_URL= \
PGRST_JWT_SECRET= \
PGRST_SECRET_IS_BASE64=false \
PGRST_MAX_ROWS= \
PGRST_PRE_REQUEST=

# PostgREST reads /etc/postgrest.conf so map the configuration
# file in when you run this container
CMD exec postgrest /etc/postgrest.conf
Expand Down
8 changes: 5 additions & 3 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
stgrest:
image: begriffs/postgrest:latest
image: pg_local
ports:
- "3000:3000"
volumes:
- ./config.conf:/etc/postgrest.conf
links:
- postgres:postgres
environment:
PGRST_DB_URI: postgres://app_user:password@postgres:5432/app_db
PGRST_DB_SCHEMA: public
PGRST_DB_ANON_ROLE: app_user

postgres:
image: postgres
Expand Down
14 changes: 14 additions & 0 deletions docker/postgrest.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
db-uri = "$(PGRST_DB_URI)"
db-schema = "$(PGRST_DB_SCHEMA)"
db-anon-role = "$(PGRST_DB_ANON_ROLE)"
db-pool = "$(PGRST_DB_POOL)"

server-host = "$(PGRST_SERVER_HOST)"
server-port = "$(PGRST_SERVER_PORT)"

server-proxy-url = "$(PGRST_SERVER_PROXY_URL)"
jwt-secret = "$(PGRST_JWT_SECRET)"
secret-is-base64 = "$(PGRST_SECRET_IS_BASE64)"

max-rows = "$(PGRST_MAX_ROWS)"
pre-request = "$(PGRST_PRE_REQUEST)"
2 changes: 1 addition & 1 deletion postgrest.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ library
, bytestring
, case-insensitive
, cassava
, configurator
, configurator-ng == 0.0.0.1
, containers
, contravariant
, either
Expand Down
63 changes: 32 additions & 31 deletions src/PostgREST/Config.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
{-|
Module : PostgREST.Config
Description : Manages PostgREST configuration options.
Expand Down Expand Up @@ -27,9 +28,11 @@ import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as BS
import qualified Data.CaseInsensitive as CI
import qualified Data.Configurator as C
import qualified Data.Configurator.Types as C
import qualified Data.Configurator.Parser as C
import Data.Configurator.Types (Value(..))
import Data.List (lookup)
import Data.Monoid
import Data.Scientific (floatingOrInteger)
import Data.Text (strip, intercalate, lines)
import Data.Text.Encoding (encodeUtf8)
import Data.Text.IO (hPutStrLn)
Expand All @@ -38,6 +41,7 @@ import Network.Wai
import Network.Wai.Middleware.Cors (CorsResourcePolicy (..))
import Options.Applicative hiding (str)
import Paths_postgrest (version)
import System.IO (hPrint)
import Text.Heredoc
import Text.PrettyPrint.ANSI.Leijen hiding ((<>), (<$>))
import qualified Text.PrettyPrint.ANSI.Leijen as L
Expand Down Expand Up @@ -95,30 +99,37 @@ readOptions = do
cfgPath <- customExecParser parserPrefs opts
-- Now read the actual config file
conf <- catch
(C.load [C.Required cfgPath])
(C.readConfig =<< C.load [C.Required cfgPath])
configNotfoundHint

handle missingKeyHint $ do
-- db ----------------
cDbUri <- C.require conf "db-uri"
cDbSchema <- C.require conf "db-schema"
cDbAnon <- C.require conf "db-anon-role"
cPool <- C.lookupDefault 10 conf "db-pool"
-- server ------------
cHost <- C.lookupDefault "*4" conf "server-host"
cPort <- C.lookupDefault 3000 conf "server-port"
cProxy <- C.lookup conf "server-proxy-uri"
-- jwt ---------------
cJwtSec <- C.lookup conf "jwt-secret"
cJwtB64 <- C.lookupDefault False conf "secret-is-base64"
-- safety ------------
cMaxRows <- C.lookup conf "max-rows"
cReqCheck <- C.lookup conf "pre-request"

return $ AppConfig cDbUri cDbAnon cProxy cDbSchema cHost cPort
(encodeUtf8 <$> cJwtSec) cJwtB64 cPool cMaxRows cReqCheck False
let (mAppConf, errs) = flip C.runParserA conf $
AppConfig <$>
C.key "db-uri"
<*> C.key "db-anon-role"
<*> C.key "server-proxy-uri"
<*> C.key "db-schema"
<*> (fromMaybe "*4" <$> C.key "server-host")
<*> (fromMaybe 3000 . join . fmap coerceInt <$> C.key "server-port")
<*> (fmap encodeUtf8 . mfilter (/= "") <$> C.key "jwt-secret")
<*> (fromMaybe False <$> C.key "secret-is-base64")
<*> (fromMaybe 10 . join . fmap coerceInt <$> C.key "db-pool")
<*> (join . fmap coerceInt <$> C.key "max-rows")
<*> C.key "pre-request"
<*> pure False

case mAppConf of
Nothing -> do
forM_ errs $ hPrint stderr
exitFailure
Just appConf ->
return appConf

where
coerceInt :: (Read i, Integral i) => Value -> Maybe i
coerceInt (Number x) = rightToMaybe $ floatingOrInteger x
coerceInt (String x) = readMaybe $ toS x
coerceInt _ = Nothing

opts = info (helper <*> pathParser) $
fullDesc
<> progDesc (
Expand All @@ -139,15 +150,6 @@ readOptions = do
"Cannot open config file:\n\t" <> show e
exitFailure

missingKeyHint :: C.KeyError -> IO a
missingKeyHint (C.KeyError n) = do
hPutStrLn stderr $
"Required config parameter \"" <> n <> "\" is missing or of wrong type.\n" <>
"Documentation for configuration options available at\n" <>
"\thttp://postgrest.com/en/v0.4/admin.html#configuration\n\n" <>
"Try the --example-config option to see how to configure PostgREST."
exitFailure

exampleCfg :: Doc
exampleCfg = vsep . map (text . toS) . lines $
[str|db-uri = "postgres://user:pass@localhost:5432/dbname"
Expand All @@ -173,7 +175,6 @@ readOptions = do
|# pre-request = "stored_proc_name"
|]


pathParser :: Parser FilePath
pathParser =
strArgument $
Expand Down
2 changes: 2 additions & 0 deletions stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ resolver: lts-8.5
extra-deps:
- Ranged-sets-0.3.0
- hasql-pool-0.4.1
- configurator-ng-0.0.0.1
- critbit-0.2.0.0
ghc-options:
postgrest: -O2 -Werror -Wall -fwarn-identities -fno-warn-redundant-constraints
nix:
Expand Down

0 comments on commit 1e2fd39

Please sign in to comment.