diff --git a/database/options.go b/database/options.go
index 28952ee02687c9a8cc94b47b4c33f5c8bf31c56f_ZGF0YWJhc2Uvb3B0aW9ucy5nbw==..b9c79b6413628b85d90c2b44cf84790b7fd04bf2_ZGF0YWJhc2Uvb3B0aW9ucy5nbw== 100644
--- a/database/options.go
+++ b/database/options.go
@@ -4,8 +4,8 @@
 
 // Options is a jessevdk/go-flags compatible struct for db-related options
 type Options struct {
-	DSN     string `long:"db-dsn" env:"DB_DSN" ini-name:"dsn" description:"DSN of the database"`
-	MaxConn int    `long:"db-max-conn" env:"DB_MAX_CONN" ini-name:"max-conn" description:"Database max connection" default:"0"`
+	DSN     string `long:"dsn" env:"DSN" ini-name:"dsn" description:"DSN of the database"`
+	MaxConn int    `long:"max-conn" env:"MAX_CONN" ini-name:"max-conn" description:"Database max connection" default:"0"`
 }
 
 // Open a connection to the database
diff --git a/generate-config.go b/generate-config.go
new file mode 100644
index 0000000000000000000000000000000000000000..b9c79b6413628b85d90c2b44cf84790b7fd04bf2_Z2VuZXJhdGUtY29uZmlnLmdv
--- /dev/null
+++ b/generate-config.go
@@ -0,0 +1,40 @@
+package orusapi
+
+import (
+	"io"
+	"os"
+
+	flags "github.com/orus-io/go-flags"
+)
+
+// GenerateConfigCmd is a command that generates a configuration file
+type GenerateConfigCmd struct {
+	Output string `short:"o" long:"output" default:"-" no-ini:"t" description:"output file"`
+
+	parser *flags.Parser
+}
+
+// NewGenerateConfigCmd creates a GenerateConfigCmd
+func NewGenerateConfigCmd(parser *flags.Parser) *GenerateConfigCmd {
+	return &GenerateConfigCmd{parser: parser}
+}
+
+// Execute write out a configuration file
+func (c *GenerateConfigCmd) Execute([]string) (errResult error) {
+	var out io.Writer
+	if c.Output == "-" {
+		out = os.Stdout
+	} else {
+		f, err := os.OpenFile(c.Output, os.O_RDWR|os.O_CREATE, 0755)
+		if err != nil {
+			return err
+		}
+		defer func() {
+			errResult = f.Close()
+		}()
+		out = f
+	}
+	fp := flags.NewIniParser(c.parser)
+	fp.Write(out, flags.IniIncludeDefaults|flags.IniCommentDefaults|flags.IniDefault)
+	return nil
+}
diff --git a/logging.go b/logging.go
index 28952ee02687c9a8cc94b47b4c33f5c8bf31c56f_bG9nZ2luZy5nbw==..b9c79b6413628b85d90c2b44cf84790b7fd04bf2_bG9nZ2luZy5nbw== 100644
--- a/logging.go
+++ b/logging.go
@@ -38,8 +38,8 @@
 
 // LoggingOptions holds the logging options
 type LoggingOptions struct {
-	Level   func(string) error `long:"log-level" env:"LOG_LEVEL" ini-name:"log-level" choice:"trace" choice:"debug" choice:"info" choice:"warn" choice:"error" choice:"fatal" choice:"panic" choice:"auto" default:"auto" description:"log level. 'auto' selects 'info' when stdout is a tty, 'error' otherwise."`
-	Format  func(string) error `long:"log-format" env:"LOG_FORMAT" ini-name:"log-format" choice:"json" choice:"pretty" choice:"auto" default:"auto" description:"Logs format. 'auto' selects 'pretty' if stdout is a tty."`
+	Level   func(string) error `long:"level" env:"LEVEL" ini-name:"log-level" choice:"trace" choice:"debug" choice:"info" choice:"warn" choice:"error" choice:"fatal" choice:"panic" choice:"auto" default:"auto" description:"log level. 'auto' selects 'info' when stdout is a tty, 'error' otherwise."`
+	Format  func(string) error `long:"format" env:"FORMAT" ini-name:"log-format" choice:"json" choice:"pretty" choice:"auto" default:"auto" description:"Logs format. 'auto' selects 'pretty' if stdout is a tty."`
 	Verbose func()             `short:"v" long:"verbose" no-ini:"t" description:"Increase log verbosity. Can be repeated"`
 
 	logFinalOutput io.Writer                   `no-flag:"t"`
diff --git a/templates/server/cmd.gotmpl b/templates/server/cmd.gotmpl
index 28952ee02687c9a8cc94b47b4c33f5c8bf31c56f_dGVtcGxhdGVzL3NlcnZlci9jbWQuZ290bXBs..b9c79b6413628b85d90c2b44cf84790b7fd04bf2_dGVtcGxhdGVzL3NlcnZlci9jbWQuZ290bXBs 100644
--- a/templates/server/cmd.gotmpl
+++ b/templates/server/cmd.gotmpl
@@ -8,7 +8,11 @@
 	"orus.io/orus-io/go-orus-api/database"
 )
 
