Self-host · source build · v1.2.0

Self-host Artifact Relay. Publish something useful.

This localhost path takes you from a versioned source checkout to one private Markdown artifact. Docker binds the service to 127.0.0.1, and sharing stays disabled by default.

About 10 minutes after prerequisites · macOS or Linux host · no public server required

01 / Build and start

A pinned checkout, local credentials, one container.

Run these commands in a terminal. The bootstrap step asks for a viewer password of at least 12 characters without echoing it and writes generated credentials to a mode-0600 .env file.

  1. 1

    Clone the repository and pin v1.2.0

    The release tag makes this guide reproducible instead of following a moving branch.

    git clone https://github.com/eloktev/artifact-relay.git
    cd artifact-relay
    git checkout v1.2.0
  2. 2

    Build the application image

    The supported default path builds the selected source checkout locally.

    docker build -t artifact-relay:1.2.0 .
  3. 3

    Bootstrap private credentials

    Choose the password you will use in the browser. The script separately generates the API token and session signing key; it never stores the plaintext viewer password.

    ./scripts/bootstrap.sh
  4. 4

    Start and check health

    A successful health request returns a small JSON response without secret data.

    docker compose up -d
    docker compose ps
    curl -fsS http://localhost:8000/api/health

02 / First value

Publish a small Markdown artifact.

This snippet creates a temporary file, loads the generated environment without printing it, sends the token only in the authorization header, extracts the returned opaque URL, and opens it.

Two credentials, two jobs

Your viewer password creates a browser session for the private library. The generated API token authorizes publishing and API reads or deletes. Do not paste either credential into an artifact, chat, command output, or source control.

SAMPLE_FILE="$(mktemp)"
trap 'rm -f "$SAMPLE_FILE"' EXIT
printf '# First relay\n\nPublished from my self-hosted Artifact Relay.\n' > "$SAMPLE_FILE"

set -a
. ./.env
set +a
RESPONSE="$(curl -fsS -X POST http://localhost:8000/api/artifacts \
  -H "Authorization: Bearer ${ARTIFACT_API_TOKEN}" \
  -F 'title=First relay' \
  -F 'summary=Local installation check' \
  -F 'format=markdown' \
  -F 'expires_in_days=30' \
  -F "content=@${SAMPLE_FILE};filename=first-relay.md;type=text/markdown")"
unset ARTIFACT_API_TOKEN SESSION_SECRET_KEY VIEW_PASSWORD_HASH

ARTIFACT_URL="$(printf '%s' "$RESPONSE" | \
  python3 -c 'import json,sys; print(json.load(sys.stdin)["url"])')"
printf 'Published: %s\n' "$ARTIFACT_URL"
if command -v open >/dev/null; then
  open "$ARTIFACT_URL"
else
  xdg-open "$ARTIFACT_URL"
fi

The artifact page asks for the viewer password you chose during bootstrap. Its path contains an opaque artifact ID, but the page remains private until you log in.

03 / Stop or continue

Keep the data, or remove it deliberately.

Stopping containers preserves artifacts in the named Docker volume. Deleting the volume is irreversible.

Stop, keep data

Stop and remove containers while retaining the artifact-data volume and your local .env.

docker compose down

Delete local data

Only when you no longer need any artifacts, remove containers and the persistent volume, then remove the credential file.

docker compose down --volumes
rm .env

Prefer not to operate it?

The managed beta remains the shortest path.

Hermes can connect an isolated instance hosted and maintained for you. Self-hosting remains fully supported when you want to own the runtime and data.