Skip to content

Commit ca43819

Browse files
committed
Add init tasks docs
Signed-off-by: nscuro <nscuro@protonmail.com>
1 parent 0fd0569 commit ca43819

10 files changed

Lines changed: 130 additions & 48 deletions

File tree

docs/concepts/architecture/deployment.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ flowchart LR
3838
- **Frontend.** Static Vue.js single-page app, typically served by the same load balancer or a CDN.
3939
Stateless.
4040

41-
Each instance exposes a separate management server for health and metrics that starts before init
42-
tasks such as schema migration, so probes stay reachable while the main server initializes.
41+
Each instance exposes a separate management server for health and metrics that starts before
42+
[init tasks](../../reference/configuration/init-tasks.md) such as schema migration, so probes
43+
stay reachable while the main server initializes.
4344

4445
## Coordination
4546

docs/guides/administration/configuring-database.md

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ or extensions of it (for example [Neon] or [Timescale]), will most definitely wo
2626

2727
The same is not necessarily true for platforms based on heavily modified PostgreSQL, or even entire re-implementations
2828
such as [CockroachDB] or [YugabyteDB]. Such solutions make certain trade-offs to achieve higher levels of scalability,
29-
which might impact functionality that Dependency-Track relies on. If you'd like to see support for those, please [let us know].
29+
which might impact functionality that Dependency-Track relies on.
3030

3131
### Self-hosting
3232

@@ -172,12 +172,12 @@ centralised connection pools such as [PgBouncer].
172172
Before proceeding, take note of the following constraints:
173173

174174
* Only `session` and `transaction` pooling modes are supported. `transaction` is recommended.
175-
* Initialisation tasks, which include database migrations, **must** connect to the
175+
* [Init tasks](../../reference/configuration/init-tasks.md) **must** connect to the
176176
database directly, bypassing the connection pooler, when using pooling mode `transaction`.
177-
* To prevent concurrent initialisation, session-level PostgreSQL advisory locks are used,
178-
which are not supported with the `transaction` pooling mode.
179-
* To facilitate this, initialisation tasks can be executed in dedicated containers,
180-
and / or using separate data sources.
177+
Init tasks coordinate across instances using session-level PostgreSQL advisory locks,
178+
which are not supported with the `transaction` pooling mode. Route them through a
179+
separate data source that connects to PostgreSQL directly, run them in a
180+
dedicated container, or configure both.
181181

182182
### Example
183183

@@ -224,25 +224,6 @@ services:
224224
DT_INIT_TASKS_DATASOURCE_NAME: "init"
225225
```
226226

227-
## Schema migration credentials
228-
229-
It is possible to use different credentials for migrations than for the application itself.
230-
This can be achieved by configuring a separate data source, and instructing the init tasks to use it:
231-
232-
```ini linenums="1"
233-
# Configure a data source named "init-tasks".
234-
dt.datasource.init-tasks.url=jdbc:postgresql://localhost:5432/dtrack
235-
dt.datasource.init-tasks.username=my-init-task-user
236-
dt.datasource.init-tasks.password=my-init-task-pass
237-
238-
# Configure init tasks to use the data source.
239-
init.tasks.datasource.name=init-tasks
240-
241-
# If the data source is only meant for init tasks, there is no need to
242-
# keep it around after the tasks completed.
243-
init.tasks.datasource.close-after-use=true
244-
```
245-
246227
[Autovacuum]: https://www.postgresql.org/docs/current/routine-vacuuming.html
247228
[CockroachDB]: https://www.cockroachlabs.com/
248229
[Neon]: https://neon.tech/
@@ -251,6 +232,5 @@ init.tasks.datasource.close-after-use=true
251232
[Postgres Operator]: https://github.com/zalando/postgres-operator
252233
[Timescale]: https://www.timescale.com/
253234
[YugabyteDB]: https://www.yugabyte.com/
254-
[let us know]: https://github.com/DependencyTrack/hyades/issues/new?assignees=&labels=enhancement&projects=&template=enhancement-request.yml
255235
[list of well-known commercial hosting providers]: https://www.postgresql.org/support/professional_hosting/
256236
[official upgrading guide]: https://www.postgresql.org/docs/current/upgrading.html

docs/guides/administration/configuring-observability.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,10 @@ containers:
4141
periodSeconds: 5
4242
```
4343
44-
The aggregate endpoint `/health` returns the combined status of all checks.
44+
The startup probe at `/health/started` reports per-task progress while
45+
[init tasks](../../reference/configuration/init-tasks.md) run, then turns
46+
healthy once the main server is ready. The aggregate endpoint `/health`
47+
returns the combined status of all checks.
4548

