189 lines
6.2 KiB
Markdown
189 lines
6.2 KiB
Markdown
# Single-VM deployment
|
|
|
|
The deployment is relocatable. Compose paths and management commands are
|
|
resolved relative to the repository checkout, so it can live anywhere on the
|
|
VM. `/opt/idssys/TA-Deployment-Access` is only one possible example.
|
|
|
|
One Compose project manages:
|
|
|
|
- TAPM broker, with an embedded SQLite database
|
|
- Gitea, with its own embedded SQLite database and repository storage
|
|
- Nginx, terminating TLS for the broker and Gitea
|
|
- Certbot, as an on-demand utility for certificate issuance and renewal
|
|
|
|
In production, only the configured Nginx HTTP and HTTPS ports are published.
|
|
They default to 8680 and 8643. Inside Docker, Nginx listens on ports 80 and 443,
|
|
the broker on 8080, and Gitea on 3000. Gitea SSH is disabled.
|
|
|
|
## 1. VM and network
|
|
|
|
Install Docker Engine with Compose v2. Permit the selected HTTP and HTTPS ports
|
|
and forward public TCP 80 and 443 from the datacenter edge to them. The
|
|
Create public DNS A/AAAA records for both application names before requesting
|
|
the certificate.
|
|
|
|
Public port 80 must reach the container's port 80 for HTTP-01 certificate
|
|
renewal. For example, if `HTTP_PORT=8080`, the edge must forward public port 80
|
|
to VM port 8080. If IPv6 is published, it must reach this same VM.
|
|
|
|
## 2. Install the repository
|
|
|
|
```sh
|
|
sudo mkdir -p /YOUR/INSTALL/PARENT
|
|
sudo git clone GITEA-REPOSITORY-URL /YOUR/INSTALL/PARENT/TA-Deployment-Access
|
|
sudo chown -R 1000:1000 /YOUR/INSTALL/PARENT/TA-Deployment-Access
|
|
cd /YOUR/INSTALL/PARENT/TA-Deployment-Access
|
|
cp .env.example .env
|
|
chmod 600 .env
|
|
```
|
|
|
|
Set `BROKER_DOMAIN`, `GITEA_DOMAIN`, and `LETSENCRYPT_EMAIL` first. `HTTP_PORT`
|
|
and `HTTPS_PORT` control the VM-side Docker bindings and default to 8680 and
|
|
8643. The datacenter edge should therefore forward public ports 80 and 443 to
|
|
VM ports 8680 and 8643. Replace all example domains in the TAPM variables.
|
|
Generate the cookie secret with:
|
|
|
|
```sh
|
|
openssl rand -base64 48
|
|
```
|
|
|
|
Runtime state is deliberately visible below the checkout:
|
|
|
|
```text
|
|
config/
|
|
├── broker/ # tapm.db and SQLite WAL files
|
|
├── gitea/
|
|
│ ├── config/ # app.ini and Gitea configuration
|
|
│ └── data/ # repositories, packages, and gitea.db
|
|
├── letsencrypt/ # account data, certificate, and private key
|
|
├── ssl/ # optional administrator-provided certificate
|
|
├── certbot-webroot/ # HTTP-01 challenge files
|
|
└── backups/ # local offline snapshots
|
|
```
|
|
|
|
The contents are ignored by Git. They must never be committed.
|
|
|
|
## 3. Bootstrap Gitea and TLS
|
|
|
|
```sh
|
|
./manage.sh bootstrap
|
|
```
|
|
|
|
This prepares the runtime directories, creates the private Docker network,
|
|
starts Gitea and the HTTP-only Nginx configuration, obtains a certificate when
|
|
using Let's Encrypt, and switches Nginx to TLS.
|
|
|
|
For an administrator-provided certificate instead, place the certificate and
|
|
key in `config/ssl/` and set:
|
|
|
|
```dotenv
|
|
SSL_MODE=custom
|
|
SSL_CERTIFICATE_DIR=./config/ssl
|
|
SSL_CERTIFICATE_FILE=fullchain.pem
|
|
SSL_CERTIFICATE_KEY_FILE=privkey.pem
|
|
```
|
|
|
|
The certificate must cover both `BROKER_DOMAIN` and `GITEA_DOMAIN`. With custom
|
|
mode, `bootstrap` skips Certbot and `renew` is intentionally unavailable;
|
|
replace the files through the certificate provider's process and restart or
|
|
reload Nginx. `SSL_CERTIFICATE_DIR` can point at another directory relative to
|
|
the repository or at an absolute host path.
|
|
|
|
Create the initial Gitea administrator:
|
|
|
|
```sh
|
|
docker compose exec gitea \
|
|
gitea admin user create \
|
|
--admin --username taiadmin --email ADMIN-EMAIL \
|
|
--password 'TEMPORARY-RANDOM-PASSWORD' --must-change-password
|
|
```
|
|
|
|
Sign in to Gitea at `https://GITEA_DOMAIN`, create the `TAI` organization, and
|
|
create:
|
|
|
|
1. `tapm-packages`, with a read-only package token.
|
|
2. `tapm-publisher`, with a write package token.
|
|
3. An OAuth2 application whose callback is
|
|
`https://BROKER_DOMAIN/auth/callback`.
|
|
|
|
Place those token and OAuth values in `.env`. The broker cannot start until all
|
|
required credentials are present.
|
|
|
|
## 4. Start the complete deployment
|
|
|
|
```sh
|
|
./manage.sh start
|
|
./manage.sh status
|
|
curl --fail "https://BROKER_DOMAIN/health/ready"
|
|
curl --fail "https://GITEA_DOMAIN/api/healthz"
|
|
```
|
|
|
|
The broker automatically applies SQLite schema migrations before starting.
|
|
Gitea uses its own SQLite database at
|
|
`config/gitea/data/data/gitea.db`.
|
|
|
|
For local testing that bypasses Nginx, set `BROKER_DIRECT_PORT` and
|
|
`GITEA_DIRECT_PORT` in `.env`, then run:
|
|
|
|
```sh
|
|
./manage.sh start-direct
|
|
```
|
|
|
|
This adds host mappings to the broker's port 8080 and Gitea's port 3000. Do not
|
|
use the direct-port override on an Internet-facing production VM. Return to the
|
|
production port layout with:
|
|
|
|
```sh
|
|
./manage.sh start
|
|
docker compose -f compose.yaml -f compose.tls.yaml up -d --force-recreate broker gitea
|
|
```
|
|
|
|
## 5. Move repositories
|
|
|
|
For each existing repository, create an empty matching repository in the new
|
|
Gitea and mirror all refs:
|
|
|
|
```sh
|
|
git clone --mirror OLD-REPOSITORY-URL
|
|
cd REPOSITORY.git
|
|
git push --mirror https://GITEA_DOMAIN/TAI/REPOSITORY.git
|
|
```
|
|
|
|
Update developer remotes, CI credentials, submodules, documentation, and the Go
|
|
module path only if the hostname embedded in the module path is also changing.
|
|
Move the deployment repository last so this checkout remains updateable during
|
|
the transition.
|
|
|
|
## 6. Renewal and backups
|
|
|
|
When `SSL_MODE=letsencrypt`, run renewal twice daily from root's crontab:
|
|
|
|
```cron
|
|
17 3,15 * * * cd /YOUR/INSTALL/PARENT/TA-Deployment-Access && ./manage.sh renew
|
|
```
|
|
|
|
Create an application-consistent local snapshot with:
|
|
|
|
```sh
|
|
./manage.sh backup
|
|
```
|
|
|
|
The backup briefly stops both SQLite writers. Copy `config/backups/` to storage
|
|
outside the VM. A backup left only on this VM does not protect against VM or
|
|
datacenter loss. Also back up `.env` through a secrets-aware system.
|
|
|
|
## 7. Updates
|
|
|
|
```sh
|
|
cd /YOUR/INSTALL/PARENT/TA-Deployment-Access
|
|
./update.sh
|
|
```
|
|
|
|
The updater operates only on the current VM. It fast-forwards the checked-out
|
|
branch, pulls the pinned Gitea image, rebuilds and restarts the local stack, and
|
|
waits for the local broker to become healthy. It has no peer discovery, SSH, or
|
|
multi-node update behavior.
|
|
|
|
Pin image versions as supplied and review release notes before changing them.
|
|
Never change Gitea between rootless and rootful image families in place.
|