|
| 1 | +# Use Docker Compose and named volumes |
| 2 | + |
| 3 | +Docker Compose simplifies managing containerized services. This guide shows how to run Percona Server for MySQL 8.0 with persistent storage for data, logs, and backups using named Docker volumes. |
| 4 | + |
| 5 | +## Benefits |
| 6 | + |
| 7 | +Creating a `docker-compose.yml` file offers numerous advantages for managing containerized applications effectively: |
| 8 | + |
| 9 | +| Benefit | Description | |
| 10 | +|----------------------------------------|-----------------------------------------------------------------------------------------------------------| |
| 11 | +| Simplifies multi-container management | Define and manage multiple services (containers) in a single configuration file, making it easy to run, stop, and scale your application. | |
| 12 | +| Automates dependency handling | Specify dependencies between services, ensuring containers start in the correct order, such as databases starting before application servers. | |
| 13 | +| Enhances portability | Share the docker-compose.yml file across environments (development, staging, production) to ensure consistent behavior regardless of system setup. | |
| 14 | +| Supports scalability | Easily scale services using the docker-compose up --scale command, allowing you to run multiple instances of specific containers. | |
| 15 | +| Improves readability | Centralizes configuration in a human-readable YAML format, making it easier to understand and modify compared to command-line options. | |
| 16 | +| Enables reproducibility | Store application settings and container configurations in version control to ensure consistent deployments. | |
| 17 | +| Allows persistent data | Define volumes directly in the file to persist data for services, ensuring storage remains intact even when containers are stopped. | |
| 18 | +| Facilitates networking | Automatically sets up networks for containers to communicate with each other without requiring manual configuration. | |
| 19 | +| Simplifies environment variables management | Integrate .env files to externalize sensitive information like database passwords and access tokens. | |
| 20 | +| Reduces errors | Avoid repetitive CLI commands by storing configurations in the file, reducing the chance of mistakes during deployment. | |
| 21 | + |
| 22 | + |
| 23 | +## Directory structure |
| 24 | + |
| 25 | +Docker automatically manages volumes, so you don't create folders manually. |
| 26 | + |
| 27 | +```text |
| 28 | +percona-compose/ |
| 29 | +├── .env |
| 30 | +└── docker-compose.yml |
| 31 | +``` |
| 32 | + |
| 33 | +### Create .env |
| 34 | + |
| 35 | +Using an `.env` file for MySQL Docker containers has several advantages: |
| 36 | + |
| 37 | +| Benefit | Description | |
| 38 | +|---------------------------------|-----------------------------------------------------------------------------------------------------------| |
| 39 | +| Keeps sensitive data secure | Stores environment variables (e.g., passwords) in an `.env` file, keeping them out of `docker-compose.yml` to avoid exposure. | |
| 40 | +| Simplifies configuration | Centralizes environment variables, making it easier to manage and update configurations in one place. | |
| 41 | +| Improves portability | Enables reuse of variables across different environments (development, staging, production) without changes to configuration files. | |
| 42 | +| Enhances readability | Keeps `docker-compose.yml` or Dockerfiles cleaner by externalizing environment variables. | |
| 43 | +| Facilitates collaboration | Allows the use of shared templates (e.g., `.env.example`) for required variables, while hiding actual secrets. | |
| 44 | +| Supports dynamic updates | Makes it easy to update environment variables without modifying Docker configurations or scripts. | |
| 45 | + |
| 46 | + |
| 47 | +By leveraging an `.env` file, you streamline both security and ease of use for MySQL container deployments. This approach ensures better organization and adaptability for various environments. |
| 48 | + |
| 49 | +```text |
| 50 | +MYSQL_ROOT_PASSWORD=supersecurepassword |
| 51 | +MYSQL_DATABASE=mydb |
| 52 | +MYSQL_USER=myuser |
| 53 | +MYSQL_PASSWORD=myuserpassword |
| 54 | +``` |
| 55 | + |
| 56 | + |
| 57 | +### Create docker-compose.yml |
| 58 | + |
| 59 | +By using a `docker-compose.yml` file, you streamline container orchestration, ensure consistency, and simplify collaboration across teams. |
| 60 | + |
| 61 | +```text |
| 62 | +
|
| 63 | +
|
| 64 | +services: |
| 65 | + mysql: |
| 66 | + image: percona/percona-server:8.0 |
| 67 | + container_name: percona-server |
| 68 | + ports: |
| 69 | + - "3306:3306" |
| 70 | + environment: |
| 71 | + MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} |
| 72 | + MYSQL_DATABASE: ${MYSQL_DATABASE} |
| 73 | + MYSQL_USER: ${MYSQL_USER} |
| 74 | + MYSQL_PASSWORD: ${MYSQL_PASSWORD} |
| 75 | + volumes: |
| 76 | + - percona-data:/var/lib/mysql # Database data |
| 77 | + - percona-logs:/var/log/mysql # MySQL logs |
| 78 | + - percona-backups:/backups # XtraBackup output (optional, for future use) |
| 79 | + restart: unless-stopped |
| 80 | +
|
| 81 | +volumes: |
| 82 | + percona-data: |
| 83 | + percona-logs: |
| 84 | + percona-backups: |
| 85 | +``` |
| 86 | + |
| 87 | + |
| 88 | +## Start the Container |
| 89 | + |
| 90 | +The command has the following options: |
| 91 | + |
| 92 | +* `up`: Starts the containers specified in the docker-compose.yml file. |
| 93 | + |
| 94 | +* `-d`: Runs the containers in detached mode, meaning they operate in the background. |
| 95 | + |
| 96 | +```{.bash data-prompt="$"} |
| 97 | +$ docker-compose up -d |
| 98 | +``` |
| 99 | + |
| 100 | +??? example "Expected output" |
| 101 | + |
| 102 | + ```{.text .no-copy} |
| 103 | + [+] Running 11/11 |
| 104 | + ✔ mysql Pulled 34.1s |
| 105 | + ✔ 56631da24b0d Pull complete 28.9s |
| 106 | + ✔ 5aee836c3728 Pull complete 28.9s |
| 107 | + ✔ a5fd539367b0 Pull complete 28.9s |
| 108 | + ✔ fc4a4cc146b3 Pull complete 28.9s |
| 109 | + ✔ 7a3939b8d92c Pull complete 32.1s |
| 110 | + ✔ 6fdbd2a9e883 Pull complete 32.1s |
| 111 | + ✔ 70ac4d191dd1 Pull complete 32.1s |
| 112 | + ✔ 5872370b843d Pull complete 32.1s |
| 113 | + ✔ 8310fa1d2765 Pull complete 32.1s |
| 114 | + ✔ 4437564bc659 Pull complete 32.2s |
| 115 | + [+] Running 5/5 |
| 116 | + ✔ Network percona-compose_default Created 0.0s |
| 117 | + ✔ Volume "percona-compose_percona-data" Created 0.0s |
| 118 | + ✔ Volume "percona-compose_percona-logs" Created 0.0s |
| 119 | + ✔ Volume "percona-compose_percona-backups" Created 0.0s |
| 120 | + ✔ Container percona-server Star... 0.3s |
| 121 | + ``` |
| 122 | + |
| 123 | +Docker automatically creates the volumes: |
| 124 | + |
| 125 | +• percona-data: stores MySQL tables |
| 126 | + |
| 127 | +• percona-logs: stores logs generated by the database |
| 128 | + |
| 129 | +• percona-backups: a mount point you can use for Percona XtraBackup |
| 130 | + |
| 131 | +## Connect to the server and run a simple query |
| 132 | + |
| 133 | +After the container is up, you can connect to the running server instance using the mysql client included in the container. |
| 134 | + |
| 135 | +Run the following command to open a MySQL shell in the container: |
| 136 | + |
| 137 | +```{.bash data-prompt="$"} |
| 138 | +$ docker exec -it percona-server mysql -u root -p |
| 139 | +``` |
| 140 | + |
| 141 | +You must enter the root password. |
| 142 | + |
| 143 | +??? example "Expected output" |
| 144 | + |
| 145 | + ```{.text .no-copy} |
| 146 | + Enter password: |
| 147 | + Welcome to the MySQL monitor. Commands end with ; or \g. |
| 148 | + Your MySQL connection id is 9 |
| 149 | + Server version: 8.0.41-32 Percona Server (GPL), Release 32, Revision b8e378ec |
| 150 | + |
| 151 | + Copyright (c) 2009-2025 Percona LLC and/or its affiliates |
| 152 | + Copyright (c) 2000, 2025, Oracle and/or its affiliates. |
| 153 | + |
| 154 | + Oracle is a registered trademark of Oracle Corporation and/or its |
| 155 | + affiliates. Other names may be trademarks of their respective |
| 156 | + owners. |
| 157 | + |
| 158 | + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. |
| 159 | + |
| 160 | + mysql> |
| 161 | + ``` |
| 162 | + |
| 163 | +Run a simple query: |
| 164 | + |
| 165 | +```{.bash data-prompt="mysql>"} |
| 166 | +mysql> SHOW DATABASES; |
| 167 | +``` |
| 168 | + |
| 169 | +??? example "Expected output" |
| 170 | + |
| 171 | + ```{.text .no-copy} |
| 172 | + +--------------------+ |
| 173 | + | Database | |
| 174 | + +--------------------+ |
| 175 | + | information_schema | |
| 176 | + | mydb | |
| 177 | + | mysql | |
| 178 | + | performance_schema | |
| 179 | + | sys | |
| 180 | + +--------------------+ |
| 181 | + 5 rows in set (0.02 sec) |
| 182 | + ``` |
| 183 | + |
| 184 | +## Create a test database and table |
| 185 | + |
| 186 | +The following query creates a `test_db` database and `test_table`: |
| 187 | + |
| 188 | +```{.bash data-prompt="mysql>"} |
| 189 | +mysql> CREATE DATABASE test_db; |
| 190 | +USE test_db; |
| 191 | +CREATE TABLE test_table (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100)); |
| 192 | +INSERT INTO test_table (name) VALUES ('Sample Data'); |
| 193 | +SELECT * FROM test_table; |
| 194 | +``` |
| 195 | + |
| 196 | +??? example "Expected output" |
| 197 | + |
| 198 | + ```{.text .no-copy} |
| 199 | + Query OK, 1 row affected (0.02 sec) |
| 200 | + |
| 201 | + Database changed |
| 202 | + Query OK, 0 rows affected (0.01 sec) |
| 203 | + |
| 204 | + Query OK, 1 row affected (0.01 sec) |
| 205 | + |
| 206 | + +----+-------------+ |
| 207 | + | id | name | |
| 208 | + +----+-------------+ |
| 209 | + | 1 | Sample Data | |
| 210 | + +----+-------------+ |
| 211 | + 1 row in set (0.00 sec) |
| 212 | + |
| 213 | + mysql> |
| 214 | + ``` |
| 215 | + |
| 216 | +Remember to `mysql> exit` when you are finished working with the server. |
| 217 | + |
| 218 | +## Use the backup volume with XtraBackup |
| 219 | + |
| 220 | +When you run XtraBackup inside a container, either in the same network or another container, you can target `/backups` to store backup files. |
| 221 | + |
| 222 | +An example of using Docker to backup the server: |
| 223 | + |
| 224 | +```{.bash data-prompt="$"} |
| 225 | +$ docker run --rm \ |
| 226 | + --volumes-from percona-server \ |
| 227 | + -v percona_backups:/backup \ |
| 228 | + percona/percona-xtrabackup:8.0 \ |
| 229 | + xtrabackup --backup \ |
| 230 | + --target-dir=/backup \ |
| 231 | + --host=percona-server \ |
| 232 | + --user=myuser \ |
| 233 | + --password=mypassword |
| 234 | +``` |
| 235 | + |
| 236 | + |
| 237 | +## Best practices |
| 238 | + |
| 239 | +* Use named volumes to simplify backup and migration. |
| 240 | + |
| 241 | +* Mount logs separately for easier troubleshooting and rotation. |
| 242 | + |
| 243 | +* Use docker volume inspect to view volume metadata and mount points. |
| 244 | + |
| 245 | + |
| 246 | +## Shut down and clean up |
| 247 | + |
| 248 | +You can stop the stack but retain volumes: |
| 249 | + |
| 250 | +```{.bash data-prompt="$"} |
| 251 | +$ docker-compose down |
| 252 | +``` |
| 253 | + |
| 254 | +You can also remove all resources, including volumes: |
| 255 | + |
| 256 | +```{.bash data-prompt="$"} |
| 257 | +$ docker-compose down -v |
| 258 | +``` |
| 259 | + |
0 commit comments