diff --git a/cmd/generate-config.go b/cmd/generate-config.go
new file mode 100644
index 0000000000000000000000000000000000000000..a13c368aa518f2e9ce540845e557565a94e0084f_Y21kL2dlbmVyYXRlLWNvbmZpZy5nbw==
--- /dev/null
+++ b/cmd/generate-config.go
@@ -0,0 +1,76 @@
+package cmd
+
+import (
+	"io"
+	"os"
+
+	"github.com/jessevdk/go-flags"
+)
+
+type GenerateConfigCmd struct {
+	Output string `short:"o" long:"config-output" no-ini:"t" description:"Destination of the generated configuration" default:"-"`
+
+	parser *flags.Parser
+}
+
+func (cmd *GenerateConfigCmd) Execute([]string) error {
+	var output io.Writer
+
+	var finalize func() error
+
+	if cmd.Output == "-" {
+		output = os.Stdout
+	} else {
+		f, err := os.CreateTemp("", "ioda-config.*.ini")
+		if err != nil {
+			return err
+		}
+
+		var finalized bool
+
+		defer func() {
+			if !finalized {
+				os.Remove(f.Name())
+			}
+		}()
+
+		finalize = func() error {
+			if err := os.Rename(f.Name(), cmd.Output); err != nil {
+				_ = os.Remove(f.Name())
+				return err
+			}
+			finalized = true
+
+			return nil
+		}
+
+		output = f
+	}
+
+	fp := flags.NewIniParser(cmd.parser)
+
+	fp.Write(output, flags.IniIncludeDefaults|flags.IniCommentDefaults|flags.IniDefault)
+
+	if _, err := output.Write([]byte{}); err != nil {
+		return err
+	}
+
+	if finalize != nil {
+		return finalize()
+	}
+
+	return nil
+}
+
+func SetupGenerateConfigCmd(program *Program) *GenerateConfigCmd {
+	cmd := GenerateConfigCmd{
+		parser: program.Parser,
+	}
+
+	_, err := program.Parser.AddCommand("generate-config", "Generate config", "", &cmd)
+	if err != nil {
+		program.Logger.Fatal().Msg(err.Error())
+	}
+
+	return &cmd
+}
diff --git a/cmd/program.go b/cmd/program.go
index 526787c227f5c915b2ede648cd182622fccc8c5c_Y21kL3Byb2dyYW0uZ28=..a13c368aa518f2e9ce540845e557565a94e0084f_Y21kL3Byb2dyYW0uZ28= 100644
--- a/cmd/program.go
+++ b/cmd/program.go
@@ -50,8 +50,9 @@
 
 	DB *sqlx.DB
 
-	ServeCmd   *ServeCmd
-	MigrateCmd *MigrateCmd
+	ServeCmd          *ServeCmd
+	MigrateCmd        *MigrateCmd
+	GenerateConfigCmd *GenerateConfigCmd
 
 	hasDB           bool
 	dbMigrateSource source.Driver
@@ -145,6 +146,7 @@
 	}
 
 	program.ServeCmd = SetupServeCmd(&program)
