Deploy Shield360
Shield360 runs two ways:
Sign in at app.shield360.ai. Nothing to deploy: enrol machines and point SDKs at your organization.
Self-hostedRun the whole platform in your own infrastructure, so telemetry and collector data never leave it.
A self-hosted deployment has three components:
- The Shield360 platform: the UI and APIs, collector ingest, the CLI downloads served to enrolling machines, and a bundled OpenTelemetry Collector
- PostgreSQL for users, organizations, projects and settings
- ClickHouse for telemetry and collector data
Self-host with Docker Compose
Section titled “Self-host with Docker Compose”The repository’s docker-compose.yml runs the whole platform on one host:
| Service | Image | Holds |
|---|---|---|
postgres | postgres:17-alpine | Users, organizations, projects and settings |
clickhouse | clickhouse/clickhouse-server:24.4.1 | Telemetry and collector data |
shield360 | Built from src/Dockerfile | The UI and API, scheduled jobs, the OpAMP server and the bundled OpenTelemetry Collector |
The compose file runs the open edition (SHIELD360_EDITION=oss). Shield360 manages its own users and roles, so it needs no external identity service. Telemetry about Shield360 itself is off (TELEMETRY_ENABLED=false).
Prerequisites
Section titled “Prerequisites”- Docker Engine 24 or later with the Compose v2 plugin (
docker compose version) - 4 CPU cores and 8 GB of memory for the host. Building the platform image needs most of that memory.
- 40 GB of free disk: about 20 GB for the image build and the rest for data. ClickHouse keeps telemetry for 30 days by default.
opensslto generate secrets- Free host port
3000for the UI and API. ClickHouse (9000,8123) and the collector’s raw OTLP ports (4317,4318) are published on127.0.0.1only.
Install
Section titled “Install”Once your access is set up (see the note above), get the distribution the way your access email describes, and open its folder:
cd shield360For a licensed deployment without building anything, use the self-hosted image instead: it carries the same compose bundle.
Copy the example, then replace every CHANGE_ME with its own random value:
cp .env.selfhost.example .envchmod 600 .envopenssl rand -hex 32 # run once for each CHANGE_ME| Variable | Purpose |
|---|---|
POSTGRES_PASSWORD | PostgreSQL password. Use a hex value: it is placed in a connection URL. |
SHIELD360_DB_PASSWORD | ClickHouse password. |
NEXTAUTH_SECRET | Signs sessions. Changing it signs everyone out. |
CRON_JOB_SECRET | Authenticates the platform’s scheduled jobs. |
SHIELD360_VAULT_ENCRYPTION_KEY | Encrypts stored credentials. If you lose it, the credentials cannot be decrypted. |
docker compose refuses to start while any of these is missing. Keep .env out of version control, and back it up with your data.
Then name the first administrator, so the account exists before anyone else can reach the server:
| Variable | Purpose |
|---|---|
SHIELD360_ADMIN_EMAIL | Email address of the first administrator. |
SHIELD360_ADMIN_PASSWORD | Their password: at least 12 characters, and not a well-known password. |
Both are optional. If you leave them unset, the first account registered at /register becomes the administrator instead.
docker compose up -d --buildThe first build takes 10 to 20 minutes. It compiles the platform, the collector and the shield360 CLI for every platform. To use a platform image you have already built or mirrored, set SHIELD360_IMAGE in .env and run docker compose up -d --no-build.
docker compose psdocker compose logs shield360 | grep -iE "migration|seeding"On every start, the platform container applies PostgreSQL migrations and runs the seed. It then brings ClickHouse up to date and starts serving. If SHIELD360_ADMIN_PASSWORD is too short or well known, the seed stops the container and logs the reason; docker compose logs shield360 shows it. The shield360 service is healthy when http://127.0.0.1:3000/login answers.
The platform image carries the shield360 CLI for macOS, Linux and Windows. Machines enrolling against your deployment download it from /api/cli/download/*, with install scripts at /api/cli/install.sh and /api/cli/install.ps1. /api/cli/install-cli.sh and /api/cli/install-cli.ps1 install the CLI alone, without an install key or enrolment, and check it against the sha256 the server publishes at /api/cli/targets. See Deploy the collector.
SDKs and enrolled machines send telemetry to the platform’s authenticated OTLP routes on port 3000. The bundled collector’s raw receivers on 4317 and 4318 write to ClickHouse without authentication. They are bound to 127.0.0.1; set OTLP_BIND_ADDRESS only if you need them on a network you trust.
First sign-in
Section titled “First sign-in”No account ships with Shield360. The first administrator owns the Default Organization and its Default Project, and comes from one of two places:
SHIELD360_ADMIN_EMAILandSHIELD360_ADMIN_PASSWORD. On the first start, the seed creates this account when there are no users yet. Sign in athttp://127.0.0.1:3000/loginwith those details.- The first registration. If those variables are unset, open
http://127.0.0.1:3000/registerand create an account. While there are no users, the page says so, and that account becomes the administrator.
Once an account exists, the seed never changes its password, even if SHIELD360_ADMIN_PASSWORD changes. Change it under Settings → Profile. You can also remove both variables from .env after the first start.
After that, registration is by invitation. Invite people from Settings → Team, choosing the role each one joins with (the organization’s default role unless you pick another; only an owner can invite an owner). Each person then registers at /register with the invited email address and joins with that role. You can change anyone’s role later on the same page. The server refuses a registration without an invitation, and so does Google or GitHub sign-in for an email it does not know.
SHIELD360_OPEN_REGISTRATION=true lets anyone who can reach the server create an account, as earlier versions did. This is not recommended.
To sign in through Google or GitHub, set the matching *_CLIENT_ID and *_CLIENT_SECRET in .env. Also set NEXTAUTH_URL to the public URL that the provider calls back to.
Upgrade
Section titled “Upgrade”Update the distribution to the release you are moving to, then rebuild and restart:
docker compose build shield360docker compose up -dIf you run a published or mirrored image, change SHIELD360_IMAGE in .env, then run docker compose pull shield360 && docker compose up -d --no-build. Migrations run automatically when the new container starts. Take a backup before every upgrade.
Earlier versions created a default account with a published password on every install. Upgrading keeps that account, but each start logs a warning while it still has that password. Sign in and change the password under Settings → Profile, or remove the account once another administrator exists.
Back up
Section titled “Back up”Back up three things: PostgreSQL, ClickHouse and your .env file.
Back up PostgreSQL as a compressed custom-format dump:
docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" -d "$POSTGRES_DB" -Fc' \ > shield360-postgres-$(date +%F).dumpTo restore it, stop the platform first:
docker compose stop shield360docker compose exec -T postgres sh -c 'pg_restore -U "$POSTGRES_USER" -d "$POSTGRES_DB" --clean --if-exists' \ < shield360-postgres-YYYY-MM-DD.dumpdocker compose start shield360Back up ClickHouse with its native BACKUP command. First allow a backup directory once, then restart ClickHouse:
docker compose exec clickhouse sh -c 'mkdir -p /var/lib/clickhouse/backups && printf "%s\n" \ "<clickhouse><backups><allowed_disk>default</allowed_disk><allowed_path>/var/lib/clickhouse/backups/</allowed_path></backups></clickhouse>" \ > /etc/clickhouse-server/config.d/backups.xml'docker compose restart clickhouseThen take the backup and copy it off the host:
STAMP=$(date +%F)docker compose exec clickhouse sh -c "clickhouse-client --user \"\$CLICKHOUSE_USER\" --password \"\$CLICKHOUSE_PASSWORD\" \ --query \"BACKUP DATABASE \$CLICKHOUSE_DATABASE TO File('/var/lib/clickhouse/backups/shield360-$STAMP.zip')\""docker compose cp clickhouse:/var/lib/clickhouse/backups/shield360-$STAMP.zip .The backups.xml file lives in the container, so write it again whenever the container is recreated. To restore, copy the file back into that directory and run RESTORE DATABASE shield360 FROM File('/var/lib/clickhouse/backups/<file>.zip').
docker compose down keeps all data. docker compose down -v deletes the postgres-data, clickhouse-data and shield360-data volumes. Run it only when you mean to start from nothing.
Air-gapped installs
Section titled “Air-gapped installs”Shield360 needs no outbound network access at runtime:
- The compose file turns off telemetry about Shield360 itself.
- The image disables Next.js and Prisma telemetry and includes the Prisma engines.
- The image serves the CLI binaries that enrolling machines download.
To install without internet access, build or pull the images on a connected machine, then carry them across:
# On a connected machine, from the Shield360 checkoutdocker compose build shield360docker pull postgres:17-alpinedocker pull clickhouse/clickhouse-server:24.4.1docker save shield360:local postgres:17-alpine clickhouse/clickhouse-server:24.4.1 | gzip > shield360-images.tar.gz
# On the air-gapped host, with the same checkout and your .envgunzip -c shield360-images.tar.gz | docker loaddocker compose up -d --no-buildIf you use an internal registry, push the three images to it and set SHIELD360_IMAGE to the platform image. Also point the postgres and clickhouse image: lines in the compose file at your mirror.
Features that call a model provider, such as LLM-as-a-judge evaluations and the chat assistant, need a provider the host can reach. That can be a model endpoint inside your network.
Kubernetes
Section titled “Kubernetes”For production Kubernetes deployments, contact hello@shield360.ai for manifests and sizing guidance.
Frequently asked questions
Section titled “Frequently asked questions”Should I use managed or self-hosted Shield360?
Managed is the quickest start. Self-host when collector data, prompts and telemetry must stay inside your own infrastructure; every feature in this documentation runs self-hosted.
Can I reuse my existing ClickHouse or OpenTelemetry Collector?
Yes. Shield360 can connect to infrastructure you already run instead of deploying its own ClickHouse or OTel Collector. See Connect Multiple Databases for setup.
Do enrolled machines need to reach the internet?
No. Machines download the CLI from, enrol with and report to your Shield360 deployment only.