README.md (13237B)
1 # Introduction 2 3 The sandcastle is a containerized deployment of GNU Taler 4 5 It uses podman to build an image and run a single container that 6 has systemd running inside. 7 8 9 # Prerequisites 10 11 You need (on your host system): 12 13 * podman 14 * bash 15 * Python 3.10 or newer 16 17 The sandcastle-ng container exposes the GNU Taler APIs and Web interfaces 18 through Unix domain sockets. 19 20 Some of these services expect to be accessed via a certain hostname, 21 so it is recommended that you set up the following domain names: 22 23 * `exchange.$MYDOMAIN` for taler-exchange 24 * `backend.$MYDOMAIN` for taler-merchant 25 * `bank.$MYDOMAIN` for libeufin-bank 26 * `landing.$MYDOMAIN` for the demo landing page 27 * `shop.$MYDOMAIN` for the demo blog shop page 28 * `donations.$MYDOMAIN` for the demo donations page 29 * `paivana.$MYDOMAIN` for the demo Paivana paywall 30 31 Your host system should reverse-proxy HTTP(s) traffic to the respective service 32 socket. 33 34 35 # Upgrading Component Versions 36 37 `packages.toml` is the single source of truth for package repositories, tags, 38 Debian paths, dependencies, enabled state, and builders. It uses the same 39 `[repositories]` and `[packages]` layout as 40 `taler-deployment/packaging/ng/packages.toml`. 41 42 Run `./sandcastle-upgrade` to update package tags in `packages.toml` to the 43 latest upstream tag of the respective repository. 44 45 By default only production tags (`vX.Y.Z`, `deb-vX.Y.Z-R`) are considered. 46 Pass `--dev` to also consider dev tags (`vX.Y.Z-dev.N`). 47 Pass `--dry` to only show what would change. 48 Individual components can be given as arguments, e.g. 49 50 ./sandcastle-upgrade --dev taler-exchange gnunet 51 52 Packages whose configured tag is not a supported version tag are left alone. 53 Use `./sandcastle-upgrade --dry` to show available updates without changing the 54 configuration. 55 56 57 # Building the Container Image 58 59 1. Set the package's `tag` in `packages.toml` to the git tag you want to build. 60 61 2. Run `./sandcastle-build` to build the Taler container. The resulting container 62 will be tagged as `taler-base-all`. 63 64 Package builds are incremental. Built Debian packages and their build keys 65 are kept below `packages/`, while downloaded build data is kept below 66 `cache/`. A component is rebuilt when its resolved package configuration, 67 build logic, builder image, or one of its package dependencies changes. 68 Unrelated packages remain untouched. Failed builds are not recorded as 69 current, so they are retried on the next invocation. 70 71 Packages using the `pnpm-workspace` builder are grouped by repository and 72 tag. Each group clones and bootstraps the monorepo once, performs one 73 filtered pnpm install and build for all selected workspace dependency 74 closures, and then creates the individual Debian packages from the prebuilt 75 artifacts. 76 77 Apt, pnpm, Gradle, Cargo, npm, Go, and pip caches are shared between package 78 containers. Source checkouts and package build trees remain fresh. 79 80 Use `./sandcastle-build --no-cache` to rebuild the package builder, every 81 component package, and the final image without cached image layers. Shared 82 dependency and compiler caches are retained. 83 84 By default `sandcastle-build` builds from the `Dockerfile` 85 in the same directory as the script. 86 Anyhow you can pass a different container file like this: 87 88 ./sandcastle-build nightly.Dockerfile 89 90 91 # Configuring the Deployment 92 93 If you just want to play around with the Taler services inside the container, 94 or want to get an integration development environment, 95 there is a nice preset, see below. 96 Thus in these cases no configuration is required 97 and you can skip to "Running the Deployment" below. 98 99 For Taler developers, it is recommended that for each sandcastle deployment, 100 you clone the sandcastle-ng.git repository 101 (https://git.taler.net/sandcastle-ng.git) and create a branch with 102 deployment-specific changes. 103 104 Currently there is not much configuration. 105 106 The main adjustments to be made are: 107 108 * scripts/demo/setup-sandcastle.sh has the currency on top of the file 109 * Services use Unix sockets below `sockets/` by default. Set 110 `SANDCASTLE_SOCKET_DIR` to choose a different host directory. 111 112 To make adjustments for an environment without changing the 113 ``setup-sandcastle.sh`` script, you can use an override file 114 ``overrides/$YOUR_ENVIRONMENT``. This is a bash script that is sourced at the 115 beginning of ``setup-sandcastle.sh`` and can be used to customize 116 environment-specific settings such as hostnames. 117 118 In order to choose an override, 119 set the ``SANDCASTLE_OVERRIDE_NAME`` environment variable 120 before running `./sandcastle-run`: 121 122 SANDCASTLE_OVERRIDE_NAME=$YOUR_ENVIRONMENT ./sandcastle-run 123 124 125 The following variables are typically adjusted in an override file: 126 127 * ``CURRENCY``: Currency of the deployment 128 * ``MYDOMAIN``: Parent domain name for ``{bank,exchange,backend}`` services. 129 * ``EXTERNAL_PORT``: The host port the services will be available on. 130 * ``EXTERNAL_IP``: The host IP the services will be available on. 131 For security reasons this defaults to localhost (127.0.0.1). 132 * ``USE_INSECURE_SANDBOX_PASSWORDS``: 133 If set to `1`, use password `sandbox` for all services instead of random ones. 134 WARNING! Use only when listening to localhost! 135 * ``PAIVANA_DESTINATION``: Upstream website that the Paivana paywall 136 protects. Defaults to `https://www.taler.net/`. Note that this is an 137 *external* server that the container proxies to, it is not served by the 138 sandcastle itself. 139 * ``ENABLE_KYC``: Set to `1` to enable KYC; it is disabled by default. 140 * ``ENABLE_TURNSTILE``: Set to `0` to omit the Drupal Turnstile setup; it is 141 enabled by default. 142 143 144 # Running the Deployment 145 146 Run ``./sandcastle-run`` to run the single container. 147 The container will be named `taler-sandcastle`. 148 Wait until everything has been set up: 149 150 ./sandcastle-wait 151 152 While provisioning is running, this follows the output of 153 ``setup-sandcastle.service`` inside the container. It exits successfully once 154 provisioning has completed, or with a non-zero status if provisioning fails. 155 After a successful deployment, the landing host serves the Sandcastle version, 156 component versions, and deployment time at ``/metrics/sandcastle-status``. 157 158 Note that ``./sandcastle-run`` is just a wrapper around ``podman run``. 159 If required, you can pass addtional arguments to ``./sandcastle-run``. 160 These will be passed on to ``podman run``. Example: 161 162 ./sandcastle-run --log-level=debug 163 164 The running container exposes these services through bind-mounted Unix sockets: 165 166 | Service | Socket | 167 | --- | --- | 168 | Bank | `bank.sock` | 169 | Exchange | `exchange.sock` | 170 | Merchant backend | `merchant-backend.sock` | 171 | Landing page | `landing.sock` | 172 | Blog shop | `blog.sock` | 173 | Donations | `donations.sock` | 174 | Challenger | `challenger.sock` | 175 | Auditor | `auditor.sock` | 176 | Donau | `donau.sock` | 177 | Drupal | `drupal.sock` | 178 | Paivana | `paivana.sock` | 179 180 Exchange, Merchant, the Blog and Donations demos, Auditor, Donau, and Paivana 181 are exposed directly through their native listener or packaged systemd socket 182 activation. Caddy owns the bank socket to bridge libeufin-bank's internal TCP 183 listener, the landing socket to add the Sandcastle status endpoint, the 184 Challenger socket to serve the insecure demo challenges, and the Drupal socket 185 because it is Drupal's HTTP server. 186 187 For example, query the Exchange and merchant configuration endpoints with: 188 189 curl --unix-socket ./sockets/exchange.sock http://localhost/config 190 curl --unix-socket ./sockets/merchant-backend.sock http://localhost/config 191 192 The socket directory defaults to `./sockets`, relative to the repository, and 193 can be changed when starting the deployment: 194 195 SANDCASTLE_SOCKET_DIR=/run/taler-sandcastle ./sandcastle-run 196 197 Missing socket directories are created with mode `1777`, and the sockets have 198 mode `0666`, so a host reverse proxy running as a different user can connect to 199 them. A pre-existing custom directory must allow the relevant container 200 service users to create sockets. The bind mount uses Podman's shared SELinux 201 label; deployments with a confined host reverse proxy may additionally need 202 an appropriate local SELinux policy. 203 204 libeufin-bank does not yet support Unix sockets, so it listens on localhost 205 inside the container and Caddy exposes it through `bank.sock`. 206 207 The shared bank Caddy configuration redirects `/` to `/webui/` while preserving 208 query parameters. The demo links use language entry paths such as `/de/` and 209 `/de_CH/`, which redirect to `/webui/?lang=de` and 210 `/webui/?lang=de_CH`. The path language replaces an existing `lang` parameter; 211 other query parameters are retained. These temporary redirects apply to GET 212 and HEAD requests through both the bank socket and HTTP/HTTPS ingress. 213 214 Overrides that define `EXTERNAL_PORT`, such as `taler.localhost`, continue to 215 publish that single Caddy ingress port for local integration testing. 216 217 When starting sandcastle like 218 219 SANDCASTLE_OVERRIDE_NAME=taler.localhost ./sandcastle-run 220 221 the services will be available as 222 223 - http://taler.localhost:4321 224 - http://bank.taler.localhost:4321 225 - http://shop.taler.localhost:4321 226 - http://donations.taler.localhost:4321 227 - http://backend.taler.localhost:4321 - the merchant backend 228 - http://exchange.taler.localhost:4321 229 - http://auditor.taler.localhost:4321 230 - http://challenger.taler.localhost:4321 231 - http://paivana.taler.localhost:4321/en/ - www.taler.net behind a Taler paywall 232 (use the ``/en/`` entry point, as www.taler.net redirects ``/`` to its own domain) 233 234 This gives a nice environment for integration testing. 235 236 237 # Running the Unit Tests 238 239 Run the Python unit-test suite from the repository root: 240 241 python3 -m unittest discover -s tests -v 242 243 244 # Stopping the deployment 245 246 For stopping the deployment simply run 247 248 ``` 249 ./sandcastle-stop 250 ``` 251 252 which is just a shortcut for ``podman stop taler-sandcastle``. 253 254 255 # Watching Logs 256 257 Run ``./sandcastle-logs`` to watch the logs within the container. 258 You can pass addtional arguments to ``./sandcastle-logs``, 259 which will be passed on to ``journalctl`` in the container. Example: 260 261 ./sandcastle-logs --output=cat 262 263 264 # Poking Around 265 266 You can poke around in a running sandcastle instance by running 267 268 ``` 269 podman exec -it taler-sandcastle /bin/bash 270 ``` 271 272 Or, as a shortcut: 273 274 ``` 275 ./sandcastle-enter 276 ``` 277 278 This will drop you into a shell inside the running container, 279 where you have access to systemd, journalctl, etc. 280 281 282 # Data Storage 283 284 All persistent data is stored in a podman volume called 285 _talerdata_. You can see where it is in your filesystem 286 by running ``podman volume inspect talerdata``. 287 288 That volume also contains the postgres database files. 289 290 ## Cleaning the Data Storage 291 292 For cleaning the data storage run 293 294 ./sandcastle-plow 295 296 and for cleaning also the persistent storage run 297 298 ./sandcastle-plow all 299 300 301 # Provisioning Details 302 303 The whole deployment is configured by a script 304 mounted into the container as ``/provision/setup-sandcastle.sh``. 305 This script will be run as a oneshot systemd service and will disable itself after 306 the first success. 307 308 To troubleshoot, run ``journalctl -u setup-sandcastle.service``. 309 310 There are different setup scripts in the ``scripts/$SANDCASTLE_SETUP_NAME`` 311 folders. Specifically: 312 313 * ``none`` does no setup at all 314 * ``demo`` set up the usual Taler demo 315 * TBD: ``regio`` is a currency conversion setup 316 317 By default, ``demo`` is used. 318 To mount a different provision script, 319 set ``$SANDCASTLE_SETUP_NAME`` when running ``./sandcastle-run``, 320 like this 321 322 SANDCASTLE_SETUP_NAME=none ./sandcastle-run 323 324 325 You can always manually run any of the provisioning script inside the container as 326 ``/scripts/$SANDCASTLE_SETUP_NAME/setup-sandcastle.sh``. 327 328 # Importing / exporting 329 330 To migrate a sandcastle deployment, export / import can be used. 331 332 ``` 333 # Requires taler-sandcastle to be running. 334 # Export the sandcastle data to ./exported/ 335 ./sandcastle-export 336 337 # Other host: 338 # Request an import 339 touch exported/import-request 340 # Now the deployment script will pick up the data to import 341 ./sandcastle-run 342 ``` 343 344 # Neat Things That Already Work 345 346 * Rebulding the base image is incremental, since we use layers. If the tag 347 of the exchange is changed, only the exchange and components that depend 348 on it are rebuilt. 349 * Inside the container, the service names resolve to localhost, 350 and on localhost a reverse proxy with locally signed certificates 351 ensures that services can talk to each other *within* the container 352 by using their *public* base URL. 353 354 355 # Future Extensions 356 357 * Better way to access logs, better way to expose errors during provisioning 358 * The Dockerfile should introduce nightly tags for debian packages it builds. 359 Currently it just uses the latest defined version, which is confusing. 360 * Deploy the Taler woocommerce plugin, wordpress plugin, Joomla plugin 361 * Do self-tests of the deployment using the wallet CLI 362 * Running the auditor 363 * Running a currency conversion setup with multiple libeufin-bank instances 364 * Instead of requiring the reverse proxy to handle TLS, 365 the sandcastle container itself could do TLS termination with caddy. 366 * To improve performance, allow connecting to an external database 367 * Make it easy to import and export the persistent data 368 * Extra tooling to checkpoint images/containers to revert to a previous 369 state quickly.