# Environment variables {#environment-variables}


After installing Shlink, you will have to set it up, and customize different aspects of its behavior. One way to do this is via **environment variables**.

This is the complete list of supported env vars. Right next to their name you will find the version in which they were introduced.

Strikethrough env vars are deprecated.


## Supported env vars {#supported-env-vars}


- [General](#general)
- [URL shortening](#url-shortening)
- [Database](#database)
- [Redirects](#redirects)
- [Visits tracking](#visits-tracking)
- [Robots.txt](#robotstxt)
- [Cross-origin](#cross-origin)
- [Real-time updates](#real-time-updates)
- [Redis integration](#redis-integration)
- [Mercure hub integration](#mercure-hub-integration)
- [RabbitMQ integration](#rabbitmq-integration)
- [Matomo integration](#matomo-integration)
- [Specific for the docker image](#specific-for-the-docker-image)


### General {#general}


- `DEFAULT_DOMAIN`: The default short domain used for this Shlink instance. For example **s.test**.
- `IS_HTTPS_ENABLED`: Tells if Shlink is served with https or not (`true` or `false`). It's still **up to you** to actually serve it with HTTPS.
- `GEOLITE_LICENSE_KEY`: The license key used to download new GeoLite2 database files. Go to [GeoLite2 license key](https://sourcey-shlink.pages.dev/documentation/geolite-license-key/index.md) to know how to generate it. Not providing a license key will completely disable visits geolocation.
- `BASE_PATH`: The base path from which you plan to serve Shlink, in case you don't want to serve it from the root of the domain. It **has** to start with a bar, like `/shlink`. Defaults to `''`.
- `TIMEZONE`: A timezone code as defined [in this list](https://www.php.net/manual/en/timezones.php). All dates stored by Shlink (visits, short URL creation, etc) will be considered to be on this timezone. By default, the default timezone set in PHP config will be used, which is `UTC` in the case of the docker image.
- `CACHE_NAMESPACE` _(v3.7.0)_ : A prefix used for all cache keys generated by Shlink. It's important to set a unique value here if you have multiple Shlink instances sharing the same cache store (same server when not using redis, or same redis cluster), otherwise there could be collisions. Defaults to `Shlink`.
- `TRUSTED_PROXIES` _(v4.5.0)_ : Either the amount of proxies in front of Shlink, or a comma-separated list of their IP addresses as fixed address (`100.200.80.40`), CIDR block (`192.168.10.0/24`) or wildcard pattern (`11.22.*.*`). It's important to set this if you have more than one reverse proxy in front of Shlink, so that the visitor's IP addresses can be properly determined.
- `MEMORY_LIMIT` _(v4.1.0)_ : The maximum amount of memory that every Shlink process can use. You can provide a number, which will be the amount of memory in bytes, or a number followed by `K` for kilobytes, `M` for megabytes or `G` for gigabytes. You can also provide `-1` to set no memory limit. Defaults to `512M`.
- `LOGS_FORMAT` _(v4.5.0)_ : The format in which Shlink generates logs. It can be `console` (the default) or `json`.



> [!IMPORTANT]
> **Note**
>
> When using RoadRunner, Shlink will spin-up one persistent process per web/job worker, which will run and consume memory until Shlink is restarted.
>
> With php-fpm, there will be one process per request that's killed once finished. The max amount of concurrent active processes can be configured using [`process.max`](https://www.php.net/manual/en/install.fpm.configuration.php).




### URL shortening {#url-shortening}


- `DEFAULT_SHORT_CODES_LENGTH`: The length you want generated short codes to have. It defaults to 5 and has to be at least 4, so any value smaller than that will fall back to 4.
- `DELETE_SHORT_URL_THRESHOLD`: The amount of visits on short URLs which will not allow them to be deleted. If not provided, this restriction will be disabled.
- `AUTO_RESOLVE_TITLES`: Used to automatically resolve the short URL's title based on the `<title />` tag in the long URL. Defaults to `true`.
- `MULTI_SEGMENT_SLUGS_ENABLED`: Allows to create and handle multi-segment custom slugs when `true` is provided. Default value is `false`. See [multi-segment custom slugs](https://sourcey-shlink.pages.dev/documentation/some-features/index.md#multi-segment-custom-slugs) for more information.
- `SHORT_URL_TRAILING_SLASH`: Allows to enable support for trailing slashes in short URLs when `true` is provided. Default value is `false`. See [short URLs trailing slash](https://sourcey-shlink.pages.dev/documentation/some-features/index.md#short-urls-trailing-slash) for more information.
- `SHORT_URL_MODE` _(v3.5.0)_ : `strict` or `loose`. Determines how to match short URLs. Defaults to `strict`. See [short URLs mode](https://sourcey-shlink.pages.dev/documentation/some-features/index.md#short-urls-mode) for more information.


### Database {#database}


- `DB_DRIVER`: **mysql**, **maria**, **postgres**, **mssql** or **sqlite**.
- `DB_NAME`: The database name to be used when using an external database driver. Defaults to **shlink**.
- `DB_USER`: The username credential to be used when using an external database driver.
- `DB_PASSWORD`: The password credential to be used when using an external database driver.
- `DB_HOST`: The host name of the database server when using an external database driver.
- `DB_PORT`: The port in which the database service is running when using an external database driver. Default value is based on the value provided for `DB_DRIVER`:
  - **mysql** or **maria** -> `3306`
  - **postgres** -> `5432`
  - **mssql** -> `1433`
- `DB_UNIX_SOCKET`: Alternatively to the `DB_HOST`, you can provide this to connect through unix sockets when using `mysql`, `maria` or `postgres` drivers.
- `DB_USE_ENCRYPTION`: Whether it is desired to use an encrypted connection with the database or not. Defaults to `false`.



> [!WARNING]
> SQLite is intended for testing/automation purposes only. Using it in production is [not supported](https://sourcey-shlink.pages.dev/documentation/supported-db-engines/index.md#sqlite-limitations), even less if mounted via docker volumes.
>
> There's a potential risk of breakage when updating Shlink, so make sure you move to any of the other alternatives if you plan to use Shlink long term.




### Redirects {#redirects}


- `REDIRECT_STATUS_CODE`: **301**, **302**, **308** or **307** (last two since v3.5.0). Determines the status code that should be used on redirects from short to long URLs. Setting **308** or **307** implicitly makes requests to short URLs work regardless the HTTP method. Defaults to **302**.
- `REDIRECT_CACHE_LIFETIME`: Allows to set the amount of seconds that redirects should be cached when redirect status is 301 or 308. Default values is 30.
- `DEFAULT_INVALID_SHORT_URL_REDIRECT`: If a URL is provided here, when a user tries to access an invalid short URL, and the visited domain does not have a redirect URL of its own, he/she will be redirected to this value. If this env var is not provided, the user will see a generic `404 - not found` page.
- `DEFAULT_REGULAR_404_REDIRECT`: If a URL is provided here, when a user tries to access a URL not matching any supported by the router, and the visited domain does not have a redirect URL of its own, he/she will be redirected to this value. If this env var is not provided, the user will see a generic `404 - not found` page.
- `DEFAULT_BASE_URL_REDIRECT`: If a URL is provided here, when a user tries to access Shlink's base URL, and the visited domain does not have a redirect URL of its own, he/she will be redirected to this value. If this env var is not provided, the user will see a generic `404 - not found` page.
- `REDIRECT_EXTRA_PATH_MODE` _(v4.4.0)_ : Determines how Shlink should match short URLs when they start with a known short code. (See [Extra path forwarding](https://sourcey-shlink.pages.dev/documentation/some-features/index.md#extra-path-forwarding) for more info).
  - **default** -> Only exact short URLs will match. Extra paths will result in a not-found short URL.
  - **append** -> The rest of the path will be appended to the long URL before redirection.
  - **ignore** -> The rest of the path will be ignored.
- ~`REDIRECT_APPEND_EXTRA_PATH`~: This is deprecated since Shlink 4.4.0. Use `REDIRECT_EXTRA_PATH_MODE=append` instead.


### Visits tracking {#visits-tracking}


- `DISABLE_TRACKING`: Tells if visits tracking should be completely disabled. Defaults to `false` (see [Tracking visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md) for more info).
- `TRACK_ORPHAN_VISITS`: Tells if [orphan visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md#orphan-visits) should be tracked or not. Defaults to `true` (see [Tracking visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md) for more info).
- `DISABLE_TRACK_PARAM`: The name of a query param that can be used to visit short URLs avoiding the visit to be tracked. This feature won't be available if no value is provided (see [Tracking visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md) for more info).
- `DISABLE_TRACKING_FROM`: A comma-separated list of IP address patterns from which all tracking should be disabled. It allows providing fixed IP addresses (`100.200.80.40`), CIDR blocks (`192.168.10.0/24`) or wildcard patterns (`11.22.*.*`)
- `DISABLE_IP_TRACKING`: Tells if tracking of the IP address (and therefore visitors location) should be disabled. Defaults to `false` (see [Tracking visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md) for more info).
- `DISABLE_REFERRER_TRACKING`: Tells if tracking of the referrer should be disabled. Defaults to `false` (see [Tracking visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md) for more info).
- `DISABLE_UA_TRACKING`: Tells if tracking of the user agent should be disabled. Defaults to `false` (see [Tracking visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md) for more info).
- `ANONYMIZE_REMOTE_ADDR`: Tells if IP addresses from visitors should be obfuscated before storing them in the database. Default value is `true` (see [Tracking visits](https://sourcey-shlink.pages.dev/documentation/tracking-visits/index.md) for more info).
  

> [!WARNING]
> Setting this to <b>false</b> will make your Shlink instance no longer be in compliance with the GDPR and other
> similar data protection regulations.




### Robots.txt {#robotstxt}


- `ROBOTS_ALLOW_ALL_SHORT_URLS` _(v4.2.0)_ : Whether all short URLs should be allowed via robots.txt or not. If set to `true`, the `crawlable` option set in individual short URLs will be ignored. Defaults to `false`.
- `ROBOTS_USER_AGENTS` _(v4.2.0)_ : A comma-separated list of allowed user agents via robots.txt. Defaults to `*`.


### Cross-origin {#cross-origin}


- `CORS_ALLOW_ORIGIN` _(v4.5.0)_ : Determines for what origins Shlink will allow cross-domain requests. Possible values are:
  - `*`: `Access-Control-Allow-Origin` header is set to `*`, implicitly allowing all origins. This is the **default** value.
  - `<origin>`: `Access-Control-Allow-Origin` header is explicitly set to the value in the request's `Origin` header, allowing all origins, but browsers will apply fewer restrictions than with `*`.
  - A comma-separated list of origins: `Access-Control-Allow-Origin` header is explicitly set to the value in the request's `Origin` header, but only if it is one of the provided values. Otherwise, `Access-Control-Allow-Origin` won't be set at all, restricting requests from any other origin.
- `CORS_ALLOW_CREDENTIALS` _(v4.5.0)_ : If set to `true`, the response will include `Access-Control-Allow-Credentials: true`, and the header won't be included at all otherwise. Defaults to `false`.
- `CORS_MAX_AGE` _(v4.5.0)_ : Determines the value in `Access-Control-Max-Age` header. Defaults to 3600.


### Real-time updates {#real-time-updates}


- `REAL_TIME_UPDATES_TOPICS` _(v4.5.0)_ : A comma-separated list of the topics to which real-time updates should be sent, if at least one real-time updates integration is enabled. All topics are enabled if not provided. Possible values are:
- `NEW_VISIT`: Notify when any short URL is visited, in a common topic.
- `NEW_ORPHAN_VISIT`: Notify when a new non-orphan.
- `NEW_SHORT_URL_VISIT`: Notify when a short URL is visited, on its own scoped topic.
- `NEW_SHORT_URL`: Notify when a short URL is created.


### Redis integration {#redis-integration}


- `REDIS_SERVERS`: A comma-separated list of redis servers which Shlink uses for shared locks, cache, and optionally real-time updates through pub/sub (make sure to include the port number and credentials for every server).
- `REDIS_SENTINEL_SERVICE`: The name of the sentinel service if you want to use redis sentinel. If this value is provided, the servers provided in `REDIS_SERVERS` will be considered sentinel instances.
- `REDIS_SERVERS_USER` _(v4.6.0)_ : The user credential for redis server/s. Ignored when not using `REDIS_SENTINEL_SERVICE`.
- `REDIS_SERVERS_PASSWORD` _(v4.6.0)_ : The password credential for redis server/s. Ignored when not using `REDIS_SENTINEL_SERVICE`.
- `REDIS_PUB_SUB_ENABLED`: Tells if the configured redis instance/cluster should also be used to publish real-time updates via redis pub/sub. Defaults to `false`.


### Mercure hub integration {#mercure-hub-integration}


- `MERCURE_ENABLED` _(v4.5.0)_ : Whether mercure integration for real-time updates is enabled or not. Defaults to `false`. (Before Shlink 4.5, mercure integration was implicitly enabled just by providing a value for `MERCURE_PUBLIC_HUB_URL`).
- `MERCURE_PUBLIC_HUB_URL`: The public URL of a mercure hub server to which Shlink will send updates. This URL will also be served to consumers that want to subscribe to those updates.
- `MERCURE_INTERNAL_HUB_URL`: An internal URL for a mercure hub. Will be used only when publishing updates to mercure, and does not need to be public. If this is not provided but `MERCURE_PUBLIC_HUB_URL` was, the former one will be used to publish updates.
- `MERCURE_JWT_SECRET`: The secret key that was provided to the mercure hub server, in order to be able to generate valid JWTs for publishing/subscribing to that server.


### RabbitMQ integration {#rabbitmq-integration}


- `RABBITMQ_ENABLED`: Tells if the integration with a RabbitMQ server for real-time updates should be enabled. Defaults to `false`.
- `RABBITMQ_HOST`: The RabbitMQ server host name. This will be ignored if `RABBITMQ_ENABLED` is false.
- `RABBITMQ_USE_SSL`: Whether connection is encrypted with SSL/TLS or not. Defaults to `false`. This will be ignored if `RABBITMQ_ENABLED` is false.
- `RABBITMQ_PORT`: The RabbitMQ server port. Defaults to `5672`. This will be ignored if `RABBITMQ_ENABLED` is false.
- `RABBITMQ_USER`: The RabbitMQ server username credential. This will be ignored if `RABBITMQ_ENABLED` is false.
- `RABBITMQ_PASSWORD`: The RabbitMQ server password credential. This will be ignored if `RABBITMQ_ENABLED` is false.
- `RABBITMQ_VHOST`: The RabbitMQ server VHost. Defaults to `/`. This will be ignored if `RABBITMQ_ENABLED` is false.


### Matomo integration {#matomo-integration}


- `MATOMO_ENABLED` _(v3.7.0)_ : Tells if visits should be sent to a Matomo instance. Defaults to `false`.
- `MATOMO_BASE_URL` _(v3.7.0)_ : The external Matomo server URL. This will be ignored if `MATOMO_ENABLED` is false.
- `MATOMO_SITE_ID` _(v3.7.0)_ : The site ID to be used for Shlink visits. This will be ignored if `MATOMO_ENABLED` is false.
- `MATOMO_API_TOKEN` _(v3.7.0)_ : The API token so that Shlink can call Matomo's API. This will be ignored if `MATOMO_ENABLED` is false.


### Specific for the docker image {#specific-for-the-docker-image}


These are the env vars that only the docker image take into consideration:

- `PORT`: Can be used to set the port in which Shlink listens. Defaults to 8080 (Some cloud providers, like Google cloud or Heroku, expect to be able to customize exposed port by providing this env var).
- `WEB_WORKER_NUM`: The amount of concurrent http requests this Shlink instance will be able to serve. Defaults to the amount of available CPUs.
- `TASK_WORKER_NUM`: The amount of concurrent background tasks this Shlink instance will be able to execute. Defaults to the amount of available CPUs.
- `SKIP_INITIAL_GEOLITE_DOWNLOAD`: If provided with value `true`, it will skip the initial GeoLite2 db file download, speeding-up the container start-up. As a side effect, first visits on this container will remain un-located until the file finishes downloading in background.
- `INITIAL_API_KEY` _(v3.6.4)_ : An API key that will be created once during container start-up, with admin permissions.
  

> [!WARNING]
> **Considerations with the initial API key**
>
> * It will be ignored if other API keys already exist. * If the env var is removed at some point, that won't make the
> API key to be deleted. * If the value is changed at some point, that won't make the API key to be edited. * Between
> v3.3.0 and v3.6.3 it was possible to pass this env var to any non-docker Shlink instance, but that caused problems.
> Now only the docker image takes it into consideration. Use the [installation
> tool](/documentation/command-line-interface/installation-tool/#init) for non-docker installations.




### QR codes {#qr-codes}




> [!WARNING]
> Starting with Shlink 4.5.0, generating QR codes through Shlink is considered deprecated. See [this
> issue](https://github.com/shlinkio/shlink/issues/2408) for details.



- `DEFAULT_QR_CODE_SIZE`: A value between 50 and 1000 to determine the default size of generated QR codes when the `size` query param is not provided. Defaults to 300.
- `DEFAULT_QR_CODE_MARGIN`: A value greater than 0 to determine the default margin of generated QR codes when the `margin` query param is not provided. Defaults to 0.
- `DEFAULT_QR_CODE_FORMAT`: One of **png** or **svg**, to determine the default format of generated QR codes when the `format` query param is not provided. Defaults to png.
- `DEFAULT_QR_CODE_ERROR_CORRECTION`: One of **L** (Low), **M** (Medium), **Q** (Quartile) or **H** (High), to determine the default error correction of generated QR codes when the `errorCorrection` query param is not provided. Defaults to l.
- `DEFAULT_QR_CODE_ROUND_BLOCK_SIZE`: Tells if the block size should be round on QR codes, making it more readable, but potentially adding some extra margin as a side effect. Defaults to `true`.
- `QR_CODE_FOR_DISABLED_SHORT_URLS` _(v3.7.2)_ : Whether generating QR codes should work for disabled short URLs. Disabled short URLs are those which reached the maximum amount of visits, have a `validSince` date in the future, or a `validUntil` date in the past. Defaults to `true`.
- `DEFAULT_QR_CODE_COLOR` _(v4.0.0)_ : The QR code foreground color. Defaults to `#000000` (black).
- `DEFAULT_QR_CODE_BG_COLOR` _(v4.0.0)_ : The QR code background color. Defaults to `#FFFFFF` (white).
- `DEFAULT_QR_CODE_LOGO_URL` _(v4.0.0)_ : A URL pointing to a logo that will be placed in the middle of the QR code. This one is experimental, as some images might break the QR code.


## Secret env vars {#secret-env-vars}


Starting with Shlink 4.0.0, you can pass any environment variable with the `_FILE` suffix. When you do that, Shlink treats its value as a file path, reads that file, and uses its value as the corresponding non-suffixed env var.

For example, if `DB_PASSWORD` is not set, but `DB_PASSWORD_FILE` is, Shlink will read it, and return its contents as the `DB_PASSWORD` value.

This is useful when used in combination with [docker compose secrets](https://docs.docker.com/compose/use-secrets/), as it prevents env vars containing secrets to leak their values to any intermediary system.



> [!IMPORTANT]
> **Considerations with secret env vars**
>
> * The logic to parse secret env vars is generic, so you can use this approach with any existing or future environment
> variable. * The use of a `_FILE` suffix is a convention used by popular docker images. * If both the suffixed and
> non-suffixed env vars are provided (for example, `DB_PASSWORD` and `DB_PASSWORD_FILE`), the latter will be ignored.




## Considerations {#considerations}


There are a few things to have in mind.

- Shlink has always supported configuration via environment variables when using the official docker image. However, it only supports env vars for other approaches since v2.9.0
- Shlink also supports providing configuration options via the so-called [installation tool](https://sourcey-shlink.pages.dev/documentation/command-line-interface/installation-tool/index.md). This is an interactive CLI tool that generates some "hardcoded" configuration after being executed.
  Before Shlink 3.0.0, this configuration will always take precedence over env vars, so you cannot combine the two of them.
  This limitation is not present starting with Shlink 3.0.0, where environment variables always have precedence.
