Environment configuration

Goat uses environment variables to configure the application, database connections, working directories, and settings specific to a given environment.

In local development, these values are typically stored in the following file:

.env

The names of variables used by the application begin with the following prefix:

GOAT_

The .env file should contain only configuration specific to the local environment. Do not treat it as a place to store production secrets, and do not include real passwords, tokens, or keys in a public repository.

Key variables

VariableDescription
GOAT_DEVEnables the application's development mode.
GOAT_DB_MAIN_HOSTHost of the primary PostgreSQL database.
GOAT_DB_MAIN_PORTPort of the primary PostgreSQL database.
GOAT_DB_MAIN_USERPrimary database user.
GOAT_DB_MAIN_PASSPrimary database user password.
GOAT_DB_MAIN_NAMEPrimary database name.
GOAT_DB_TEST_HOSTHost of the database used by tests.
GOAT_DB_TEST_PORTTest database port.
GOAT_DB_TEST_USERTest database user.
GOAT_DB_TEST_PASSTest database user password.
GOAT_DB_TEST_NAMETest database name.
GOAT_JWT_SECRETSecret used to sign JWT tokens.
GOAT_URL_BASEPublic base URL of the application.
GOAT_DIR_DATAApplication data directory.
GOAT_DIR_TMPLocal temporary files directory.
GOAT_DIR_SHARED_TMPTemporary directory shared between processes or containers.
GOAT_DOMAINDomain used by the target environment configuration.

Example local configuration

A minimal local environment configuration may look as follows:

GOAT_DEV=TRUE

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=admin
GOAT_DB_MAIN_PASS=local-password
GOAT_DB_MAIN_NAME=maindb

GOAT_JWT_SECRET=zmien-na-dlugi-losowy-sekret

GOAT_URL_BASE=http://localhost:8080/

The values in the example are intended for development only.

Credentials for shared, staging, and production environments should be provided through the configuration mechanism appropriate for the given environment.

Development mode

Use the following variable:

GOAT_DEV

to determine whether the application runs in development mode.

Example:

GOAT_DEV=TRUE

Development mode may affect application behavior related to, among other things:

  • logging,
  • diagnostics,
  • error handling,
  • cache,
  • helper tools,
  • the way the frontend or backend is started.

Do not assume that development configuration is suitable for a production environment.

Primary database configuration

The primary PostgreSQL connection is defined by a set of variables:

GOAT_DB_MAIN_HOST
GOAT_DB_MAIN_PORT
GOAT_DB_MAIN_USER
GOAT_DB_MAIN_PASS
GOAT_DB_MAIN_NAME

Example:

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=admin
GOAT_DB_MAIN_PASS=local-password
GOAT_DB_MAIN_NAME=maindb

These values are used by the application and scripts responsible for working with the main database.

In the local environment, PostgreSQL is started by default by Goat scripts in Docker.

Separate database for tests

Tests can use a separate connection:

GOAT_DB_TEST_HOST
GOAT_DB_TEST_PORT
GOAT_DB_TEST_USER
GOAT_DB_TEST_PASS
GOAT_DB_TEST_NAME

Separating the test database from the development database reduces the risk of accidentally deleting or modifying data used during daily work.

Example configuration:

GOAT_DB_TEST_HOST=localhost
GOAT_DB_TEST_PORT=5433
GOAT_DB_TEST_USER=admin
GOAT_DB_TEST_PASS=local-password
GOAT_DB_TEST_NAME=testdb

It is particularly important that destructive operations performed during tests never point to the production database.

JWT secret

The variable:

GOAT_JWT_SECRET

is used by the application to sign JWT tokens.

The value should be:

  • long,
  • random,
  • unique to a given environment,
  • not publicly accessible.

Do not use the example secret in the production environment.

Do not store the actual GOAT_JWT_SECRET in files tracked by Git.

Each environment should have its own value. In particular, local, test, and production environments should not share the same secret.

Public application URL

Use the variable:

GOAT_URL_BASE

to specify the public base URL of the application.

