Repository: juanfont/headscale

Issue:
[Bug] Dead link to container docs in 0.23.0 changelog, possible buggy documentation
### Is this a support request?

- [X] This is not a support request

### Is there an existing issue for this?

- [X] I have searched the existing issues

### Current Behavior

A. The changelog contains a dead link to the container docs:

https://github.com/juanfont/headscale/blob/main/CHANGELOG.md?plain=1#L256
points to https://github.com/juanfont/headscale/blob/main/docs/running-headscale-container.md

That leads to a 404.

B. The changelog and the correct docs at https://github.com/juanfont/headscale/blob/main/docs/setup/install/container.md are confusing or seem lacking or even incorrect when it comes to /var/lib/headscale or /var/run/headscale. The example config uses these directories, but the changelog says these are not created anymore while the container docs do not hint about creating a volume for it (despite mentioning confusingly to "alternatively" mount them from the host system. alternatively to what?) I think this needs a review :smile: 

### Expected Behavior

A. fixed changelog 
B. Review 

:smile: 

### Steps To Reproduce

- See above -

### Environment

```markdown
- OS: Linux
- Headscale version: 0.23.x
- Tailscale version: not relevant
```


### Runtime environment

- [ ] Headscale is behind a (reverse) proxy
- [X] Headscale runs in a container

### Anything else?

_No response_

