docs/quick-start.md

# Quick Start: Minimal Welley Deployment

The shortest path to a running Welley instance on a single Linux host, on any cloud or on your own hardware. It uses only the flags the CLI actually requires; everything else stays at its default.

What you get: the platform, the RAG pipeline, Nginx, Redis and a **bundled** PostgreSQL container, with a Let's Encrypt certificate issued during installation. No managed database, no CDN, no telemetry or Slack integration — see the AWS EC2 and DigitalOcean guides for those.

## 1\. Prerequisites

**A Linux host**

-   Ubuntu 24.04 LTS (or a comparable current distribution).
-   2 vCPU, 4 GB RAM, 60 GB disk as a starting point.
-   A public IPv4 address that does not change.
-   Inbound TCP **80** and **443** open to the internet, and **22** open to you. Port 80 is needed during installation for the certificate challenge and afterwards for the weekly renewal.
-   A non-root user with `sudo` — the guide runs everything as that user, referred to below as `<user>`.

**DNS**

Two records, both pointing to the host's public IP:

| Record | Purpose |
| --- | --- |
| `<domain>` | the site itself |
| `storage.<domain>` | uploads and static files, because this setup has no CDN |

Create them before you start: the CLI checks that both names resolve to this host and stops if they do not.

**Email DNS records**

The domain of your `--smtp-from` address needs email authentication records. Without them, Gmail, Outlook and other large providers often drop mail to recipients who have never received anything from you. That covers every invitation and sign-up confirmation, and the mail does not even land in spam, although your SMTP provider reports it as sent.

| Record | Type | Value |
| --- | --- | --- |
| `<mail-domain>` | TXT | SPF, for example `v=spf1 include:<provider> ~all` — take the exact value from your SMTP provider |
| `_dmarc.<mail-domain>` | TXT | DMARC, for example `v=DMARC1; p=none; rua=mailto:dmarc@<mail-domain>` |
| `<selector>._domainkey.<mail-domain>` | TXT or CNAME | DKIM, generated by your SMTP provider when you verify the domain |

A domain can carry only one SPF record. If it already has one, add your provider to it instead of creating a second. `create` warns if SPF or DMARC is missing, but it does not stop. It cannot check DKIM, because the selector name is specific to your provider.

Do not skip DKIM. Many providers, Amazon SES among them, send with their own domain as the envelope sender by default. SPF then checks the provider's domain, not yours, so it does not count toward DMARC, and only DKIM can make DMARC pass. Check DKIM status in your provider's console. In Amazon SES it is under _Verified identities → `<mail-domain>` → DKIM_ and must read _Successful_. SES Easy DKIM publishes three CNAME records named `<token>._domainkey.<mail-domain>`.

**SMTP credentials**

Host, user, password and a from address, from any provider. The platform needs them for email confirmation and password recovery, and the CLI refuses to install without them. Defaults assume submission over STARTTLS on port 587.

**An admin email address** for the first login and password recovery.

## 2\. Install Docker

Follow the official instructions for your distribution: [Install Docker Engine](https://docs.docker.com/engine/install/). Then let your user talk to the daemon:

```
sudo usermod -aG docker <user>
```

Log out and back in, then check both parts are in place:

```
docker ps
docker compose version
```

## 3\. Download the CLI

Pick the `platform` value that matches your host:

**linux/amd64**

```

curl -fL "https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?channel=stable&platform=linux/amd64" -o wlycli
chmod +x wlycli
./wlycli -v
  
```
  **linux/arm64**

```

curl -fL "https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?channel=stable&platform=linux/arm64" -o wlycli
chmod +x wlycli
./wlycli -v
  
```
  **darwin/arm64**

```

curl -fL "https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?channel=stable&platform=darwin/arm64" -o wlycli
chmod +x wlycli
./wlycli -v
  
```
  **darwin/amd64**

```

curl -fL "https://appstore.allroads.social/v1/social.wellesley.wlycli/latest?channel=stable&platform=darwin/amd64" -o wlycli
chmod +x wlycli
./wlycli -v
  
```
  

## 4\. Deploy

```
./wlycli deploy create \
-d example.com \
-e admin@example.com \
--smtp-host smtp.example.com \
--smtp-user "$MAIL_USER" \
--smtp-password "$MAIL_PASSWORD" \
--smtp-from noreply@example.com
```

These six flags are the whole required set. The command checks DNS, writes the deployment files, issues the certificate with Certbot and starts the containers; expect it to take several minutes.

Defaults you are accepting here:

| Setting | Default |
| --- | --- |
| Install directory | `~/.welley/<project>`, where `<project>` is the domain with every non-alphanumeric character replaced by `_` (so `example.com` becomes `example_com`) |
| Database | bundled PostgreSQL container, data under the install directory |
| Certificates | Let's Encrypt via Certbot, renewed automatically once a week |
| Uploads and static files | served from `https://storage.<domain>` |
| Updates | `stable` channel, checked daily, applied with zero downtime where possible |

## 5\. First login

The generated admin password is printed to the platform log:

```
docker logs example_com-platform-blue-1 | grep "Auto-init complete"
```

Open `https://<domain>`, sign in as the admin email you passed with `-e`, and change the password immediately. Treat the log as a secret until you have.

## 6\. Check the result

```
docker ps
```

You should see one container each for `nginx`, `platform-blue`, `rag-pipeline-blue`, `postgres`, `redis`, `autoheal` and `snoopy`, all named `<project>-<service>-1`.

## If something went wrong

`create` will not run a second time while the project directory or its containers exist. If the files are fine and only some containers failed to start, recreate them without losing anything:

```
./wlycli deploy restart -d example.com
```

If the deployment itself needs to be redone, remove it and start over — this deletes the bundled database along with everything else:

```
./wlycli deploy delete -d example.com --yes-please-delete-all-the-data
```

## Other documents

-   [**Welley CLI** docs/index.md](https://welley.com/administrators/docs/cli/)
-   [**Deploy Server** skills/deploy-server/SKILL.md](https://welley.com/administrators/docs/deploy-server-skill/)
-   [**openai.yaml** skills/deploy-server/agents/openai.yaml](https://welley.com/administrators/docs/deploy-server-openai-yaml/)
-   [**DigitalOcean Reference** skills/deploy-server/references/digitalocean.md](https://welley.com/administrators/docs/deploy-server-digitalocean/)
