QUICKSTART.md
Rama main · réplica de lectura del repositorio original.
# Quick Start
Get **OpenLicensd** running in minutes.
## Prerequisites
Choose one deployment path:
| Path | Requirements |
|------|-------------|
| **Helm** | Kubernetes cluster, [Helm 3](https://helm.sh/docs/intro/install/), [kubectl](https://kubernetes.io/docs/tasks/tools/), PostgreSQL 16+ |
| **Docker Compose** | [Docker](https://docs.docker.com/get-docker/), [Docker Compose](https://docs.docker.com/compose/) |
| **Docker** | [Docker](https://docs.docker.com/get-docker/), a PostgreSQL instance |
| **Local dev** | Go 1.27+, Node.js 24+, Docker (for PostgreSQL) |
Published server binaries and container images are **Linux amd64 and arm64** only. Helm and Docker paths inherit that platform scope. See [docs/deployment.md](docs/deployment.md#platforms).
## Helm (production)
Container images are published to `ghcr.io/alvarorg14/openlicensd`. The Helm chart is published to `oci://ghcr.io/alvarorg14/charts/openlicensd`.
Replace `X.Y.Z` with the [latest release](https://github.com/alvarorg14/openlicensd/releases) version:
```bash
helm install openlicensd oci://ghcr.io/alvarorg14/charts/openlicensd \
--version X.Y.Z \
--namespace openlicensd \
--create-namespace \
--set config.bootstrapAdmin.email=admin@example.com \
--set config.database.host=postgres.example.com \
--set config.database.port=5432 \
--set config.database.name=openlicensd \
--set config.database.user=openlicensd \
--set config.database.sslmode=require \
--set secret.data.databasePassword='change-me' \
--set secret.data.bootstrapAdminPasswordHash="$(make hash-password PASSWORD=yourpassword)"
```
Or install from the chart source (set `image.tag` — git `Chart.yaml` uses a `0.0.0-dev` placeholder):
```bash
helm install openlicensd ./charts/openlicensd \
--namespace openlicensd \
--create-namespace \
--set image.tag=X.Y.Z \
-f my-values.yaml
```
### Verify (Helm)
```bash
kubectl get pods -n openlicensd -l app.kubernetes.io/name=openlicensd
kubectl port-forward -n openlicensd svc/openlicensd 8080:8080
curl -s localhost:8080/healthz
curl -s localhost:8080/readyz
```
Open http://localhost:8080 and sign in with your configured admin credentials.
## Docker Compose (fastest)
Run PostgreSQL and OpenLicensd together from the published image:
```bash
make stack-up
```
By default the stack pulls `ghcr.io/alvarorg14/openlicensd:latest` for quick evaluation. Pin a release with `OPENLICENSD_IMAGE_TAG=X.Y.Z make stack-up` (replace `X.Y.Z` with a [release](https://github.com/alvarorg14/openlicensd/releases) version).
Open http://localhost:8080 and sign in with:
- Email: `admin@example.com`
- Password: `admin`
> **Warning:** The default bootstrap password is for evaluation only. Generate your own hash with `make hash-password PASSWORD=yourpassword` and set `OPENLICENSD_BOOTSTRAP_ADMIN_PASSWORD_HASH` before any real use (for example via a `.env.stack` file and `COMPOSE_ENV_FILES=.env.stack make stack-up`).
[`docker-compose.stack.yml`](docker-compose.stack.yml) exposes the full `.env.example` variable set with stack-safe defaults. If you use `.env.stack`, do not copy `.env` or `.env.example` verbatim — keep `OPENLICENSD_DATABASE_HOST=postgres` (the compose file sets discrete database variables for you).
### Verify (Docker Compose)
```bash
curl -s localhost:8080/healthz
curl -s localhost:8080/readyz
```
Stop the stack:
```bash
make stack-down
```
To remove the stack's database volume as well:
```bash
make stack-down ARGS=-v
```
## Docker
Replace `X.Y.Z` with a pinned [release](https://github.com/alvarorg14/openlicensd/releases) version (semver without the `v` prefix). The `:latest` tag tracks the most recent release but can change without notice — do not use it in production.
```bash
docker pull ghcr.io/alvarorg14/openlicensd:X.Y.Z
docker run -d \
--name openlicensd \
-p 8080:8080 \
-e OPENLICENSD_DATABASE_HOST=host \
-e OPENLICENSD_DATABASE_PORT=5432 \
-e OPENLICENSD_DATABASE_USER=user \
-e OPENLICENSD_DATABASE_PASSWORD=pass \
-e OPENLICENSD_DATABASE_NAME=openlicensd \
-e OPENLICENSD_DATABASE_SSLMODE=disable \
-e OPENLICENSD_BOOTSTRAP_ADMIN_EMAIL=admin@example.com \
-e OPENLICENSD_BOOTSTRAP_ADMIN_PASSWORD_HASH='$2a$10$...' \
-e OPENLICENSD_COOKIE_SECURE=true \
ghcr.io/alvarorg14/openlicensd:X.Y.Z
```
### Verify (Docker)
```bash
curl -s localhost:8080/healthz
curl -s localhost:8080/readyz
```
Open http://localhost:8080.
## Binary
Download a **Linux amd64 or arm64** archive from [GitHub Releases](https://github.com/alvarorg14/openlicensd/releases), or build from source for local development on any OS:
```bash
make build
```
> **Note:** `make build` runs `make ui` first so the binary embeds the full admin UI. A plain `go build` embeds a placeholder page instead.
```bash
export OPENLICENSD_DATABASE_HOST=localhost
export OPENLICENSD_DATABASE_PORT=5432
export OPENLICENSD_DATABASE_USER=user
export OPENLICENSD_DATABASE_PASSWORD=pass
export OPENLICENSD_DATABASE_NAME=openlicensd
export OPENLICENSD_DATABASE_SSLMODE=disable
export OPENLICENSD_BOOTSTRAP_ADMIN_EMAIL=admin@example.com
export OPENLICENSD_BOOTSTRAP_ADMIN_PASSWORD_HASH=$(make hash-password PASSWORD=your-secure-password)
export OPENLICENSD_COOKIE_SECURE=false
./bin/openlicensd
```
Open http://localhost:8080.
## Local development
1. Start PostgreSQL:
```bash
make dev-db
```
If you are upgrading from a version without products/policies, reset the local database:
```bash
make dev-db-reset
```
2. Copy environment variables:
```bash
cp .env.example .env
```
If you regenerate `OPENLICENSD_BOOTSTRAP_ADMIN_PASSWORD_HASH`, wrap the bcrypt value in single quotes in `.env` (e.g. `'$2a$10$...'`) so Docker Compose does not misinterpret `$` characters.
3. In one terminal, start the API server:
```bash
make dev-server
```
4. In another terminal, start the UI dev server:
```bash
make dev-ui
```
Open http://localhost:3000 and sign in with:
- Email: `admin@example.com`
- Password: `admin`
## Try the API
### Login
```bash
curl -s -c cookies.txt -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@example.com","password":"admin"}'
CSRF=$(grep openlicensd_csrf cookies.txt | awk '{print $7}')
```
### Create a product and policy
```bash
PRODUCT_ID=$(curl -s -b cookies.txt -X POST http://localhost:8080/api/v1/products \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: $CSRF" \
-d '{"name":"Acme Widget","code":"acme-widget"}' | jq -r .id)
POLICY_ID=$(curl -s -b cookies.txt -X POST http://localhost:8080/api/v1/policies \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: $CSRF" \
-d "{\"product_id\":\"$PRODUCT_ID\",\"name\":\"Perpetual\"}" | jq -r .id)
```
### Create a license
```bash
curl -s -b cookies.txt -X POST http://localhost:8080/api/v1/licenses \
-H "Content-Type: application/json" \
-H "X-CSRF-Token: $CSRF" \
-d "{\"label\":\"Test License\",\"product_id\":\"$PRODUCT_ID\",\"policy_id\":\"$POLICY_ID\"}" | jq
```
Save the `key` from the response — it is shown only once.
### Validate a license
```bash
curl -s -X POST http://localhost:8080/api/v1/validate \
-H "Content-Type: application/json" \
-d '{"key":"YOUR-KEY-HERE","product":"acme-widget"}' | jq
```
## Uninstall (Helm)
```bash
helm uninstall openlicensd -n openlicensd
```
## Next Steps
- Documentation site: [https://alvarorg14.github.io/openlicensd/](https://alvarorg14.github.io/openlicensd/)
- Full configuration reference: [docs/configuration.md](docs/configuration.md)
- API documentation: [docs/api.md](docs/api.md) and [docs/openapi.yaml](docs/openapi.yaml)
- Harbor registry credentials: [docs/harbor-registry-credentials.md](docs/harbor-registry-credentials.md)
- Deployment guide: [docs/deployment.md](docs/deployment.md)
- Upgrade procedure: [docs/upgrade.md](docs/upgrade.md)
- PostgreSQL backup and restore: [docs/backup-restore.md](docs/backup-restore.md)
- Troubleshooting: [docs/troubleshooting.md](docs/troubleshooting.md)