+	program.GenerateConfigCmd = SetupGenerateConfigCmd(&program)
 
 	if program.hasDB {
 		g, err := parser.AddGroup("Database", "Database options", &program.DatabaseOptions)
diff --git a/cmd/serve.go b/cmd/serve.go
index 526787c227f5c915b2ede648cd182622fccc8c5c_Y21kL3NlcnZlLmdv..a13c368aa518f2e9ce540845e557565a94e0084f_Y21kL3NlcnZlLmdv 100644
--- a/cmd/serve.go
+++ b/cmd/serve.go
@@ -9,7 +9,7 @@
 type ServeCmd struct {
 	Server *orusapi.Server
 
-	AutoMigrate bool `long:"auto-migrate" description:"Automaticaly migrate the database if necessary" env:"AUTOMIGRATE"`
+	AutoMigrate bool `long:"auto-migrate" ini-name:"auto-migrate" description:"Automaticaly migrate the database if necessary" env:"AUTOMIGRATE"`
 
 	program *Program
 }
diff --git a/cmd/xbus_serve.go b/cmd/xbus_serve.go
index 526787c227f5c915b2ede648cd182622fccc8c5c_Y21kL3hidXNfc2VydmUuZ28=..a13c368aa518f2e9ce540845e557565a94e0084f_Y21kL3hidXNfc2VydmUuZ28= 100644
--- a/cmd/xbus_serve.go
+++ b/cmd/xbus_serve.go
@@ -25,7 +25,7 @@
 type XbusServeCmd struct {
 	program *Program
 
-	NoReconnect bool `long:"no-reconnect" description:"When the connection to xbus is lost, stops the program instead of attempting a reconnection"`
+	NoReconnect bool `long:"no-reconnect" ini-name:"no-reconnect" description:"When the connection to xbus is lost, stops the program instead of attempting a reconnection"`
 }
 
 func (cmd *XbusServeCmd) Execute([]string) error {
diff --git a/server.go b/server.go
index 526787c227f5c915b2ede648cd182622fccc8c5c_c2VydmVyLmdv..a13c368aa518f2e9ce540845e557565a94e0084f_c2VydmVyLmdv 100644
--- a/server.go
+++ b/server.go
@@ -61,8 +61,8 @@
 
 // Server for the API.
 type Server struct {
-	EnabledListeners []string         `long:"scheme" description:"the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec" env:"SCHEME"`
-	CleanupTimeout   time.Duration    `long:"cleanup-timeout" description:"grace period for which to wait before killing idle connections" default:"10s"`
-	GracefulTimeout  time.Duration    `long:"graceful-timeout" description:"grace period for which to wait before shutting down the server" default:"15s"`
-	MaxHeaderSize    flagext.ByteSize `long:"max-header-size" description:"controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body." default:"1MiB"`
+	EnabledListeners []string         `long:"scheme" ini-name:"scheme" description:"the listeners to enable, this can be repeated and defaults to the schemes in the swagger spec" env:"SCHEME"`
+	CleanupTimeout   time.Duration    `long:"cleanup-timeout" ini-name:"cleanup-timeout" description:"grace period for which to wait before killing idle connections" default:"10s"`
+	GracefulTimeout  time.Duration    `long:"graceful-timeout" ini-name:"graceful-timeout" description:"grace period for which to wait before shutting down the server" default:"15s"`
+	MaxHeaderSize    flagext.ByteSize `long:"max-header-size" ini-name:"max-header-size" description:"controls the maximum number of bytes the server will read parsing the request header's keys and values, including the request line. It does not limit the size of the request body." default:"1MiB"`
 
@@ -68,4 +68,4 @@
 
-	SocketPath    flags.Filename `long:"socket-path" description:"the unix socket to listen on" default:"/var/run/server.sock"`
+	SocketPath    flags.Filename `long:"socket-path" ini-name:"socket-path" description:"the unix socket to listen on" default:"/var/run/server.sock"`
 	domainSocketL net.Listener
 
@@ -70,10 +70,10 @@
 	domainSocketL net.Listener
 
-	Host         string        `long:"host" description:"the IP to listen on" default:"localhost" env:"HOST"`
-	Port         int           `long:"port" description:"the port to listen on for insecure connections, defaults to a random value" env:"PORT"`
-	ListenLimit  int           `long:"listen-limit" description:"limit the number of outstanding requests"`
-	KeepAlive    time.Duration `long:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"`
-	ReadTimeout  time.Duration `long:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"`
-	WriteTimeout time.Duration `long:"write-timeout" description:"maximum duration before timing out write of the response" default:"60s"`
+	Host         string        `long:"host" ini-name:"host" description:"the IP to listen on" default:"localhost" env:"HOST"`
+	Port         int           `long:"port" ini-name:"port" description:"the port to listen on for insecure connections, defaults to a random value" env:"PORT"`
+	ListenLimit  int           `long:"listen-limit" ini-name:"listen-limit" description:"limit the number of outstanding requests"`
+	KeepAlive    time.Duration `long:"keep-alive" ini-name:"keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)" default:"3m"`
+	ReadTimeout  time.Duration `long:"read-timeout" ini-name:"read-timeout" description:"maximum duration before timing out read of the request" default:"30s"`
+	WriteTimeout time.Duration `long:"write-timeout" ini-name:"write-timeout" description:"maximum duration before timing out write of the response" default:"60s"`
 	httpServerL  net.Listener
 
@@ -78,13 +78,13 @@
 	httpServerL  net.Listener
 
-	TLSHost           string         `long:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`
-	TLSPort           int            `long:"tls-port" description:"the port to listen on for secure connections, defaults to a random value" env:"TLS_PORT"`
-	TLSCertificate    flags.Filename `long:"tls-certificate" description:"the certificate to use for secure connections" env:"TLS_CERTIFICATE"`
-	TLSCertificateKey flags.Filename `long:"tls-key" description:"the private key to use for secure connections" env:"TLS_PRIVATE_KEY"`
-	TLSCACertificate  flags.Filename `long:"tls-ca" description:"the certificate authority file to be used with mutual tls auth" env:"TLS_CA_CERTIFICATE"`
-	TLSListenLimit    int            `long:"tls-listen-limit" description:"limit the number of outstanding requests"`
-	TLSKeepAlive      time.Duration  `long:"tls-keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)"`
-	TLSReadTimeout    time.Duration  `long:"tls-read-timeout" description:"maximum duration before timing out read of the request"`
-	TLSWriteTimeout   time.Duration  `long:"tls-write-timeout" description:"maximum duration before timing out write of the response"`
+	TLSHost           string         `long:"tls-host" ini-name:"tls-host" description:"the IP to listen on for tls, when not specified it's the same as --host" env:"TLS_HOST"`
+	TLSPort           int            `long:"tls-port" ini-name:"tls-port" description:"the port to listen on for secure connections, defaults to a random value" env:"TLS_PORT"`
+	TLSCertificate    flags.Filename `long:"tls-certificate" ini-name:"tls-certificate" description:"the certificate to use for secure connections" env:"TLS_CERTIFICATE"`
+	TLSCertificateKey flags.Filename `long:"tls-key" ini-name:"tls-key" description:"the private key to use for secure connections" env:"TLS_PRIVATE_KEY"`
+	TLSCACertificate  flags.Filename `long:"tls-ca" ini-name:"tls-ca" description:"the certificate authority file to be used with mutual tls auth" env:"TLS_CA_CERTIFICATE"`
+	TLSListenLimit    int            `long:"tls-listen-limit" ini-name:"tls-listen-limit" description:"limit the number of outstanding requests"`
+	TLSKeepAlive      time.Duration  `long:"tls-keep-alive" ini-name:"tls-keep-alive" description:"sets the TCP keep-alive timeouts on accepted connections. It prunes dead TCP connections ( e.g. closing laptop mid-download)"`
+	TLSReadTimeout    time.Duration  `long:"tls-read-timeout" ini-name:"tls-write-timeout" description:"maximum duration before timing out read of the request"`
+	TLSWriteTimeout   time.Duration  `long:"tls-write-timeout" ini-name:"tls-write-timeout" description:"maximum duration before timing out write of the response"`
 	httpsServerL      net.Listener
 
@@ -89,6 +89,6 @@
 	httpsServerL      net.Listener
 
-	Prometheus bool `long:"prometheus" description:"enable prometheus metrics on /metrics"`
+	Prometheus bool `long:"prometheus" ini-name:"prometheus" description:"enable prometheus metrics on /metrics"`
 
 	Environment string `no-flag:"t" description:"A environment name"`