+type ConfigFile struct {
+	ConfigFile string `long:"config" short:"c" env:"CONFIG" no-ini:"t" description:"A configuration file"`
+}
+
 var (
 	Logger = orusapi.DefaultLogger(os.Stdout)
 	LoggingOptions  = orusapi.MustLoggingOptions(orusapi.NewLoggingOptions(&Logger, os.Stdout))
 	DatabaseOptions = &database.Options{}
@@ -11,6 +15,7 @@
 var (
 	Logger = orusapi.DefaultLogger(os.Stdout)
 	LoggingOptions  = orusapi.MustLoggingOptions(orusapi.NewLoggingOptions(&Logger, os.Stdout))
 	DatabaseOptions = &database.Options{}
+	ConfigFileOption = &ConfigFile{}
 
 	parser = flags.NewNamedParser("{{ dasherize (pascalize .Name) }}", flags.HelpFlag|flags.PassDoubleDash)
@@ -15,5 +20,6 @@
 
 	parser = flags.NewNamedParser("{{ dasherize (pascalize .Name) }}", flags.HelpFlag|flags.PassDoubleDash)
+	bootstrapParser = flags.NewNamedParser("{{ dasherize (pascalize .Name) }}", flags.IgnoreUnknown)
 )
 
 func Run() int {
@@ -17,6 +23,20 @@
 )
 
 func Run() int {
+	if _, err := bootstrapParser.Parse(); err != nil {
+		Logger.Err(err).Msg("")
+		return 1
+	}
+
+	if ConfigFileOption.ConfigFile != "" {
+		Logger.Debug().Str("configfile", ConfigFileOption.ConfigFile).Msg("parsing configuration file")
+		iniParser := flags.NewIniParser(parser)
+		if err := iniParser.ParseFile(ConfigFileOption.ConfigFile); err != nil {
+			Logger.Err(err).Msg("")
+			return 1
+		}
+	}
+
 	if _, err := parser.Parse(); err != nil {
 		code := 1
 		if fe, ok := err.(*flags.Error); ok {
@@ -26,6 +46,6 @@
 				// so we print it on the console
 				fmt.Println(err)
 			} else {
-				log.Error().Msg(err.Error())
+				Logger.Error().Msg(err.Error())
 			}
 		} else {
@@ -30,6 +50,6 @@
 			}
 		} else {
-			log.Err(err).Msg("")
+			Logger.Err(err).Msg("")
 		}
 		return code
 	}
@@ -37,6 +57,34 @@
 }
 
 func init() {
-	parser.AddGroup("Logging", "Logging options", LoggingOptions)
-	parser.AddGroup("Database", "Database options", DatabaseOptions)
+	parser.NamespaceDelimiter = "-"
+	parser.EnvNamespaceDelimiter = "_"
+	parser.EnvNamespace = "CARNET"
+	parser.AddGroup("Configuration", "Configuration file", ConfigFileOption)
+	g, err := parser.AddGroup("Logging", "Logging options", LoggingOptions)
+	if err != nil {
+		panic(err)
+	}
+	g.Namespace="log"
+	g.EnvNamespace="LOG"
+	g, err = parser.AddGroup("Database", "Database options", DatabaseOptions)
+	if err != nil {
+		panic(err)
+	}
+	g.Namespace="db"
+	g.EnvNamespace="DB"
+
+	parser.AddCommand("generate-config", "Generate a configuration file", "", orusapi.NewGenerateConfigCmd(parser))
+
+	bootstrapParser.NamespaceDelimiter = "-"
+	bootstrapParser.EnvNamespaceDelimiter = "_"
+	bootstrapParser.EnvNamespace = "CARNET"
+	bootstrapParser.AddGroup("Configuration", "Configuration file", ConfigFileOption)
+	g, err = bootstrapParser.AddGroup("Logging", "Logging options", LoggingOptions)
+	if err != nil {
+		panic(err)
+	}
+	g.Namespace="log"
+	g.EnvNamespace="LOG"
+
 }