Skip to content
How do I license the UniHTML server?

How do I license the UniHTML server?

UniHTML has two parts and each checks a license on its own. The server reads one from its environment when the container starts. The client reads one from your Go process, through UniPDF’s license package, when you call Connect.

It is one key. You just have to give it to both.

The server

Metered, which is the usual case:

docker run -d -p 8080:8080 \
  -e UNIDOC_METERED_API_KEY=$UNIDOC_LICENSE_API_KEY \
  unidoccloud/unihtml

Offline, where an outbound call to the license server is not acceptable:

docker run -d -p 8080:8080 \
  -v /path/to/license.txt:/license.txt \
  -e UNIHTML_LICENSE_PATH=/license.txt \
  -e UNIHTML_CUSTOMER_NAME="My Company" \
  unidoccloud/unihtml

The variable names are the thing to get right, because the prefixes differ by license type:

VariablePurpose
UNIDOC_METERED_API_KEYMetered API key. No UNIHTML_ prefix on this one.
UNIHTML_LICENSE_PATHPath to an offline license file, inside the container.
UNIHTML_LICENSEOffline license content, if mounting a file is awkward.
UNIHTML_CUSTOMER_NAMERequired with an offline license. Must match the license.

UNIHTML_CUSTOMER_NAME is only needed for the offline license, and it has to match what was issued exactly. A metered key needs no customer name.

Mounting a host path into the container is easy to get wrong: UNIHTML_LICENSE_PATH is the path as the container sees it, not the path on your machine.

The client

Your Go program loads the key through UniPDF, because UniHTML is a UniPDF plugin and shares its license state:

import (
    "os"

    "github.com/unidoc/unipdf/v5/common/license"
)

func init() {
    if err := license.SetMeteredKey(os.Getenv(`UNIDOC_LICENSE_API_KEY`)); err != nil {
        panic(err)
    }
}

With an offline license, license.SetLicenseKey(content, "My Company") takes its place.

unihtml.Connect verifies this before it tries the network, so an unlicensed client fails with a license error rather than a connection one:

invalid or no license provided

Seeing that means the key never reached your process. A key set after Connect has already run is set too late.

Which one is failing

An unlicensed server does not start. It prints the reason and exits, so the container is gone by the time you look:

Err: no license provided. Use UNIHTML_LICENSE, UNIHTML_LICENSE_PATH (license-path flag)
or UNIDOC_METERED_API_KEY (metered-api-key flag)

Your program then fails at Connect with a connection error, which reads like a networking problem and is not one:

Get "http://localhost:8080/health": dial tcp [::1]:8080: connect: connection refused

Connection refused from an address you are sure is right means check the container:

docker ps -a          # is it running, or did it exit?
docker logs unihtml   # why

An unlicensed client is the other case, and it looks completely different: the error comes from Connect before any network call, and says invalid or no license provided.

So a license error names the license, and connection refused points at the container.

A third case looks like neither. A server that started fine but whose metered key has run out of credits accepts the connection, passes the health check, and rejects each conversion with HTTP 401. In your program that arrives as unauthorized on the call that converts, never on Connect. The server’s message is metered license is out of credits.

For what a metered key transmits, and how to remove the outbound call, see does UniHTML send my HTML anywhere?

Last updated on