|
| 1 | +# Demo App Deployment |
| 2 | + |
| 3 | +## Architecture |
| 4 | + |
| 5 | +``` |
| 6 | +push to main (demo/ changes) ─┐ |
| 7 | +new version tag ─┤─▶ GitHub Actions ─▶ build image ─▶ push to GHCR |
| 8 | + │ |
| 9 | + ▼ (via Tailscale) |
| 10 | + SSH into server ─▶ docker compose pull + up -d |
| 11 | +``` |
| 12 | + |
| 13 | +The container runs [FrankenPHP](https://frankenphp.dev/) in worker mode, serving HTTP on port 80. TLS termination is handled externally by your reverse proxy. |
| 14 | + |
| 15 | +## Trigger Conditions |
| 16 | + |
| 17 | +| Event | Condition | Result | |
| 18 | +|-------|-----------|--------| |
| 19 | +| Push to `main` | Files changed under `demo/` or `.github/workflows/deploy.yml` | Build + deploy `:latest` | |
| 20 | +| Version tag (e.g. `0.3`) | Tag commit must include a `demo/` file change (GitHub paths filter applies to tags too) | Build + deploy `:0.3` and `:latest` | |
| 21 | + |
| 22 | +> **Tagging tip**: If your release commit doesn't touch `demo/`, create the tag on a commit that does — for example, update `demo/DEPLOYMENT.md` or bump a version comment in any demo file. |
| 23 | +
|
| 24 | +## Required GitHub Secrets |
| 25 | + |
| 26 | +Configure these under **Settings → Secrets and variables → Actions** in the repository: |
| 27 | + |
| 28 | +| Secret | Description | |
| 29 | +|--------|-------------| |
| 30 | +| `TS_OAUTH_CLIENT_ID` | Tailscale OAuth client ID for the CI node | |
| 31 | +| `TS_OAUTH_CLIENT_SECRET` | Tailscale OAuth client secret | |
| 32 | +| `SERVER_TAILSCALE_IP` | Tailscale IP address of the deploy target | |
| 33 | +| `SERVER_USER` | SSH username on the deploy target | |
| 34 | +| `SERVER_SSH_KEY` | SSH private key (PEM) for the deploy target | |
| 35 | +| `GHCR_TOKEN` | GitHub PAT with `read:packages` scope, used to pull the image on the target | |
| 36 | +| `DEPLOY_COMPOSE_PATH` | Absolute path to the `docker-compose.yml` file on the deploy target | |
| 37 | + |
| 38 | +`GITHUB_TOKEN` (auto-provided by Actions) is used for pushing to GHCR from CI. |
| 39 | + |
| 40 | +## Target Host Setup |
| 41 | + |
| 42 | +The deploy target needs Docker installed and a `docker-compose.yml` in the path configured by `DEPLOY_COMPOSE_PATH`: |
| 43 | + |
| 44 | +```yaml |
| 45 | +services: |
| 46 | + demo: |
| 47 | + image: ghcr.io/ardenexal/php-fhir-tools:latest |
| 48 | + restart: unless-stopped |
| 49 | + ports: |
| 50 | + - "8080:80" |
| 51 | + env_file: |
| 52 | + - .env |
| 53 | +``` |
| 54 | +
|
| 55 | +The `.env` file in the same directory must set at minimum: |
| 56 | + |
| 57 | +```env |
| 58 | +APP_SECRET=<random 32-char hex string> |
| 59 | +``` |
| 60 | + |
| 61 | +Generate a value with: `openssl rand -hex 32` |
| 62 | + |
| 63 | +## Reverse Proxy |
| 64 | + |
| 65 | +The container serves plain HTTP on port 80 (`SERVER_NAME="http://:80"`). Configure your reverse proxy to forward to the host port you mapped (e.g. `8080`). Example Caddy block: |
| 66 | + |
| 67 | +``` |
| 68 | +your-domain.example.com { |
| 69 | + reverse_proxy localhost:8080 |
| 70 | +} |
| 71 | +``` |
| 72 | + |
| 73 | +## Tailscale ACL |
| 74 | + |
| 75 | +The GitHub Actions runner joins your tailnet using an OAuth client. Before this will work: |
| 76 | + |
| 77 | +1. Create an OAuth client at [tailscale.com/settings/oauth-clients](https://login.tailscale.com/admin/settings/oauthclients) with the `devices` write scope |
| 78 | +2. Ensure `tag:ci` exists in your ACL policy (Tailscale requires OAuth clients to specify an existing tag) |
| 79 | +3. Grant `tag:ci` SSH access to the deploy target in your ACL policy |
| 80 | + |
| 81 | +Example ACL entry: |
| 82 | + |
| 83 | +```json |
| 84 | +{ |
| 85 | + "action": "accept", |
| 86 | + "src": ["tag:ci"], |
| 87 | + "dst": ["tag:server:22"] |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +## Building Locally |
| 92 | + |
| 93 | +From the repository root: |
| 94 | + |
| 95 | +```bash |
| 96 | +docker build -f demo/Dockerfile -t fhir-demo . |
| 97 | +docker run -p 8080:80 -e APP_SECRET=$(openssl rand -hex 32) fhir-demo |
| 98 | +``` |
| 99 | + |
| 100 | +Then open `http://localhost:8080`. |
0 commit comments