|
| 1 | +# Using the Docker plugin |
| 2 | + |
| 3 | +The **docker** plugin adds a `powersync docker` topic for running a self-hosted PowerSync stack with Docker Compose. You scaffold a compose layout once with **`powersync docker init`**, then use **deploy**, **start**, and **stop** to run the stack. No need to edit config for basic use; the PowerSync container reads **docker/.env** and resolves **`!env`** in **service.yaml** at runtime. |
| 4 | + |
| 5 | +## Prerequisites |
| 6 | + |
| 7 | +- A self-hosted PowerSync project: **service.yaml** with `_type: self-hosted` in your config directory (default **powersync/**). Create one with **`powersync init --type=self-hosted`** if needed. |
| 8 | +- Docker and Docker Compose (Compose V2) installed. |
| 9 | +- Linking (**link.yaml**, API_URL, PS_TOKEN) is **optional** for docker commands; they only need the project directory and the compose dir. |
| 10 | + |
| 11 | +## Local configuration created by the plugin |
| 12 | + |
| 13 | +Docker commands work against a **compose directory** inside your PowerSync config directory. By default that directory is **powersync/docker/** (override with **`--compose-dir`** on deploy/start/stop). Init creates: |
| 14 | + |
| 15 | +- **powersync/docker/** – Compose project root. |
| 16 | + - **docker-compose.yaml** – Includes database and storage compose partials and the PowerSync service (uses **env_file: .env**; mounts **service.yaml** and **sync.yaml**). |
| 17 | + - **.env** – Merged from template snippets and PowerSync vars (defaults; no manual setup required for basic use). |
| 18 | + - **modules/** – Copied database and storage modules (each with its own compose partial and **template.env**). |
| 19 | + |
| 20 | +Init also: |
| 21 | + |
| 22 | +- Merges **service snippets** into **powersync/service.yaml** (replication and storage sections), **preserving the `!env` tag** so the PowerSync container resolves values from **docker/.env** at runtime. |
| 23 | +- Creates or updates **powersync/link.yaml** with **`plugins.docker.project_name`** so deploy/start/stop use the same Compose project name. |
| 24 | + |
| 25 | +You can use a different config directory with **`--directory`** (e.g. **`--directory my-powersync`**); the compose dir is then **my-powersync/docker/** by default. |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +## Workflow: init then deploy |
| 30 | + |
| 31 | +### 1. Create the Docker layout (init) |
| 32 | + |
| 33 | +From your repo root, run init with the database and storage modules you want (e.g. postgres for both): |
| 34 | + |
| 35 | +```bash |
| 36 | +powersync docker init --database postgres --storage postgres |
| 37 | +``` |
| 38 | + |
| 39 | +This creates **powersync/docker/** with: |
| 40 | + |
| 41 | +- **docker-compose.yaml** – Database (pg-db), storage (pg-storage), and PowerSync service. |
| 42 | +- **.env** – Default values for DB credentials, URIs, port, JWKS URL, etc. |
| 43 | +- **modules/database-postgres/** and **modules/storage-postgres/** – Compose partials and env snippets. |
| 44 | + |
| 45 | +It also merges replication and storage config into **powersync/service.yaml** (with **`!env PS_DATA_SOURCE_URI`** and **`!env PS_STORAGE_SOURCE_URI`** preserved) and sets **plugins.docker.project_name** in **powersync/link.yaml** (derived from the config directory name, or use **`--project-name`**). |
| 46 | + |
| 47 | +### 2. Start the stack (deploy) |
| 48 | + |
| 49 | +No need to edit **.env** for default setups. Run: |
| 50 | + |
| 51 | +```bash |
| 52 | +powersync docker deploy |
| 53 | +``` |
| 54 | + |
| 55 | +This runs **`docker compose up -d --force-recreate`** in **powersync/docker/** (using the project name from **link.yaml**). Images are pulled if missing. The PowerSync container gets all env from **docker/.env** via **env_file** and resolves **`!env`** in **service.yaml** at runtime. |
| 56 | + |
| 57 | +### 3. Start and stop later |
| 58 | + |
| 59 | +- **Start** (after stop or reboot): **`powersync docker start`** → `docker compose up -d` |
| 60 | +- **Stop**: **`powersync docker stop`** → `docker compose down` |
| 61 | + |
| 62 | +All of these use the same compose dir (**powersync/docker/** by default) and project name from **link.yaml**. |
| 63 | + |
| 64 | +--- |
| 65 | + |
| 66 | +## Commands reference |
| 67 | + |
| 68 | +| Command | Description | |
| 69 | +| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 70 | +| **`powersync docker init`** | Create **powersync/docker/** with chosen database and storage modules, **.env**, and merged **service.yaml** snippets. Requires **`--database`** and **`--storage`**. Writes **link.yaml** with **plugins.docker.project_name**. | |
| 71 | +| **`powersync docker deploy`** | Start or recreate containers (`docker compose up -d --force-recreate`). Images are pulled if missing. | |
| 72 | +| **`powersync docker start`** | Start the stack (`docker compose up -d`). | |
| 73 | +| **`powersync docker stop`** | Stop the stack (`docker compose down`). | |
| 74 | + |
| 75 | +Run **`powersync docker`** (no subcommand) to see help. |
| 76 | + |
| 77 | +--- |
| 78 | + |
| 79 | +## Flags |
| 80 | + |
| 81 | +- **`--directory`** – PowerSync config directory (default: **powersync**). Used by all docker commands. |
| 82 | +- **`--database`** – Database module for **init** (e.g. **postgres**). Required for init. |
| 83 | +- **`--storage`** – Storage module for **init** (e.g. **postgres**). Required for init. |
| 84 | +- **`--project-name`** – Docker Compose project name for **init** (default: derived from config directory name, sanitized). |
| 85 | +- **`--compose-dir`** – Compose directory relative to config (default: **docker**). Used by deploy, start, stop. Compose file is **docker-compose.yaml** inside this dir. |
| 86 | +- **`--api-url`** – PowerSync API URL (optional; for consistency with other self-hosted commands; not required for docker init/deploy/start/stop). |
| 87 | + |
| 88 | +--- |
| 89 | + |
| 90 | +## How init uses templates |
| 91 | + |
| 92 | +Templates are **composable modules** by category and implementation: |
| 93 | + |
| 94 | +- **database/** – Replication source (e.g. **postgres**). |
| 95 | +- **storage/** – PowerSync bucket metadata (e.g. **postgres**). |
| 96 | + |
| 97 | +Each module provides: |
| 98 | + |
| 99 | +- A **compose partial** (**`<impl>.<category>.compose.yaml`**) – Included by the main **docker-compose.yaml** (e.g. pg-db, pg-storage services). |
| 100 | +- A **service snippet** (**`<impl>.<category>.service.yaml`**) – Merged into **powersync/service.yaml** (replication or storage section). Snippets use **`!env`** (e.g. **`uri: !env PS_DATA_SOURCE_URI`**) so the PowerSync container resolves values from **docker/.env** at runtime. |
| 101 | +- **template.env** – Env vars for that module. Init merges these into **powersync/docker/.env**. |
| 102 | + |
| 103 | +Init copies the selected modules into **powersync/docker/modules/**, generates **docker-compose.yaml** (include of both partials plus the PowerSync service with **env_file: .env**), merges **template.env** into **.env**, and merges the service snippets into **service.yaml** while **preserving `!env` tags** so the container does substitution at runtime. |
| 104 | + |
| 105 | +--- |
| 106 | + |
| 107 | +## Using a different config or compose directory |
| 108 | + |
| 109 | +**Different config directory:** |
| 110 | + |
| 111 | +```bash |
| 112 | +powersync docker init --directory=my-powersync --database postgres --storage postgres |
| 113 | +powersync docker deploy --directory=my-powersync |
| 114 | +``` |
| 115 | + |
| 116 | +**Different compose directory** (e.g. **docker-dev/**): |
| 117 | + |
| 118 | +```bash |
| 119 | +powersync docker deploy --compose-dir=docker-dev |
| 120 | +powersync docker start --compose-dir=docker-dev |
| 121 | +powersync docker stop --compose-dir=docker-dev |
| 122 | +``` |
| 123 | + |
| 124 | +--- |
| 125 | + |
| 126 | +## Optional: linking for other self-hosted commands |
| 127 | + |
| 128 | +Docker commands do **not** require **link.yaml** or API_URL/PS_TOKEN for init, deploy, start, or stop. If you also want to run **fetch status**, **validate**, **generate schema**, or **generate token** against the same self-hosted instance, link it so those commands know the API URL and (if needed) the API key: |
| 129 | + |
| 130 | +```bash |
| 131 | +# After the stack is running, link to it (use the URL where PowerSync is reachable) |
| 132 | +powersync link self-hosted --api-url=http://localhost:8080 |
| 133 | +# You will be prompted for the API key, or set PS_TOKEN so link.yaml can use !env PS_TOKEN |
| 134 | + |
| 135 | +# Then you can run other self-hosted commands without passing --api-url |
| 136 | +powersync fetch status |
| 137 | +powersync validate |
| 138 | +powersync generate schema --output=ts --output-path=./schema.ts |
| 139 | +``` |
| 140 | + |
| 141 | +You can supply **`--api-url`** (and **PS_TOKEN** in the environment) on individual commands instead of linking if you prefer. |
0 commit comments