Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 50 additions & 7 deletions docs/get-started/use-docker.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
---
title: Run Web3Signer from Docker
description: Run Web3Signer using the official Docker image.
description: Run Web3Signer using the official Docker images.
sidebar_position: 2
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# Run Web3Signer from Docker image

A Docker image is provided to run Web3Signer in a Docker container.
Web3Signer publishes two Docker images.
Both include Eclipse Temurin JRE 25 and the same Web3Signer application.
Comment thread
bgravenorst marked this conversation as resolved.
Outdated

- Ubuntu image (`consensys/web3signer:<version>`).
Includes a shell and runs as the `web3signer` user.
- Distroless image (`consensys/web3signer:<version>-distroless`).
Based on [Google Distroless](https://github.com/GoogleContainerTools/distroless).
Has no shell and no package manager, and runs as UID `65532`.

Replace `<version>` with `latest` or a release tag.

## Prerequisites

Expand All @@ -22,18 +34,49 @@ The Docker image does not run on Windows.

## Run Docker image

Display the Web3Signer command line help using the Docker image:
Display the Web3Signer command line help:

<Tabs>
<TabItem value="Ubuntu" label="Ubuntu" default>

```bash
docker run consensys/web3signer:<version> --help
```

</TabItem>
<TabItem value="Distroless" label="Distroless">

```bash
docker run consensys/web3signer:develop --help
docker run consensys/web3signer:<version>-distroless --help
```

</TabItem>
</Tabs>

## Expose listening port

To use the default listening port (`9000`) or the port specified using `--http-listen-port`, you must expose the listening port.
To use the default listening port (`9000`) or the port specified using `--http-listen-port`, you
must expose the listening port.

<Tabs>
<TabItem value="Ubuntu" label="Ubuntu" default>

```bash
docker run -p <listenPort>:9000 consensys/web3signer:<version> [options] [subcommand] [options]
```

To run Web3Signer exposing listening port for access:
</TabItem>
<TabItem value="Distroless" label="Distroless">

```bash
docker run -p <listenPort>:9000 consensys/web3signer:develop [options] [subcommand] [options]
docker run -p <listenPort>:9000 consensys/web3signer:<version>-distroless [options] [subcommand] [options]
```

</TabItem>
</Tabs>

## Use the distroless image

The distroless image does not require `--read-only`.
For optional read-only root filesystem hardening, the `JAVA_OPTS` difference, and key manager
Comment thread
bgravenorst marked this conversation as resolved.
Outdated
imports that skip disk writes, see [Run the distroless Docker image](../how-to/run-distroless-docker.md).
8 changes: 8 additions & 0 deletions docs/how-to/manage-keys.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,14 @@ curl -X POST http://127.0.0.1:9000/eth/v1/keystores --header "Content-Type: appl
</TabItem>
</Tabs>

Import writes keystore files to
[`--key-store-path`](../reference/cli/options.md#key-config-path-key-store-path).
On a read-only container root filesystem, that write fails unless you set
`--Xkey-manager-skip-keystore-storage`.
See [Run the distroless Docker image](./run-distroless-docker.md#use-the-key-manager-api-on-a-read-only-root).

This is not the `readonly` field returned when you [list keys](#list-keys).

### Delete keys

Delete keys using the [`delete keys`
Expand Down
23 changes: 22 additions & 1 deletion docs/how-to/monitor/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,16 @@ For more information, see the Log4j [configuration file](https://logging.apache.
</TabItem>
</Tabs>

To use your custom configuration, set the environment variable `JAVA_OPTS` to the location of your
To use your custom configuration, set a JVM environment variable to the location of your
configuration file.

The binary distribution and the Ubuntu Docker image read `JAVA_OPTS`.
The [distroless Docker image](../run-distroless-docker.md#pass-jvm-options) ignores `JAVA_OPTS`.
Use `JDK_JAVA_OPTIONS` (preferred) or `JAVA_TOOL_OPTIONS` instead.

<Tabs>
<TabItem value="Binary or Ubuntu image" label="Binary or Ubuntu image" default>

```bash
export JAVA_OPTS="-Dlog4j.configurationFile=<path_to_file>"
```
Expand All @@ -144,6 +151,20 @@ setting it before starting Web3Signer.
JAVA_OPTS="-Dlog4j.configurationFile=/Users/me/debug.xml" web3signer --key-store-path=/Users/me/keyFiles/ eth2
```

</TabItem>
<TabItem value="Distroless image" label="Distroless image">

```bash
docker run -p 9000:9000 \
-v <path_to_file>:/var/config/log4j2.xml:ro \
-e JDK_JAVA_OPTIONS='-Dlog4j.configurationFile=/var/config/log4j2.xml' \
consensys/web3signer:<version>-distroless \
eth2 --slashing-protection-enabled=false
```

</TabItem>
</Tabs>

:::info Note
When a custom Log4j2 configuration file is provided, it takes precedence over the [logging command line options](#basic-log-level-setting).
:::
133 changes: 133 additions & 0 deletions docs/how-to/run-distroless-docker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
title: Run the distroless Docker image
description: Run the Web3Signer distroless Docker image, including optional read-only root filesystem hardening.
sidebar_position: 9
keywords:
[
docker,
distroless,
]
---

# Run the distroless Docker image

The [distroless](https://github.com/GoogleContainerTools/distroless) image is an alternative to the
Ubuntu image. It has no shell and no package manager, and it runs as UID `65532`.

A read-only container root filesystem is optional.
The distroless image is built to start under `docker run --read-only` (or Kubernetes
`readOnlyRootFilesystem`) without a `/tmp` mount.
Use that mode when you want to prevent writes to the image filesystem.

To pull the image and start a container without `--read-only`, see
[Run Web3Signer from Docker](../get-started/use-docker.md).

## Prerequisites

- [Docker](https://docs.docker.com/install/)

The image includes its own Java runtime.

## Run with a read-only root filesystem

A read-only root filesystem (`docker run --read-only` or Kubernetes `readOnlyRootFilesystem`) makes
the container root unwritable.
If the process is compromised, it cannot install tools, rewrite binaries, or leave files on the
image filesystem.

:::important
This setting applies to the container root.
It is not the key manager API `readonly` field on listed keys.
:::

Web3Signer can still write to mounted volumes.
The distroless image starts under `--read-only` without a `/tmp` mount.
Add a writable `/tmp` only if extra tooling in the container writes there.

Run with `--read-only` and mount any paths Web3Signer must write:

```bash
docker run --read-only -p 9000:9000 \
-v <host-keys-path>:/keys:ro \
Comment thread
bgravenorst marked this conversation as resolved.
consensys/web3signer:<version>-distroless \
--key-store-path=/keys \
eth2 --slashing-protection-enabled=false
```

Mount keys, configuration, and any on-disk data as volumes.
Only the container root filesystem is read-only.

Typical writable mounts include:

- [`--key-store-path`](../reference/cli/options.md#key-config-path-key-store-path) if the [key manager API](./manage-keys.md) writes imported keystores.
- [`--data-path`](../reference/cli/options.md#data-path) if you configure a data directory.
- File log paths, if you log to a file.

Grant UID `65532` write access on a directory Web3Signer writes, or start the container with
`--user` set to a UID that already has that access.

If [`--data-path`](../reference/cli/options.md#data-path) is set and Web3Signer cannot write
`web3signer.ports`, it logs `Error writing ports file` and keeps serving requests.
A key manager import that cannot write the keystore reports
`Error importing keystore: Unable to add validator` for that keystore.
The container keeps running.

PostgreSQL slashing protection writes to the database, not the container root.

## Pass JVM options

You do not need extra JVM flags to start the distroless image.

If you already set heap size, GC flags, or system properties, the Ubuntu image and binary
distribution read `JAVA_OPTS`.
The distroless image has no shell and starts `java` directly, so `JAVA_OPTS` is ignored.

Use `JDK_JAVA_OPTIONS` (preferred) or `JAVA_TOOL_OPTIONS` instead:

```bash
docker run -p 9000:9000 \
-e JDK_JAVA_OPTIONS='-Xmx3g -Xms2g' \
consensys/web3signer:<version>-distroless \
eth2 --slashing-protection-enabled=false
```

If a value contains spaces, backslash-escape the spaces in `JDK_JAVA_OPTIONS`.

Pass a debug agent, such as JDWP, in `JDK_JAVA_OPTIONS`.
`docker kill -s QUIT <container>` prints a JVM thread dump to the container logs.
Tools that attach to the JVM, such as `jcmd`, need a writable temporary directory.
With `--read-only`, mount a writable `/tmp` before using those tools.

## Use the key manager API on a read-only root

[Importing keystores](./manage-keys.md#import-keystores) writes files under `--key-store-path`.
That write fails when the key store path is on a read-only root filesystem.

To keep imported keys in memory only, set the early access
Comment thread
bgravenorst marked this conversation as resolved.
`--Xkey-manager-skip-keystore-storage` option on the `eth2` subcommand:

```bash
docker run --read-only -p 9000:9000 \
consensys/web3signer:<version>-distroless \
eth2 --key-manager-api-enabled=true \
--Xkey-manager-skip-keystore-storage=true \
--slashing-protection-enabled=false
```

:::tip Early access feature

`--Xkey-manager-skip-keystore-storage` is an early access option and is hidden from `--help`.
Imported keys exist only in memory and are lost on restart.
Re-import keys after every restart.
Do not use this option unless you have a keystore backup.

:::

## Limitations

- There is no shell, so `docker exec -it <container> sh` is unavailable.
- Bind mounts that Web3Signer reads must be readable by UID `65532`.
Bind mounts that it writes must be writable by UID `65532`.
- `JAVA_OPTS` has no effect.
Use `JDK_JAVA_OPTIONS` or `JAVA_TOOL_OPTIONS`.
See [Pass JVM options](#pass-jvm-options).
Loading