Discussion:
@github-actions: This issue is stale because it has been open for 90 days with no activity.

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f1965455..ffa0b104 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -164,13 +164,14 @@ This will also affect the way you
 - Fixed updating of hostname and givenName when it is updated in HostInfo
   [#2199](https://github.com/juanfont/headscale/pull/2199)
 - Fixed missing `stable-debug` container tag
-  [#2232](https://github.com/juanfont/headscale/pr/2232)
+  [#2232](https://github.com/juanfont/headscale/pull/2232)
 - Loosened up `server_url` and `base_domain` check. It was overly strict in some
   cases. [#2248](https://github.com/juanfont/headscale/pull/2248)
 - CLI for managing users now accepts `--identifier` in addition to `--name`,
   usage of `--identifier` is recommended
   [#2261](https://github.com/juanfont/headscale/pull/2261)
 - Add `dns.extra_records_path` configuration option [#2262](https://github.com/juanfont/headscale/issues/2262)
+- Support client verify for DERP [#2046](https://github.com/juanfont/headscale/pull/2046)
 
 ## 0.23.0 (2024-09-18)
 
@@ -253,7 +254,7 @@ part of adopting [#1460](https://github.com/juanfont/headscale/pull/1460).
   - Entrypoint of container image has changed from shell to headscale, require
     change from `headscale serve` to `serve`
   - `/var/lib/headscale` and `/var/run/headscale` is no longer created
-    automatically, see [container docs](./docs/running-headscale-container.md)
+    automatically, see [container docs](./docs/setup/install/container.md)
 - Prefixes are now defined per v4 and v6 range.
   [#1756](https://github.com/juanfont/headscale/pull/1756)
   - `ip_prefixes` option is now `prefixes.v4` and `prefixes.v6`
@@ -643,7 +644,7 @@ part of adopting [#1460](https://github.com/juanfont/headscale/pull/1460).
 
 - Boundaries between Namespaces has been removed and all nodes can communicate
   by default [#357](https://github.com/juanfont/headscale/pull/357)
-  - To limit access between nodes, use [ACLs](./docs/acls.md).
+  - To limit access between nodes, use [ACLs](./docs/ref/acls.md).
 - `/metrics` is now a configurable host:port endpoint:
   [#344](https://github.com/juanfont/headscale/pull/344). You must update your
   `config.yaml` file to include:
@@ -701,13 +702,12 @@ behaviour.
   - All machines can communicate with all machines by default
   - Tags should now work correctly and adding a host to Headscale should now
     reload the rules.
-  - The documentation have a [fictional example](docs/acls.md) that should cover
+  - The documentation have a [fictional example](./docs/ref/acls.md) that should cover
     some use cases of the ACLs features
 
 ### Features
 
-- Add support for configurable mTLS
-  [docs](docs/tls.md#configuring-mutual-tls-authentication-mtls)
+- Add support for configurable mTLS [docs](./docs/ref/tls.md)
   [#297](https://github.com/juanfont/headscale/pull/297)
 
 ### Changes
@@ -721,7 +721,7 @@ behaviour.
 
 - Add IPv6 support to the prefix assigned to namespaces
 - Add API Key support
-  - Enable remote control of `headscale` via CLI [docs](docs/remote-cli.md)
+  - Enable remote control of `headscale` via CLI [docs](./docs/ref/remote-cli.md)
   - Enable HTTP API (beta, subject to change)
 - OpenID Connect users will be mapped per namespaces
   - Each user will get its own namespace, created if it does not exist
diff --git a/Makefile b/Makefile
index 5b09147d..25fa1c67 100644
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ build:
 dev: lint test build
 
 test:
-	gotestsum -- -short -coverprofile=coverage.out ./...
+	gotestsum -- -short -race -coverprofile=coverage.out ./...
 
 test_integration:
 	docker run \
@@ -33,7 +33,7 @@ test_integration:
 		-v /var/run/docker.sock:/var/run/docker.sock \
 		-v $$PWD/control_logs:/tmp/control \
 		golang:1 \
-		go run gotest.tools/gotestsum@latest -- -failfast ./... -timeout 120m -parallel 8
+		go run gotest.tools/gotestsum@latest -- -race -failfast ./... -timeout 120m -parallel 8
 
 lint:
 	golangci-lint run --fix --timeout 10m
diff --git a/config-example.yaml b/config-example.yaml
index 529a80ed..cb7bf4da 100644
--- a/config-example.yaml
+++ b/config-example.yaml
@@ -301,7 +301,7 @@ dns:
   search_domains: []
 
   # Extra DNS records
-  # so far only A-records are supported (on the tailscale side)
+  # so far only A and AAAA records are supported (on the tailscale side)
   # See: docs/ref/dns.md
   extra_records: []
   #   - name: "grafana.myvpn.example.com"
@@ -310,6 +310,10 @@ dns:
   #
   #   # you can also put it in one line
   #   - { name: "prometheus.myvpn.example.com", type: "A", value: "100.64.0.3" }
+  #
+  # Alternatively, extra DNS records can be loaded from a JSON file.
+  # Headscale processes this file on each change.
+  # extra_records_path: /var/lib/headscale/extra-records.json
 
 # Unix socket used for the CLI to connect without authentication
 # Note: for production you will want to set this to something like:
diff --git a/docs/about/features.md b/docs/about/features.md
index 80e94874..21b5fb6d 100644
--- a/docs/about/features.md
+++ b/docs/about/features.md
@@ -12,7 +12,7 @@ provides on overview of headscale's feature and compatibility with the Tailscale
     - [x] [MagicDNS](https://tailscale.com/kb/1081/magicdns)
     - [x] [Global and restricted nameservers (split DNS)](https://tailscale.com/kb/1054/dns#nameservers)
     - [x] [search domains](https://tailscale.com/kb/1054/dns#search-domains)
-    - [x] [Extra DNS records (headscale only)](../ref/dns.md#setting-custom-dns-records)
+    - [x] [Extra DNS records (headscale only)](../ref/dns.md#setting-extra-dns-records)
 - [x] [Taildrop (File Sharing)](https://tailscale.com/kb/1106/taildrop)
 - [x] Routing advertising (including exit nodes)
 - [x] Dual stack (IPv4 and IPv6)
@@ -25,6 +25,7 @@ provides on overview of headscale's feature and compatibility with the Tailscale
     - [ ] `autogroup:member`
 * [ ] Node registration using Single-Sign-On (OpenID Connect) ([GitHub label "OIDC"](https://github.com/juanfont/headscale/labels/OIDC))
     - [x] Basic registration
+    - [ ] Update user profile from identity provider
     - [ ] Dynamic ACL support
     - [ ] OIDC groups cannot be used in ACLs
 - [ ] [Funnel](https://tailscale.com/kb/1223/funnel) ([#1040](https://github.com/juanfont/headscale/issues/1040))
diff --git a/docs/ref/acls.md b/docs/ref/acls.md
index d7ceb629..c5f7d55e 100644
--- a/docs/ref/acls.md
+++ b/docs/ref/acls.md
@@ -40,9 +40,6 @@ servers.
 
 ## ACL setup
 
-Note: Users will be created automatically when users authenticate with the
-headscale server.
-
 ACLs have to be written in [huJSON](https://github.com/tailscale/hujson).
 
 When [registering the servers](../usage/getting-started.md#register-a-node) we
@@ -52,11 +49,17 @@ tags to a server they can register, the check of the tags is done on headscale
 server and only valid tags are applied. A tag is valid if the user that is
 registering it is allowed to do it.
 
-To use ACLs in headscale, you must edit your `config.yaml` file. In there you will find a `policy.path` parameter. This will need to point to your ACL file. More info on how these policies are written can be found [here](https://tailscale.com/kb/1018/acls/).
+To use ACLs in headscale, you must edit your `config.yaml` file. In there you will find a `policy.path` parameter. This
+will need to point to your ACL file. More info on how these policies are written can be found
+[here](https://tailscale.com/kb/1018/acls/).
+
+Please reload or restart Headscale after updating the ACL file. Headscale may be reloaded either via its systemd service
+(`sudo systemctl reload headscale`) or by sending a SIGHUP signal (`sudo kill -HUP $(pidof headscale)`) to the main
+process. Headscale logs the result of ACL policy processing after each reload.
 
 Here are the ACL's to implement the same permissions as above:
 
-```json
+```json title="acl.json"
 {
   // groups are collections of users having a common scope. A user can be in multiple groups
   // groups cannot be composed of groups
diff --git a/docs/ref/dns.md b/docs/ref/dns.md
index 1e3ad897..9eaa5245 100644
--- a/docs/ref/dns.md
+++ b/docs/ref/dns.md
@@ -1,44 +1,76 @@
 # DNS
 
-Headscale supports [most DNS features](../about/features.md) from Tailscale and DNS releated settings can be configured
-in the [configuration file](./configuration.md) within the `dns` section.
+Headscale supports [most DNS features](../about/features.md) from Tailscale. DNS releated settings can be configured
+within `dns` section of the [configuration file](./configuration.md).
 
-## Setting custom DNS records
+## Setting extra DNS records
 
-!!! warning "Community documentation"
+Headscale allows to set extra DNS records which are made available via
+[MagicDNS](https://tailscale.com/kb/1081/magicdns). Extra DNS records can be configured either via static entries in the
+[configuration file](./configuration.md) or from a JSON file that Headscale continously watches for changes:
 
-    This page is not actively maintained by the headscale authors and is
-    written by community members. It is _not_ verified by headscale developers.
+* Use the `dns.extra_records` option in the [configuration file](./configuration.md) for entries that are static and
+  don't change while Headscale is running. Those entries are processed when Headscale is starting up and changes to the
+  configuration require a restart of Headscale.
+* For dynamic DNS records that may be added, updated or removed while Headscale is running or DNS records that are
+  generated by scripts the option `dns.extra_records_path` in the [configuration file](./configuration.md) is useful.
+  Set it to the absolute path of the JSON file containing DNS records and Headscale processes this file as it detects
+  changes.
 
-    **It might be outdated and it might miss necessary steps**.
-
-Headscale allows to set custom DNS records which are made available via
-[MagicDNS](https://tailscale.com/kb/1081/magicdns). An example use case is to serve multiple apps on the same host via a
-reverse proxy like NGINX, in this case a Prometheus monitoring stack. This allows to nicely access the service with
-"http://grafana.myvpn.example.com" instead of the hostname and port combination
-"http://hostname-in-magic-dns.myvpn.example.com:3000".
+An example use case is to serve multiple apps on the same host via a reverse proxy like NGINX, in this case a Prometheus
+monitoring stack. This allows to nicely access the service with "http://grafana.myvpn.example.com" instead of the
+hostname and port combination "http://hostname-in-magic-dns.myvpn.example.com:3000".
 
 !!! warning "Limitations"
 
-    [Not all types of records are supported](https://github.com/tailscale/tailscale/blob/6edf357b96b28ee1be659a70232c0135b2ffedfd/ipn/ipnlocal/local.go#L2989-L3007), especially no CNAME records.
+    Currently, [only A and AAAA records are processed by Tailscale](https://github.com/tailscale/tailscale/blob/v1.78.3/ipn/ipnlocal/local.go#L4461-L4479).
 
-1.  Update the [configuration file](./configuration.md) to contain the desired records like so:
 
-    ```yaml
-    dns:
-      ...
-      extra_records:
-        - name: "prometheus.myvpn.example.com"
-          type: "A"
-          value: "100.64.0.3"
+1.  Configure extra DNS records using one of the available configuration options:
 
-        - name: "grafana.myvpn.example.com"
-          type: "A"
-          value: "100.64.0.3"
-      ...
-    ```
+    === "Static entries, via `dns.extra_records`"
+
+        ```yaml title="config.yaml"
+        dns:
+          ...
+          extra_records:
+            - name: "grafana.myvpn.example.com"
+              type: "A"
+              value: "100.64.0.3"
+
+            - name: "prometheus.myvpn.example.com"
+              type: "A"
+              value: "100.64.0.3"
+          ...
+        ```
 
-1.  Restart your headscale instance.
+        Restart your headscale instance.
+
+    === "Dynamic entries, via `dns.extra_records_path`"
+
+        ```json title="extra-records.json"
+        [
+          {
+            "name": "grafana.myvpn.example.com",
+            "type": "A",
+            "value": "100.64.0.3"
+          },
+          {
+            "name": "prometheus.myvpn.example.com",
+            "type": "A",
+            "value": "100.64.0.3"
+          }
+        ]
+        ```
+
+        Headscale picks up changes to the above JSON file automatically.
+
+        !!! tip "Good to know"
+
+            * The `dns.extra_records_path` option in the [configuration file](./configuration.md) needs to reference the
+              JSON file containing extra DNS records.
+            * Be sure to "sort keys" and produce a stable output in case you generate the JSON file with a script.
+              Headscale uses a checksum to detect changes to the file and a stable output avoids unnecessary processing.
 
 1.  Verify that DNS records are properly set using the DNS querying tool of your choice:
 
@@ -61,7 +93,7 @@ reverse proxy like NGINX, in this case a Prometheus monitoring stack. This allow
     The motivating example here was to be able to access internal monitoring services on the same host without
     specifying a port, depicted as NGINX configuration snippet:
 
-    ```
+    ```nginx title="nginx.conf"
     server {
         listen 80;
         listen [::]:80;
diff --git a/docs/ref/integration/reverse-proxy.md b/docs/ref/integration/reverse-proxy.md
index a50e894a..91ee8dfc 100644
--- a/docs/ref/integration/reverse-proxy.md
+++ b/docs/ref/integration/reverse-proxy.md
@@ -23,7 +23,7 @@ Running headscale behind a cloudflare proxy or cloudflare tunnel is not supporte
 
 Headscale can be configured not to use TLS, leaving it to the reverse proxy to handle. Add the following configuration values to your headscale config file.
 
-```yaml
+```yaml title="config.yaml"
 server_url: https://<YOUR_SERVER_NAME> # This should be the FQDN at which headscale will be served
 listen_addr: 0.0.0.0:8080
 metrics_listen_addr: 0.0.0.0:9090
@@ -35,7 +35,7 @@ tls_key_path: ""
 
 The following example configuration can be used in your nginx setup, substituting values as necessary. `<IP:PORT>` should be the IP address and port where headscale is running. In most cases, this will be `http://localhost:8080`.
 
-```Nginx
+```nginx title="nginx.conf"
 map $http_upgrade $connection_upgrade {
     default      upgrade;
     ''           close;
@@ -113,7 +113,7 @@ spec:
 
 The following Caddyfile is all that is necessary to use Caddy as a reverse proxy for headscale, in combination with the `config.yaml` specifications above to disable headscale's built in TLS. Replace values as necessary - `<YOUR_SERVER_NAME>` should be the FQDN at which headscale will be served, and `<IP:PORT>` should be the IP address and port where headscale is running. In most cases, this will be `localhost:8080`.
 
-```
+```none title="Caddyfile"
 <YOUR_SERVER_NAME> {
     reverse_proxy <IP:PORT>
 }
@@ -127,7 +127,7 @@ For a slightly more complex configuration which utilizes Docker containers to ma
 
 The following minimal Apache config will proxy traffic to the headscale instance on `<IP:PORT>`. Note that `upgrade=any` is required as a parameter for `ProxyPass` so that WebSockets traffic whose `Upgrade` header value is not equal to `WebSocket` (i. e. Tailscale Control Protocol) is forwarded correctly. See the [Apache docs](https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html) for more information on this.
 
-```
+```apache title="apache.conf"
 <VirtualHost *:443>
 	ServerName <YOUR_SERVER_NAME>
 
diff --git a/docs/ref/oidc.md b/docs/ref/oidc.md
index 734184df..6bc45572 100644
--- a/docs/ref/oidc.md
+++ b/docs/ref/oidc.md
@@ -11,7 +11,7 @@ Known limitations:
 
 In your `config.yaml`, customize this to your liking:
 
-```yaml
+```yaml title="config.yaml"
 oidc:
   # Block further startup until the OIDC provider is healthy and available
   only_start_if_oidc_is_available: true
@@ -56,7 +56,7 @@ oidc:
 
 In order to integrate headscale with Azure Active Directory, we'll need to provision an App Registration with the correct scopes and redirect URI. Here with Terraform:
 
-```hcl
+```hcl title="terraform.hcl"
 resource "azuread_application" "headscale" {
   display_name = "Headscale"
 
@@ -127,7 +127,7 @@ output "headscale_client_secret" {
 
 And in your headscale `config.yaml`:
 
-```yaml
+```yaml title="config.yaml"
 oidc:
   issuer: "https://login.microsoftonline.com/<tenant-UUID>/v2.0"
   client_id: "<client-id-from-terraform>"
@@ -162,7 +162,7 @@ However if you don't have a domain, or need to add users outside of your domain,
 8. Click `Save` at the bottom of the form
 9. Take note of the `Client ID` and `Client secret`, you can also download it for reference if you need it.
 10. Edit your headscale config, under `oidc`, filling in your `client_id` and `client_secret`:
-    ```yaml
+    ```yaml title="config.yaml"
     oidc:
       issuer: "https://accounts.google.com"
       client_id: ""
diff --git a/docs/ref/remote-cli.md b/docs/ref/remote-cli.md
index d50359c2..10c7534f 100644
--- a/docs/ref/remote-cli.md
+++ b/docs/ref/remote-cli.md
@@ -54,7 +54,7 @@ headscale apikeys expire --prefix "<PREFIX>"
 
     === "Minimal YAML configuration file"
 
-        ```yaml
+        ```yaml title="config.yaml"
         cli:
             address: <HEADSCALE_ADDRESS>:<PORT>
             api_key: <API_KEY_FROM_PREVIOUS_STEP>
@@ -69,7 +69,7 @@ headscale apikeys expire --prefix "<PREFIX>"
 
         !!! bug
 
-            Headscale 0.23.0 requires at least an empty configuration file when environment variables are used to
+            Headscale currently requires at least an empty configuration file when environment variables are used to
             specify connection details. See [issue 2193](https://github.com/juanfont/headscale/issues/2193) for more
             information.
 
diff --git a/docs/ref/tls.md b/docs/ref/tls.md
index 23bc82a4..d1e91016 100644
--- a/docs/ref/tls.md
+++ b/docs/ref/tls.md
@@ -4,7 +4,7 @@
 
 Headscale can be configured to expose its web service via TLS. To configure the certificate and key file manually, set the `tls_cert_path` and `tls_cert_path` configuration parameters. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.
 
-```yaml
+```yaml title="config.yaml"
 tls_cert_path: ""
 tls_key_path: ""
 ```
@@ -15,7 +15,7 @@ The certificate should contain the full chain, else some clients, like the Tails
 
 To get a certificate automatically via [Let's Encrypt](https://letsencrypt.org/), set `tls_letsencrypt_hostname` to the desired certificate hostname. This name must resolve to the IP address(es) headscale is reachable on (i.e., it must correspond to the `server_url` configuration parameter). The certificate and Let's Encrypt account credentials will be stored in the directory configured in `tls_letsencrypt_cache_dir`. If the path is relative, it will be interpreted as relative to the directory the configuration file was read from.
 
-```yaml
+```yaml title="config.yaml"
 tls_letsencrypt_hostname: ""
 tls_letsencrypt_listen: ":http"
 tls_letsencrypt_cache_dir: ".cache"
diff --git a/docs/setup/install/cloud.md b/docs/setup/install/cloud.md
deleted file mode 100644
index 99e6c74b..00000000
--- a/docs/setup/install/cloud.md
+++ /dev/null
@@ -1,25 +0,0 @@
-# Running headscale in a cloud
-
-!!! warning "Community documentation"
-
-    This page is not actively maintained by the headscale authors and is
-    written by community members. It is _not_ verified by headscale developers.
-
-    **It might be outdated and it might miss necessary steps**.
-
-## Sealos
-
-[Deploy headscale as service on Sealos.](https://icloudnative.io/en/posts/how-to-set-up-or-migrate-headscale/)
-
-1. Click the following prebuilt template:
-
-   [![](https://cdn.jsdelivr.net/gh/labring-actions/templates@main/Deploy-on-Sealos.svg)](https://cloud.sealos.io/?openapp=system-template%3FtemplateName%3Dheadscale)
-
-2. Click "Deploy Application" on the template page to start deployment. Upon completion, two applications appear: headscale, and one of its [web interfaces](../../ref/integration/web-ui.md).
-3. Once deployment concludes, click 'Details' on the headscale application page to navigate to the application's details.
-4. Wait for the application's status to switch to running. For accessing the headscale server, the Public Address associated with port 8080 is the address of the headscale server. To access the headscale console, simply append `/admin/` to the headscale public URL.
-
-!!! tip "Remote CLI"
-
-    Headscale can be managed remotely via its remote CLI support. See our [Controlling headscale with remote
-    CLI](../../ref/remote-cli.md) documentation for details.
diff --git a/docs/setup/install/official.md b/docs/setup/install/official.md
index d3f307f5..0bd59499 100644
--- a/docs/setup/install/official.md
+++ b/docs/setup/install/official.md
@@ -94,7 +94,7 @@ systemd.
 1.  In `/etc/headscale/config.yaml`, override the default `headscale` unix socket with a path that is writable by the
     `headscale` user or group:
 
-    ```yaml
+    ```yaml title="config.yaml"
     unix_socket: /var/run/headscale/headscale.sock
     ```
 
diff --git a/docs/setup/upgrade.md b/docs/setup/upgrade.md
index e518a7b5..9c72eb4f 100644
--- a/docs/setup/upgrade.md
+++ b/docs/setup/upgrade.md
@@ -1,6 +1,6 @@
 # Upgrade an existing installation
 
-An existing headscale installation can be updated to a new version:
+Update an existing headscale installation to a new version:
 
 - Read the announcement on the [GitHub releases](https://github.com/juanfont/headscale/releases) page for the new
   version. It lists the changes of the release along with possible breaking changes.
diff --git a/integration/scenario.go b/integration/scenario.go
index 99a25647..987b8dbe 100644
--- a/integration/scenario.go
+++ b/integration/scenario.go
@@ -372,18 +372,22 @@ func (s *Scenario) CreateTailscaleNodesInUser(
 			cert := headscale.GetCert()
 			hostname := headscale.GetHostname()
 
+			s.mu.Lock()
 			opts = append(opts,
 				tsic.WithCACert(cert),
 				tsic.WithHeadscaleName(hostname),
 			)
+			s.mu.Unlock()
 
 			user.createWaitGroup.Go(func() error {
+				s.mu.Lock()
 				tsClient, err := tsic.New(
 					s.pool,
 					version,
 					s.network,
 					opts...,
 				)
+				s.mu.Unlock()
 				if err != nil {
 					return fmt.Errorf(
 						"failed to create tailscale (%s) node: %w",
diff --git a/mkdocs.yml b/mkdocs.yml
index e28cd593..3f19aead 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -168,7 +168,6 @@ nav:
           - Official releases: setup/install/official.md
           - Community packages: setup/install/community.md
           - Container: setup/install/container.md
-          - Cloud: setup/install/cloud.md
           - Build from source: setup/install/source.md
       - Upgrade: setup/upgrade.md
   - Usage:



Test patch:
diff --git a/integration/dockertestutil/execute.go b/integration/dockertestutil/execute.go
index 9e16f366..078b3bc2 100644
--- a/integration/dockertestutil/execute.go
+++ b/integration/dockertestutil/execute.go
@@ -25,7 +25,6 @@ type ExecuteCommandOption func(*ExecuteCommandConfig) error
 func ExecuteCommandTimeout(timeout time.Duration) ExecuteCommandOption {
 	return ExecuteCommandOption(func(conf *ExecuteCommandConfig) error {
 		conf.timeout = timeout
-
 		return nil
 	})
 }
@@ -67,6 +66,7 @@ func ExecuteCommand(
 				StdErr: &stderr,
 			},
 		)
+
 		resultChan <- result{exitCode, err}
 	}()
 
@@ -88,7 +88,6 @@ func ExecuteCommand(
 
 		return stdout.String(), stderr.String(), nil
 	case <-time.After(execConfig.timeout):
-
 		return stdout.String(), stderr.String(), fmt.Errorf("command failed, stderr: %s: %w", stderr.String(), ErrDockertestCommandTimeout)
 	}
 }