> For the complete documentation index, see [llms.txt](https://docs.wproofreader.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wproofreader.com/v6.18.1/admin-panel/self-hosted/server-configuration.md).

# Server configuration

Use this page to configure email, provider sign-in, profile photo storage and environment variables for the self-hosted admin panel.

These settings require server access. They are separate from proofreading settings on the [Settings](/v6.18.1/admin-panel/self-hosted/settings.md) page.

### Applying changes

1. Set the variables in your deployment's environment configuration.
2. Apply the updated configuration through your deployment process.
3. Refresh cached application configuration if your deployment uses it.
4. Restart the admin panel.
5. Check the affected feature in the browser.

Defaults below come from the application configuration. Your deployment can override them. Values in development examples are not production defaults.

{% hint style="warning" %}
Keep passwords, client secrets and `APP_KEY` private. Do not include them in screenshots or support messages.
{% endhint %}

### Application address and server connection

| Variable                  | Default            | Purpose                                                                                                  |
| ------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------- |
| `APP_URL`                 | `http://localhost` | Public admin panel address used for setup links and default OAuth callbacks. Set your actual address.    |
| `APP_KEY`                 | Unset              | Application encryption and signing key. Keep the existing installation key when changing other settings. |
| `APP_SERVER_URL`          | Unset              | WProofreader Server API address accessible to browsers and the extension.                                |
| `APP_SERVER_INTERNAL_URL` | `APP_SERVER_URL`   | WProofreader Server API address used by the admin panel. Set it when the internal address differs.       |

Use your deployment's WProofreader Server API URL, including `/wscservice/api`, for both server variables.

Changing `APP_KEY` affects existing signed links. Do not generate another key to change SMTP or OAuth settings.

### Email through SMTP

SMTP is optional. Configure it to send invitations, password-reset links and confirmations for email-address changes.

Use the host, port, credentials and sender identity supplied by your mail administrator.

| Variable            | Default                | Purpose                                                              |
| ------------------- | ---------------------- | -------------------------------------------------------------------- |
| `MAIL_MAILER`       | `log`                  | Use `smtp` to send email. `log` does not deliver email to users.     |
| `MAIL_HOST`         | `127.0.0.1`            | SMTP server host. Set your relay's actual host.                      |
| `MAIL_PORT`         | `2525`                 | SMTP server port. Set your relay's port.                             |
| `MAIL_USERNAME`     | Unset                  | SMTP account name, when the relay requires authentication.           |
| `MAIL_PASSWORD`     | Unset                  | SMTP account password, when the relay requires authentication.       |
| `MAIL_FROM_ADDRESS` | `no-reply@example.com` | Sender email address. Use an address accepted by your relay.         |
| `MAIL_FROM_NAME`    | `Example`              | Sender name. Set a recognizable name for your installation.          |
| `MAIL_EHLO_DOMAIN`  | Host from `APP_URL`    | Name used when the admin panel introduces itself to the SMTP server. |
| `MAIL_URL`          | Unset                  | Optional SMTP connection URL.                                        |

For separate host and credential settings, leave `MAIL_URL` unset.

Port 465 uses implicit TLS. Other ports use STARTTLS when the relay offers it.

The admin panel considers SMTP configured when `MAIL_MAILER=smtp` and its configured host is nonempty. This does not test delivery.

#### Checking email delivery

1. Apply your SMTP settings.
2. Invite an example recipient from **Team**.
3. Check that the recipient receives the invitation email.
4. Open the invitation link.
5. Check password reset from **Forgot your password?** on **Sign in**.
6. Check that the reset email arrives.

If email fails, ask your mail administrator to check the relay and delivery logs. A visible reset link does not prove delivery.

#### Running without email

Use `MAIL_MAILER=log` when outgoing email is unavailable.

* On **Team**, copy invitation links and share them with recipients.
* Password reset by email is unavailable. Use [member password reset](/v6.18.1/admin-panel/self-hosted/team.md#setting-a-password-for-a-member) or [the server command](/v6.18.1/admin-panel/self-hosted/server-commands.md#reset-the-password-of-a-user).
* A changed profile email address takes effect immediately.
* A pending email change requested earlier offers only **Cancel request** while email is unavailable.

See [Sign in](/v6.18.1/admin-panel/self-hosted/sign-in.md#resetting-your-password) and [Profile](/v6.18.1/admin-panel/account-settings.md#profile-information) for these flows.

### OAuth provider sign-in

The admin panel supports Google, Microsoft and LinkedIn. Each provider requires an OAuth application registered with that provider.

A provider appears when both its client ID and client secret are set. There is no separate enable variable.

| Provider  | Client ID             | Client secret             | Optional callback override | Default callback path             |
| --------- | --------------------- | ------------------------- | -------------------------- | --------------------------------- |
| Google    | `GOOGLE_CLIENT_ID`    | `GOOGLE_CLIENT_SECRET`    | `GOOGLE_REDIRECT_URI`      | `/oauth/google/callback`          |
| Microsoft | `MICROSOFT_CLIENT_ID` | `MICROSOFT_CLIENT_SECRET` | `MICROSOFT_REDIRECT_URI`   | `/oauth/microsoft/callback`       |
| LinkedIn  | `LINKEDIN_CLIENT_ID`  | `LINKEDIN_CLIENT_SECRET`  | `LINKEDIN_REDIRECT_URI`    | `/oauth/linkedin-openid/callback` |

The default callback combines `APP_URL` with the provider's callback path. For example:

```
https://admin-panel.example.com/oauth/google/callback
```

#### Enabling a provider

1. Create an OAuth application with the provider.
2. Register the admin panel's callback URL with the provider.
3. Set the provider's client ID variable.
4. Set the provider's client secret variable.
5. Set its redirect URI variable only if the default callback is unsuitable.
6. Apply the environment changes.
7. Open **Sign in**.
8. Click the provider button.
9. Sign in with a provider email matching an existing admin panel account.

The registered callback must exactly match the effective redirect URI. Leave the override empty to use the callback derived from `APP_URL`.

The admin panel needs a network connection to the provider during sign-in.

Setting only the client ID or only the secret leaves the provider disabled. Disabled providers have no working sign-in endpoints.

To disable a provider, clear its client ID and secret, then apply the changes.

For account linking, two-factor authentication and invitation requirements, see [Signing in with an OAuth provider](/v6.18.1/admin-panel/self-hosted/sign-in.md#signing-in-with-an-oauth-provider).

### License checks

The admin panel reads the license from WProofreader Server over `APP_SERVER_INTERNAL_URL`. It does not install or change a license.

| Variable             | Default | Purpose                                                                                                                                                  |
| -------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `LICENSE_VERIFY_TLS` | `false` | Certificate verification for license requests: `true`, `false`, or a certificate authority (CA) bundle path accessible inside the admin panel container. |

{% hint style="warning" %}
Turn on certificate verification when WProofreader Server uses HTTPS. Set `true` for a trusted certificate, or the path to your CA bundle for a certificate from your own certificate authority. Without verification, the admin panel cannot detect a forged license answer.
{% endhint %}

After changes, check [Subscription](/v6.18.1/admin-panel/self-hosted/subscription.md). **Unknown** means the admin panel cannot obtain a usable license answer.

### Sessions

| Variable                  | Default | Purpose                                                     |
| ------------------------- | ------- | ----------------------------------------------------------- |
| `SESSION_LIFETIME`        | `120`   | Session inactivity timeout, in minutes.                     |
| `SESSION_EXPIRE_ON_CLOSE` | `false` | Whether the session cookie expires when the browser closes. |
| `SESSION_DOMAIN`          | Unset   | Session cookie domain.                                      |
| `SESSION_PATH`            | `/`     | Session cookie path.                                        |
| `SESSION_SECURE_COOKIE`   | Unset   | `true` restricts session cookies to HTTPS connections.      |
| `SESSION_SAME_SITE`       | `lax`   | Session cookie SameSite policy.                             |

Sessions are stored in the database. Keep this installation default: administrative password resets sign users out of their sessions only with database storage.

After session changes, check sign-in and provider callbacks.

### Profile photo storage

The admin panel stores one type of file: user profile photos. Other admin panel data is in the database.

By default, the admin panel stores photos on the local disk of its container. Amazon S3 is optional. The admin panel image includes S3 support, so you do not install extra packages.

| Variable                       | Default  | Purpose                                                                     |
| ------------------------------ | -------- | --------------------------------------------------------------------------- |
| `JETSTREAM_PROFILE_PHOTO_DISK` | `public` | Storage for profile photos: `public` for the local disk, `s3` for a bucket. |
| `AWS_DEFAULT_REGION`           | Unset    | Bucket region. Required for `s3`.                                           |
| `AWS_BUCKET`                   | Unset    | Bucket name. Required for `s3`.                                             |
| `AWS_ACCESS_KEY_ID`            | Unset    | Access key ID.                                                              |
| `AWS_SECRET_ACCESS_KEY`        | Unset    | Secret access key.                                                          |

The admin panel uses the access key only when both `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are set. If one of them is unset, the AWS SDK uses its default credentials. An example is the IAM role of the EC2 instance or the ECS task.

#### Local disk

Photos are in `/var/www/html/storage/app/public` inside the container. Mount this folder as a persistent volume. If you do not, photos are lost when the container is recreated.

#### S3 bucket

Photos are stored as private objects. The admin panel shows them through signed links that expire after 30 minutes. You can keep the bucket private, with public access blocked and object ACLs disabled.

The access key or IAM role needs these permissions on the bucket objects:

* `s3:PutObject`
* `s3:GetObject`
* `s3:DeleteObject`

The admin panel needs an HTTPS connection to the storage endpoint.
