Skip to content

Commit 3a9bb76

Browse files
committed
PXC-5141 - [DOCS] - [feedback] It doesn't work with podman compose 8.4
modified: docs/docker-compose.md
1 parent a94d125 commit 3a9bb76

1 file changed

Lines changed: 107 additions & 38 deletions

File tree

docs/docker-compose.md

Lines changed: 107 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,21 @@ We gather [Telemetry data](telemetry.md) in the Percona packages and Docker imag
88

99
--8<--- "get-help-snip.md"
1010

11-
This guide shows you how to deploy a three-node Percona XtraDB Cluster 8.4 using Docker Compose. You generate SSL certificates on the first node and copy them to the other two nodes to enable secure communication.
11+
The guide shows you how to deploy a three-node Percona XtraDB Cluster 8.4 using Docker Compose. You generate SSL certificates on the first node and copy them to the other two nodes to enable secure communication.
1212

13-
The following procedure describes setting up a simple 3-node cluster
14-
for evaluation and testing purposes. Do not use these instructions in a
15-
production environment because the MySQL certificates generated in this
16-
procedure are self-signed.
17-
18-
In a production environment, you should generate and store the certificates to be used by Docker and configure proper storage, security, backup, and monitoring systems.
13+
The following procedure is for evaluation and testing only. Do not use these instructions in a production environment because the MySQL certificates generated here are self-signed. In production, generate and store proper certificates and configure storage, security, backup, and monitoring.
1914

2015
## Prerequisites
2116