4649
## Enabling Prometheus metrics scraping
4750

docs/guides/administration/upgrading-instances.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ The durable execution engine, leader election, and
1111
to replace one API server instance at a time as long as:
1212

1313
- The release notes describe no breaking schema changes that require all instances to stop.
14-
- The destination version's Liquibase migrations are additive against the running schema.
14+
- The destination version's Flyway migrations are additive against the running schema.
1515
- More than one instance is running. A single-instance deployment cannot upgrade without downtime.
1616

1717
If any of these conditions fail, plan a full-stop upgrade window instead.
@@ -23,7 +23,7 @@ If any of these conditions fail, plan a full-stop upgrade window instead.
2323
full-stop upgrade if any release calls for one.
2424
- If you run schema migrations in a dedicated container (recommended for large deployments and
2525
PgBouncer in transaction mode), plan to run it before any new-version API server starts. See
26-
[Schema migration credentials](configuring-database.md#schema-migration-credentials).
26+
[init-only containers](../../reference/configuration/init-tasks.md#init-only-containers).
2727

2828
## Rolling upgrade
2929

@@ -38,9 +38,6 @@ condition listed earlier is what makes that safe: the old version must keep work
3838
migrated schema for the duration of the roll-out. Cap the roll-out to a single deploy window. Do
3939
not leave the cluster running mixed versions indefinitely.
4040

41-
If a migration fails partway and leaves the Liquibase change-log lock held, clear the lock in
42-
PostgreSQL before retrying the upgrade.
43-
4441
## Web/worker split
4542

4643
When the cluster [splits API and worker traffic](scaling.md#separate-api-traffic-from-background-work),

docs/guides/upgrading/v0.7.0-alpha.3.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@
140140
Update your configurations at your earliest convenience.
141141

142142
* **Health and metrics endpoints have moved to a dedicated management server** that listens
143-
on a separate port (default `9000`). The management server starts before init tasks, making
143+
on a separate port (default `9000`). The management server starts before
144+
[init tasks](../../reference/configuration/init-tasks.md), making
144145
health probes available during the entire startup sequence.
145146

146147
| Endpoint | Before | After |
@@ -160,7 +161,7 @@
160161
* `init.tasks.database.url`
161162
* `init.tasks.database.username`
162163
* `init.tasks.database.password`
163-
* Refer to [schema migration credentials](../administration/configuring-database.md#schema-migration-credentials)
164-
for an example of how to run init tasks with separate database credentials.
164+
* Refer to [Init tasks](../../reference/configuration/init-tasks.md#data-source)
165+
for how to configure a dedicated data source for init tasks.
165166

166167
[hyades/#1910]: https://github.com/DependencyTrack/hyades/issues/1910

docs/guides/upgrading/v5.0.0-rc.2.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
| `dt.http.timeout.connection` (seconds) | `dt.http.connect-timeout-ms` (milliseconds, default `30000`) |
7979
| `dt.no.proxy` | `dt.http.proxy.exclusions` |
8080

81-
**Init tasks**
81+
**[Init tasks](../../reference/configuration/init-tasks.md)**
8282

8383
| Old | New |
8484
| --- | --- |

docs/reference/configuration/.pages

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ nav:
55
- Database: database.md
66
- Durable execution engine: dex-engine.md
77
- File storage: file-storage.md
8+
- Init tasks: init-tasks.md
89
- Task scheduler: task-scheduler.md
910
- Telemetry: telemetry.md
1011
- All properties: properties.md

docs/reference/configuration/database.md

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,10 @@ For context on when and why to apply these, see the
109109

110110
## Schema Migrations
111111

112-
Schema migrations are performed automatically by the API server upon startup using [Liquibase].
113-
Usually no manual action is required when upgrading from an older Dependency-Track version, unless explicitly
114-
stated otherwise in the release notes.
112+
Schema migrations run on startup as an [init task](init-tasks.md), using [Flyway].
113+
No manual action is required when upgrading from an older Dependency-Track version,
114+
unless explicitly stated otherwise in the [upgrade guides](../../guides/upgrading).
115115

116-
This behaviour can be turned off by setting [`init.tasks.enabled`](properties.md#dtinittasksenabled)
117-
on the API server container to `false`.
118-
119-
For configuring separate migration credentials, see the
120-
[schema migration credentials guide](../../guides/administration/configuring-database.md#schema-migration-credentials).
121-
122-
[Liquibase]: https://www.liquibase.com/
116+
[Flyway]: https://www.red-gate.com/products/flyway/
123117
[PostgreSQL]: https://www.postgresql.org/
124118
[newest available version]: https://www.postgresql.org/support/versioning/

docs/reference/configuration/datasources.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,24 @@ via [`dt.secret-management.database.datasource.name`](properties.md#dtsecret-man
5151
data sources as you like, but unless they're being used by a feature,
5252
they will not be created.
5353

54+
## Privileges
55+
56+
The user configured for the `default` data source must hold privileges to perform
57+
DDL against the Dependency-Track schema. The API server issues DDL during normal
58+
operation:
59+
60+
* On startup, by running [init tasks](init-tasks.md) (schema migrations,
61+
extension creation, partition setup, seeding).
62+
* At runtime, by creating and dropping [table partitions] to manage
63+
[time series metrics retention](../../concepts/time-series-metrics.md#daily-partitions-and-bounded-retention).
64+
65+
!!! warning
66+
Configuring an unprivileged user for the `default` data source is not supported.
67+
A user restricted to `SELECT`, `INSERT`, `UPDATE`, and `DELETE` will cause runtime
68+
failures even after a successful startup.
69+
70+
Grant the user ownership of the database, or of the Dependency-Track schema within it.
71+
5472
## Connection Pool Properties
5573

5674
The following properties control local connection pooling per data source:
@@ -73,3 +91,4 @@ For centralised connection pooling with PgBouncer, see the
7391
[database configuration guide](../../guides/administration/configuring-database.md#centralised-connection-pooling).
7492

7593
[configuration reference]: database.md
94+
[table partitions]: https://www.postgresql.org/docs/current/ddl-partitioning.html
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Init tasks
2+
3+
Init tasks are one-time operations the API server performs at startup, before
4+
the main server begins serving traffic. They prepare the database schema, seed
5+
default objects, and bring the durable execution engine to a consistent state.
6+
7+
## Lifecycle
8+
9+
Init tasks run before the HTTP listener starts and before background workers
10+
initialize. They block startup. If any task fails, the JVM exits and the
11+
container does not begin serving traffic.
12+
13+
The management server starts before init tasks run and exposes the
14+
[startup health endpoint](../../guides/administration/configuring-observability.md#configuring-kubernetes-health-probes)
15+
at `/health/started`, which reports per-task status (`STARTED`, `COMPLETED`,
16+
`FAILED`) during execution.
17+
18+
By default, init tasks run in every API server container. To coordinate across
19+
instances, the executor acquires a session-level PostgreSQL [advisory lock],
20+
so only one container performs each task at a time. Remaining containers wait
21+
for the lock, then confirm there is nothing left to do.
22+
23+
!!! warning
24+
Session-level advisory locks are incompatible with PgBouncer in
25+
`transaction` pooling mode. When using a transaction-mode connection
26+
pooler, configure a separate [init data source](#data-source) that
27+
connects directly to PostgreSQL.
28+
29+
## Tasks
30+
31+
| Task | Purpose | Enable property |
32+
|------|---------|-----------------|
33+
| Database migration | Runs [Flyway](database.md#schema-migrations) migrations against the Dependency-Track schema. Creates required [extensions](database.md#extensions). | [`dt.init-task.database-migration.enabled`](properties.md#dtinit-taskdatabase-migrationenabled) |
34+
| Database partition maintenance | Creates [table partitions] required for [time series metrics](../../concepts/time-series-metrics.md). | [`dt.init-task.database-partition-maintenance.enabled`](properties.md#dtinit-taskdatabase-partition-maintenanceenabled) |
35+
| Database seeding | Populates default permissions, teams, users, licenses, license groups, repositories, and configuration properties. Idempotent. Skips on later startups when the build identifier has not changed. | [`dt.init-task.database-seeding.enabled`](properties.md#dtinit-taskdatabase-seedingenabled) |
36+
| Dex engine database migration | Runs schema migrations for the [durable execution engine](dex-engine.md). | [`dt.init-task.dex-engine-database-migration.enabled`](properties.md#dtinit-taskdex-engine-database-migrationenabled) |
37+
38+
Per-task enable properties take effect only when
39+
[`dt.init-tasks.enabled`](properties.md#dtinit-tasksenabled) is `true`.
40+
41+
## Data source
42+
43+
By default, init tasks use the `default` [data source](datasources.md).
44+
Override this with
45+
[`dt.init-tasks.datasource.name`](properties.md#dtinit-tasksdatasourcename)
46+
to route them through a separate connection pool.
47+
48+
The most common reason: centralized connection pooling with PgBouncer in
49+
`transaction` mode, which requires init tasks to bypass the pooler and
50+
connect to PostgreSQL directly. The default data source connects through
51+
PgBouncer, while the init data source connects to PostgreSQL directly so
52+
session-level advisory locks remain usable. See
53+
[centralized connection pooling](../../guides/administration/configuring-database.md#centralised-connection-pooling)
54+
for an example.
55+
56+
When the init data source exists solely to serve init tasks, set
57+
[`dt.init-tasks.datasource.close-after-completion`](properties.md#dtinit-tasksdatasourceclose-after-completion)
58+
to `true`. The API server closes the connection pool once tasks finish,
59+
freeing its connections.
60+
61+
## Init-only containers
62+
63+
Setting
64+
[`dt.init-tasks.exit-after-completion`](properties.md#dtinit-tasksexit-after-completion)
65+
to `true` causes the JVM to exit with status `0` once init tasks succeed,
66+
without starting the main server. This supports a dedicated init container
67+
pattern, where a short-lived container runs init tasks and exits before
68+
long-lived API server containers start.
69+
70+
In this pattern, the long-lived containers set
71+
[`dt.init-tasks.enabled`](properties.md#dtinit-tasksenabled) to `false` to
72+
skip init tasks on startup.
73+
74+
## Configuration
75+
76+
* [`dt.init-tasks.enabled`](properties.md#dtinit-tasksenabled)
77+
* [`dt.init-tasks.datasource.name`](properties.md#dtinit-tasksdatasourcename)
78+
* [`dt.init-tasks.datasource.close-after-completion`](properties.md#dtinit-tasksdatasourceclose-after-completion)
79+
* [`dt.init-tasks.exit-after-completion`](properties.md#dtinit-tasksexit-after-completion)
80+
* [`dt.init-task.database-migration.enabled`](properties.md#dtinit-taskdatabase-migrationenabled)
81+
* [`dt.init-task.database-partition-maintenance.enabled`](properties.md#dtinit-taskdatabase-partition-maintenanceenabled)
82+
* [`dt.init-task.database-seeding.enabled`](properties.md#dtinit-taskdatabase-seedingenabled)
83+
* [`dt.init-task.dex-engine-database-migration.enabled`](properties.md#dtinit-taskdex-engine-database-migrationenabled)
84+
85+
[advisory lock]: https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS
86+
[table partitions]: https://www.postgresql.org/docs/current/ddl-partitioning.html

0 commit comments

Comments
 (0)