Locally, it can be:

GOAT_URL_BASE=http://localhost:8080/

In the target environment, the value should correspond to the actual address used by application clients.

It may be used, among other things, when generating:

  • absolute links,
  • callbacks,
  • addresses in messages,
  • metadata,
  • links to application resources.

Data and temporary file directories

Goat allows you to configure locations used to store data and temporary files.

The following are used for this purpose:

GOAT_DIR_DATA
GOAT_DIR_TMP
GOAT_DIR_SHARED_TMP

GOAT_DIR_DATA points to the directory intended for application data.

GOAT_DIR_TMP can be used by a single process to store temporary files.

GOAT_DIR_SHARED_TMP is intended for temporary data that must be available to more than one process or container.

Explicitly defining these directories makes it easier to adapt the application to different runtime environments.

Environment domain

The variable:

GOAT_DOMAIN

can be used to specify the domain associated with the current environment.

The value may be used by deployment configuration, a reverse proxy, address generation, or other infrastructure components.

For example:

GOAT_DOMAIN=example.com

It should not be automatically equated with GOAT_URL_BASE.

GOAT_DOMAIN describes the domain, whereas GOAT_URL_BASE may contain the full address including the protocol, port, and base path.

Secrets and version control

Configuration files stored in the repository should contain only safe example values.

Store actual secrets outside version control.

This applies primarily to:

GOAT_DB_MAIN_PASS
GOAT_DB_TEST_PASS
GOAT_JWT_SECRET

In the local environment, they may be located in .env.

In shared and production environments, it is better to provide them through:

  • platform environment variables,
  • CI/CD system,
  • secrets manager,
  • mechanisms provided by the deployment platform.

A good practice is to keep an example file in the repository, e.g.:

.env.example

containing the names of the required variables, but without the actual secrets.

Example:

GOAT_DEV=TRUE

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=
GOAT_DB_MAIN_PASS=
GOAT_DB_MAIN_NAME=

GOAT_JWT_SECRET=

GOAT_URL_BASE=http://localhost:8080/

Such a file makes it easier to prepare a new environment without exposing sensitive data.

Container configuration

Local Goat scripts use Docker to run part of the project infrastructure.

In particular, the database scripts run PostgreSQL in a container and expose it locally on the following port:

5433

From the perspective of a process running directly on the host, the connection may therefore look like this:

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433

The situation is different when the application itself runs inside a container.

For a process inside Docker:

localhost

means its own container, not the host system.

Therefore, the development script may override the database host to:

host.docker.internal

The flow then looks as follows, in simplified form:

application in a container
        ↓
host.docker.internal:5433
        ↓
port exposed by the host
        ↓
PostgreSQL

This makes it possible to use the same project configuration regardless of whether a given command is executed directly on the host or inside a container.

Local configuration vs. target configuration

It is not worth copying the local .env to the server unchanged.

Locally, the configuration is optimized for development convenience:

localhost
ports exposed by Docker
GOAT_DEV=TRUE
local passwords
local directories

The production environment may instead use:

an internal PostgreSQL host
secrets provided by the platform
HTTPS
persistent volumes
different data directories
GOAT_DEV=FALSE

Configuration should therefore be treated as an environment-dependent element, not as part of the application code.

Typical local workflow

Preparing a local configuration may look as follows:

cp .env.example .env

Then fill in the values required by the project:

GOAT_DEV=TRUE

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=admin
GOAT_DB_MAIN_PASS=local-password
GOAT_DB_MAIN_NAME=maindb

GOAT_JWT_SECRET=lokalny-losowy-sekret

GOAT_URL_BASE=http://localhost:8080/

After saving the configuration, you can start the environment:

goat run:script --path=herd/dev.goat

Goat scripts will prepare the remaining environment components according to the project configuration.

The most important rule

Application code should define what configuration it needs, while the actual values should come from the environment in which the application is run.

This allows the same code to run locally, in tests, in CI, on staging, and in production without requiring changes directly in the sources.

Treat secrets as environment data, not as part of the project.