22-
* Docker and Docker Compose installed
17+
* Docker and Docker Compose installed (or Podman 4.1 or later and Podman Compose; see [Appendix: Podman Alternative](#appendix-podman-alternative))
2318

2419
* At least 3 GB of memory per container
25-
20+
2621
* Familiarity with Docker volumes and networks
2722

2823
## Directory Structure
2924

30-
You must create a separate directory structure to organize your configuration, certificate files, and Docker Compose setup. This step keeps your deployment clean and easy to manage.
25+
You must create a separate directory structure to organize your configuration, certificate files, and Docker Compose setup. The directory structure keeps your deployment clean and easy to manage.
3126

3227
Run the following commands to create the directory structure:
3328

@@ -40,9 +35,11 @@ After running these commands, your working directory (pxc-cluster/) will contain
4035

4136
![PXC cluster directories](_static/pxc-cluster-dirs.png)
4237

43-
This structure helps manage configuration files, TLS/SSL certificates, and setup scripts, ensuring a tidy and easy-to-manage deployment.
38+
The directory structure helps manage configuration files, TLS/SSL certificates, and setup scripts, ensuring a tidy and easy-to-manage deployment.
4439
{.power-number}
4540

41+
## Configuration Files
42+
4643
1. Create conf.d/custom.cnf with minimal SSL settings:
4744

4845

@@ -62,6 +59,8 @@ This structure helps manage configuration files, TLS/SSL certificates, and setup
6259
6360
Add `.env` to your .gitignore file to prevent committing secrets to version control.
6461
62+
## SSL Certificate Generation
63+
6564
3. Copy the SSL certificate generation script. Save the script as `init/create-ssl-certs.sh`:
6665
6766
```text
@@ -101,37 +100,21 @@ This structure helps manage configuration files, TLS/SSL certificates, and setup
101100
./init/create-ssl-certs.sh
102101
```
103102
104-
4. Copy Certificates to All Nodes
103+
4. Copy Certificates to All Nodes (only for multi-host)
105104
106-
All three nodes in the cluster must use the same set of SSL certificates. After generating the certificates in the certs/ directory on node 1, you need to copy them to the directories for node 2 and node 3.
107-
108-
If you run all containers from a single project directory (like with Docker Compose on one host), you can reuse the same certs/ directory for all nodes. However, you must explicitly copy the certificates if you’re organizing them into separate directories or deploying on separate hosts.
109-
110-
To create the directories for node 2 and node 3:
111-
112-
113-
```shell
114-
mkdir -p certs-node2
115-
mkdir -p certs-node3
116-
```
117-
118-
Then copy the certificates:
119-
120-
121-
```shell
122-
cp -r certs/* certs-node2/
123-
cp -r certs/* certs-node3/
124-
```
105+
All three nodes in the cluster must use the same set of SSL certificates. The `docker-compose.yml` in the guide mounts the same `./certs` directory for all three services (pxc1, pxc2, pxc3). For a single-host deployment, you do not need to create separate certificate directories; the `certs/` you created in step 5 is used by all nodes.
125106
126-
If you’re deploying on separate machines, run the following from node 1:
107+
If you deploy on separate machines instead of one host, copy the certificates to each machine so each has its own `certs/` (or equivalent path) for its Compose project. From node 1, run:
127108
128109
129110
```shell
130111
scp -r ./certs/ user@node2-host:/path/to/pxc-cluster/certs
131112
scp -r ./certs/ user@node3-host:/path/to/pxc-cluster/certs
132113
```
133114
134-
Ensure each container mounts its own copy of the certs/ directory.
115+
Ensure each host's Compose file mounts that host's certificate directory.
116+
117+
## Docker Compose Setup
135118
136119
5. Create docker-compose.yml:
137120
@@ -143,11 +126,11 @@ This structure helps manage configuration files, TLS/SSL certificates, and setup
143126
environment:
144127
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
145128
- CLUSTER_NAME=pxc-cluster
146-
- CLUSTER_JOIN=pxc2,pxc3
147129
- XTRABACKUP_PASSWORD=${XTRABACKUP_PASSWORD}
148130
volumes:
149131
- ./certs:/etc/mysql/certs:ro
150132
- ./conf.d:/etc/percona-xtradb-cluster.conf.d:ro
133+
- ./data-pxc1:/var/lib/mysql
151134
networks:
152135
- pxcnet
153136
ports:
@@ -164,11 +147,12 @@ This structure helps manage configuration files, TLS/SSL certificates, and setup
164147
environment:
165148
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
166149
- CLUSTER_NAME=pxc-cluster
167-
- CLUSTER_JOIN=pxc1,pxc3
150+
- CLUSTER_JOIN=pxc1
168151
- XTRABACKUP_PASSWORD=${XTRABACKUP_PASSWORD}
169152
volumes:
170153
- ./certs:/etc/mysql/certs:ro
171154
- ./conf.d:/etc/percona-xtradb-cluster.conf.d:ro
155+
- ./data-pxc2:/var/lib/mysql
172156
networks:
173157
- pxcnet
174158
healthcheck:
@@ -182,11 +166,12 @@ This structure helps manage configuration files, TLS/SSL certificates, and setup
182166
environment:
183167
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
184168
- CLUSTER_NAME=pxc-cluster
185-
- CLUSTER_JOIN=pxc1,pxc2
169+
- CLUSTER_JOIN=pxc1
186170
- XTRABACKUP_PASSWORD=${XTRABACKUP_PASSWORD}
187171
volumes:
188172
- ./certs:/etc/mysql/certs:ro
189173
- ./conf.d:/etc/percona-xtradb-cluster.conf.d:ro
174+
- ./data-pxc3:/var/lib/mysql
190175
networks:
191176
- pxcnet
192177
healthcheck:
@@ -199,6 +184,8 @@ This structure helps manage configuration files, TLS/SSL certificates, and setup
199184
driver: bridge
200185
```
201186
187+
## Deployment
188+
202189
6. Start the Cluster
203190
204191
Start node 1 to initialize the cluster:
@@ -207,23 +194,105 @@ This structure helps manage configuration files, TLS/SSL certificates, and setup
207194
```shell
208195
docker compose up -d pxc1
209196
```
197+
(With Podman: `podman compose up -d pxc1` or `podman-compose up -d pxc1`.)
210198
211199
Then, start the remaining nodes:
212200
213201
214202
```shell
215203
docker compose up -d pxc2 pxc3
216204
```
205+
(With Podman: `podman compose up -d pxc2 pxc3` or `podman-compose up -d pxc2 pxc3`.)
206+
207+
## Validation
217208
218209
7. Validate the Cluster
219210
220-
Check the status of each node:
211+
Check the status of each node. Exact commands (run from the host; use the same password as in your `.env`):
221212
222-
223213
```shell
224214
docker exec -it pxc1 mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
225215
docker exec -it pxc2 mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SHOW STATUS LIKE 'wsrep_cluster_status';"
226216
```
217+
(With Podman: use `podman exec` instead of `docker exec`.)
227218
228219
You should see all three nodes joined and synchronized.
229220
221+
## Troubleshooting
222+
223+
* Containers exit or fail to start: Check logs with `docker compose logs pxc1` (and pxc2, pxc3). Ensure the bootstrap node (pxc1) is healthy before starting pxc2 and pxc3.
224+
225+
* Cluster size stays at 1: Start pxc1 first, wait for pxc1 to be ready (healthcheck passing), then start pxc2 and pxc3. If nodes start too soon, the nodes may not join; restart pxc2 and pxc3 after pxc1 is up.
226+
227+
* Permission denied on certs or config: Ensure `certs/` and `conf.d/` are readable by the container. On SELinux with Podman, use the `:Z` or `:z` volume option (see [Appendix: Podman Alternative](#appendix-podman-alternative)).
228+
229+
* Nodes cannot reach each other: Verify all containers are on the same network (`docker network inspect pxc-cluster_pxcnet` or equivalent). Open firewall ports 3306, 4567, 4568, and 4444 if running on separate hosts.
230+
231+
## Cleanup and Shutdown
232+
233+
To stop the cluster and remove containers (data in `data-pxc1/`, `data-pxc2/`, `data-pxc3/` is preserved):
234+
235+
```shell
236+
docker compose down
237+
```
238+
239+
To stop and remove containers and volumes (the `-v` option deletes all database data):
240+
241+
```shell
242+
docker compose down -v
243+
```
244+
245+
Note: The Compose file in the guide uses bind mounts (`./data-pxc1`, etc.), not named volumes, so `-v` removes only any named volumes if present. To fully reset, remove the data directories manually: `rm -rf data-pxc1 data-pxc2 data-pxc3` (only when the containers are stopped).
246+
247+
## Appendix: Podman Alternative
248+
249+
Podman can be used as an alternative to Docker because Podman supports the same container images. However, Podman is not fully compatible with Docker Compose.
250+
251+
To run the deployment with Podman, you may need to use tools such as podman compose, podman-compose, or a configured Docker Compose compatibility layer, depending on your environment.
252+
253+
Podman uses a different architecture (for example, pods and rootless containers), so networking, volume mounts, and service behavior may differ from Docker Compose.
254+
255+
The deployment is designed and tested with Docker Compose. Podman support is not guaranteed. If you use Podman, verify that the cluster operates correctly before using the cluster beyond testing or experimentation.
256+
257+
You can use the same Compose file and workflow with [Podman](https://podman.io/). Use Podman 4.1 or later; the built-in `podman compose` subcommand requires 4.1 or newer. With older Podman, use the separate podman-compose tool. Then:
258+
259+
* Prerequisites: Podman and Podman Compose (for example, `pip install podman-compose` or your distro's package) if you are not using built-in `podman compose`. For rootless Podman, ensure the user has enough resources (for example, `sysctl user.max_user_namespaces` and subuid/subgid ranges).
260+
261+
* Commands: Replace `docker compose` with `podman compose` or `podman-compose`, and `docker exec` with `podman exec`. Examples:
262+
263+
* Start node 1: `podman compose up -d pxc1` (or `podman-compose up -d pxc1`)
264+
265+
* Start other nodes: `podman compose up -d pxc2 pxc3`
266+
267+
* Validate: `podman exec -it pxc1 mysql -uroot -p${MYSQL_ROOT_PASSWORD} -e "SHOW STATUS LIKE 'wsrep_cluster_size';"`
268+
269+
* Directory structure: The same layout (`pxc-cluster/` with `certs/`, `conf.d/`, and `init/`) works with Podman. Run `podman compose` from the project directory (for example, `pxc-cluster/`) so the relative volume paths in the Compose file resolve correctly.
270+
271+
* Compose file: The `docker-compose.yml` in the guide works as-is with Podman; the `bridge` network and volume mounts are supported. For rootless Podman, see the volume mount options below.
272+
273+
### Handling rootless permissions (most important for Podman)
274+
275+
In Docker, the daemon runs as root and can override file permissions. In Podman, if you run as a normal user, the MySQL process inside the container (usually UID 1001 or 999) may not have permission to read the files you created on the host. Ensure the files are readable by the container. On systems with SELinux, use the `:Z` (private) or `:z` (shared) mount option so Podman relabels the volume for the container. In your `docker-compose.yml`, use:
276+
277+
```text
278+
volumes:
279+
- ./certs:/etc/mysql/certs:ro,Z
280+
- ./conf.d:/etc/percona-xtradb-cluster.conf.d:ro,Z
281+
```
282+
283+
Apply the same volume options to every service (pxc1, pxc2, pxc3). Without `:Z` or `:z`, the container may fail to read certs or config when running rootless on SELinux.
284+
285+
### podman-compose vs docker-compose
286+
287+
* If you use podman-compose (the Python tool): podman-compose reads the directory structure and `.env` file the same way Docker does.
288+
289+
* If you use docker-compose with the Podman socket: Using docker-compose with the Podman socket is often more stable for PXC. Set `DOCKER_HOST` to point at the Podman socket (for example, `unix:///run/user/$(id -u)/podman/podman.sock`) so `docker compose` talks to Podman.
290+
291+
### Network considerations
292+
293+
PXC uses specific ports for cluster communication (4567, 4568, 4444). Podman uses different networking (netavark or CNI). If nodes cannot find each other:
294+
295+
* Keep using a named network in the Compose file (for example, `pxcnet`) so Podman can resolve container names (pxc1, pxc2, pxc3).
296+
297+
* If problems persist, try setting `network_mode: slirp4netns` on the services, or run the stack rootful to use the default bridge.
298+

0 commit comments

Comments
 (0)