mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
314 lines
9.2 KiB
Markdown
314 lines
9.2 KiB
Markdown
# DorkNet Deployment
|
|
|
|
This branch has two deployable shapes:
|
|
|
|
- **Production/full API:** build the root `Dockerfile`, which runs
|
|
`DorkNet.Server`. This is still the runtime that serves every public
|
|
Rec Room-compatible endpoint.
|
|
- **Microservices scaffold:** deploy `docker-compose.microservices.yml`
|
|
for local testing or `docker-compose.microservices.dokploy.yml` on
|
|
Dokploy. Both start `DorkNet.Gateway`,
|
|
`DorkNet.Services.Identity`, `DorkNet.Services.Rooms`,
|
|
`DorkNet.Services.Notify`, Postgres, and Redis. These hosts currently
|
|
expose internal health/capability endpoints only; public routes move
|
|
behind the gateway incrementally.
|
|
|
|
Object storage is always a **separate S3-compatible instance**. The
|
|
microservices compose files do not start MinIO/Garage.
|
|
|
|
---
|
|
|
|
## Dokploy: full server
|
|
|
|
Use this for a real server today.
|
|
|
|
Create a Dokploy **Application**:
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Source | This GitHub repo / branch |
|
|
| Build type | Dockerfile |
|
|
| Dockerfile path | `Dockerfile` |
|
|
| Context | `.` |
|
|
| Container port | `8080` |
|
|
|
|
Set application environment variables:
|
|
|
|
```env
|
|
ASPNETCORE_ENVIRONMENT=Production
|
|
ASPNETCORE_URLS=http://0.0.0.0:8080
|
|
DOTNET_RUNNING_IN_CONTAINER=true
|
|
|
|
DORKNET_DOMAIN=yourdomain.com
|
|
DORKNET_JWT_SECRET=replace-with-at-least-64-random-characters
|
|
|
|
Database__Provider=postgres
|
|
ConnectionStrings__Default=Host=<postgres-host>;Port=5432;Database=dorknet;Username=<user>;Password=<password>
|
|
ConnectionStrings__Redis=redis://<redis-host>:6379
|
|
|
|
S3__Endpoint=https://your-s3-api-endpoint
|
|
S3__AccessKey=your-access-key
|
|
S3__SecretKey=your-secret-key
|
|
S3__Region=garage
|
|
|
|
Photon__AppId=your-photon-realtime-app-id
|
|
Photon__VoiceAppId=your-photon-voice-app-id
|
|
Photon__CloudRegion=eu
|
|
```
|
|
|
|
If Postgres and Redis are Dokploy-managed services in the same project,
|
|
use the internal service hostnames Dokploy gives you. For a Compose-style
|
|
network the values usually look like:
|
|
|
|
```env
|
|
ConnectionStrings__Default=Host=postgres;Port=5432;Database=dorknet;Username=dorknet;Password=dorknet_dev
|
|
ConnectionStrings__Redis=redis://redis:6379
|
|
```
|
|
|
|
### Domains
|
|
|
|
Point DNS at the Dokploy server, then add domains to the same
|
|
application. Every host routes to container port `8080`.
|
|
|
|
Add these hosts for full client compatibility:
|
|
|
|
```text
|
|
yourdomain.com
|
|
www.yourdomain.com
|
|
admin.yourdomain.com
|
|
api.yourdomain.com
|
|
auth.yourdomain.com
|
|
accounts.yourdomain.com
|
|
bugreporting.yourdomain.com
|
|
cards.yourdomain.com
|
|
cdn.yourdomain.com
|
|
chat.yourdomain.com
|
|
clubs.yourdomain.com
|
|
cms.yourdomain.com
|
|
commerce.yourdomain.com
|
|
data.yourdomain.com
|
|
datacollection.yourdomain.com
|
|
discovery.yourdomain.com
|
|
econ.yourdomain.com
|
|
feed.yourdomain.com
|
|
gamelogs.yourdomain.com
|
|
geo.yourdomain.com
|
|
img.yourdomain.com
|
|
leaderboard.yourdomain.com
|
|
link.yourdomain.com
|
|
lists.yourdomain.com
|
|
match.yourdomain.com
|
|
moderation.yourdomain.com
|
|
notify.yourdomain.com
|
|
ns.yourdomain.com
|
|
platformnotifications.yourdomain.com
|
|
playersettings.yourdomain.com
|
|
roomcomments.yourdomain.com
|
|
roomieintegrations.yourdomain.com
|
|
rooms.yourdomain.com
|
|
storage.yourdomain.com
|
|
strings.yourdomain.com
|
|
strings-cdn.yourdomain.com
|
|
studio.yourdomain.com
|
|
thorn.yourdomain.com
|
|
videos.yourdomain.com
|
|
```
|
|
|
|
All of these point to the same `DorkNet.Server` application/container
|
|
port today. `admin` and `feed` serve static hosts; the rest are the
|
|
service URLs returned to the client by `ConfigService`.
|
|
|
|
---
|
|
|
|
## Dokploy: microservices scaffold
|
|
|
|
Use this to run the new gateway/service-host layout. It is not yet a
|
|
replacement for the full public API.
|
|
|
|
Create a Dokploy **Compose** service from one of these files:
|
|
|
|
| Compose file | Use |
|
|
|---|---|
|
|
| `docker-compose.microservices.yml` | Local/dev-style compose; use Dokploy's domain UI manually |
|
|
| `docker-compose.microservices.dokploy.yml` | Dokploy Traefik labels generated from `DORKNET_DOMAIN` |
|
|
|
|
Both compose files provide:
|
|
|
|
| Service | Purpose |
|
|
|---|---|
|
|
| `gateway` | Edge host scaffold; service map and service health probes |
|
|
| `identity` | Future identity/auth/accounts service |
|
|
| `rooms` | Future rooms/matchmaking/discovery service |
|
|
| `notify` | Future notification/presence service |
|
|
| `postgres` | Internal Postgres for the service network |
|
|
| `redis` | Internal Redis for ephemeral state and fan-out |
|
|
|
|
Only the gateway needs a public domain during scaffold testing. Route the
|
|
gateway domain to service `gateway`, container port `8080`.
|
|
|
|
In Dokploy's Compose domain modal:
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Service Name | `gateway` |
|
|
| Host | the domain you are adding |
|
|
| Path | `/` |
|
|
| Internal Path | `/` |
|
|
| Container Port | `8080` |
|
|
| Strip Path | off |
|
|
|
|
If the service dropdown says **Services not found**, deploy or redeploy
|
|
the Compose service first, then refresh the domain modal. Dokploy derives
|
|
the service list from the parsed compose file.
|
|
|
|
### Env-driven domains
|
|
|
|
Use `docker-compose.microservices.dokploy.yml` if you do not want to add
|
|
every domain row manually in Dokploy. Set:
|
|
|
|
```env
|
|
DORKNET_DOMAIN=yourdomain.com
|
|
```
|
|
|
|
That file adds Traefik labels to `gateway` for the apex plus every host
|
|
listed in the full-server domain list above, then sends them all to
|
|
container port `8080`. It also attaches the gateway to Dokploy's external
|
|
`dokploy-network`, which is why this is a separate file instead of the
|
|
default local compose file.
|
|
|
|
DNS still has to resolve to the Dokploy server. The simplest setup is an
|
|
apex record plus wildcard subdomain record:
|
|
|
|
```text
|
|
yourdomain.com A/AAAA <dokploy-server-ip>
|
|
*.yourdomain.com A/AAAA <dokploy-server-ip>
|
|
```
|
|
|
|
If you do not use wildcard DNS, add A/AAAA or CNAME records for each
|
|
listed subdomain.
|
|
|
|
When the gateway starts carrying the public API, every public DorkNet
|
|
domain listed above should point to `gateway`. Until then, keep the real
|
|
player-facing domains on the full `DorkNet.Server` application.
|
|
|
|
Set these Compose environment variables in Dokploy:
|
|
|
|
```env
|
|
DORKNET_S3_ENDPOINT=https://your-s3-api-endpoint
|
|
DORKNET_S3_ACCESS_KEY=your-access-key
|
|
DORKNET_S3_SECRET_KEY=your-secret-key
|
|
DORKNET_S3_REGION=garage
|
|
```
|
|
|
|
The compose services already refer to Postgres as `postgres` and Redis as
|
|
`redis` on the internal Compose network. Do not add an `object-storage`
|
|
service unless you intentionally want a local dev-only S3 emulator.
|
|
|
|
Useful smoke checks after deploy:
|
|
|
|
```bash
|
|
curl https://gateway.yourdomain.com/healthz
|
|
curl https://gateway.yourdomain.com/internal/services
|
|
curl https://gateway.yourdomain.com/internal/services/health
|
|
```
|
|
|
|
Expected during scaffold-only deploys: `/internal/services/health`
|
|
reports gateway-visible status for identity, rooms, and notify. It does
|
|
not prove the full game API has moved yet.
|
|
|
|
---
|
|
|
|
## S3 storage
|
|
|
|
DorkNet uses S3-compatible storage for room blobs, profile images,
|
|
camera photos, and CDN/image pipeline backing data. Create these buckets
|
|
before production cutover:
|
|
|
|
```text
|
|
profile-images
|
|
camera-photos
|
|
room-blobs
|
|
```
|
|
|
|
Garage-style endpoints usually use:
|
|
|
|
```env
|
|
S3__Endpoint=https://your-garage-or-s3-api
|
|
S3__Region=garage
|
|
S3__AccessKey=...
|
|
S3__SecretKey=...
|
|
```
|
|
|
|
Cloudflare R2 uses the S3 API endpoint, not a public bucket URL:
|
|
|
|
```env
|
|
S3__Endpoint=https://<cloudflare-account-id>.r2.cloudflarestorage.com
|
|
S3__Region=auto
|
|
S3__AccessKey=<r2 access key id>
|
|
S3__SecretKey=<r2 secret access key>
|
|
S3__MaxErrorRetry=1
|
|
S3__TimeoutSeconds=300
|
|
```
|
|
|
|
For the microservices compose file, use the `DORKNET_S3_*` equivalents;
|
|
Compose maps them into `S3__*` for the rooms service.
|
|
|
|
---
|
|
|
|
## First-time cutover from SQLite
|
|
|
|
1. Stop the local server so the SQLite source stops accepting writes.
|
|
2. Snapshot the SQLite database.
|
|
3. Provision Postgres, Redis, and the separate S3-compatible storage.
|
|
4. Run the migration/import tooling against the new Postgres and S3
|
|
targets.
|
|
5. Deploy the full `DorkNet.Server` application.
|
|
6. Verify `/healthz` returns 200 before sending players to the new host.
|
|
|
|
The server uses an advisory-lock guarded startup path for Postgres so
|
|
multiple replicas can start without racing schema/bootstrap work.
|
|
|
|
Rollback before players write to Postgres is simple: stop the deploy and
|
|
return to the SQLite snapshot. After players write to Postgres, rollback
|
|
means losing post-cutover writes unless you migrate them back.
|
|
|
|
---
|
|
|
|
## Photon Cloud
|
|
|
|
Use your own Photon AppIds. Rec Room's original Photon AppIds reject
|
|
external clients because their dashboard points CustomAuth at the
|
|
official backend.
|
|
|
|
1. Create a Photon Realtime app at <https://dashboard.photonengine.com>.
|
|
2. Create a Photon Voice app if voice chat is needed.
|
|
3. Set:
|
|
|
|
```env
|
|
Photon__AppId=<your realtime AppId>
|
|
Photon__VoiceAppId=<your voice AppId>
|
|
Photon__CloudRegion=eu
|
|
```
|
|
|
|
Server-side Photon custom auth exists at `/photon/customauth`, but the
|
|
2020 client does not send the needed AuthValues without client patching.
|
|
Leave Photon dashboard "Reject if Auth Failed" off unless the client mod
|
|
is updated to send `userid` and `LoginLock`.
|
|
|
|
---
|
|
|
|
## Future schema changes
|
|
|
|
SQLite dev DBs apply EF migrations. The production Postgres path is still
|
|
based on `EnsureCreated()` plus idempotent bootstrap steps. Until that is
|
|
changed to `Migrate()` under the same advisory lock, treat production
|
|
schema changes as explicit deployment work:
|
|
|
|
1. Add or update the entity model.
|
|
2. Add the migration for SQLite/dev.
|
|
3. Add any needed idempotent Postgres bootstrap SQL.
|
|
4. Deploy and verify `/healthz`.
|
|
|
|
See [`../DorkNet.Server/Data/MIGRATIONS.md`](../DorkNet.Server/Data/MIGRATIONS.md)
|
|
for the detailed migration discipline.
|