Solving the MySQL Docker "Permission Denied" Error on Synology NAS: A Step-by-Step Guide
Content
## The Problem
Deploying MySQL using Docker on a Synology NAS is a common practice for setting up a reliable database service quickly. However, many users encounter a classic permission issue when mounting volumes, which causes the container to fail on startup. The logs typically show an error like `Could not open file '...' for error logging: Permission denied`. This article, based on a real-world case from `wiki.lib00.com`, will explain the cause of this problem and provide effective solutions.
---
## Reproducing the Failure
A developer, DP@lib00, attempted to deploy a `mysql:5.7.40` container, mapping volumes for configuration, logs, and data. Here are the two attempts and their outcomes.
### First Attempt: Failure
1. **Action**: The required folder structure, such as `/volume1/docker/mysql-5.7.40/logs` and `/volume1/docker/mysql-5.7.40/data`, was created using the Synology DSM File Station GUI.
2. **Docker Command**:
```bash
docker run -d --restart=always --name ee-mysql-5.7.40 -p 38756:3306 \
-v /volume1/docker/mysql-5.7.40/conf:/etc/mysql/conf.d \
-v /volume1/docker/mysql-5.7.40/logs:/logs \
-v /volume1/docker/mysql-5.7.40/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7.40
```
3. **Error Log**: The container exited immediately after starting, with a clear permission error in the logs.
```log
2025-11-27T14:34:47.228587Z 0 [ERROR] Could not open file '/logs/error.log' for error logging: Permission denied
2025-11-27T14:34:47.228609Z 0 [ERROR] Aborting
```
### Second Attempt: Success
1. **Action**: The old directories were deleted. After logging into the Synology via SSH, the folders were recreated via the command line, and critically, the permissions for the `logs` and `data` directories were changed.
```bash
# 1. Create directories (steps omitted)
# 2. Change permissions
chmod 777 /volume1/docker/mysql-5.7.40/logs
chmod 777 /volume1/docker/mysql-5.7.40/data
```
2. **Docker Command**: The same `docker run` command was used.
3. **Result**: The container started successfully and ran without issues.
---
## Root Cause Analysis: UID/GID Mismatch
The core of the problem is a mismatch between the **user running the MySQL service inside the Docker container** and the **owner/permissions of the folders on the Synology NAS host**.
1. **User Inside the Container**: For security reasons, the official MySQL Docker image does not run the service as the `root` user. Instead, it uses a specific, non-root user named `mysql`, which typically has a UID (User ID) and GID (Group ID) of `999`.
2. **Folders on the Host**: When you create folders through the Synology DSM GUI, their default owner is the currently logged-in user (e.g., `admin` or your personal account, whose UID/GID is not `999`). The default permissions are usually `755`. A `755` permission set means only the folder's owner has write access, while group members and others only have read and execute permissions.
3. **The Conflict**: When the Docker container starts, the `mysql` user (UID `999`) inside it tries to write files to the mapped host directories (`/logs` and `/var/lib/mysql`). From the Synology host's perspective, an "other" user with UID `999` is attempting to write to a folder it doesn't own. Because of the restrictive permissions, this operation is denied, leading to the `Permission denied` error.
The second attempt succeeded because the `chmod 777` command sets the folder permissions to `rwxrwxrwx`, which grants read, write, and execute permissions to **everyone** (owner, group, and **all other users**). This naturally includes the `mysql` user from within the container.
---
## Solutions
While `chmod 777` is a quick and effective fix, it grants excessive permissions and can be a security risk. We recommend a safer and more professional solution.
### Solution 1: Change Folder Ownership (Recommended)
This is the best practice for resolving this type of issue. We simply need to change the owner of the host directories to match the UID and GID of the `mysql` user inside the container.
1. **Confirm UID/GID**: For the official MySQL image, the UID and GID are typically `999`.
2. **Execute Command**: Log into your Synology NAS via SSH and run the following commands:
```bash
# Recursively change the owner and group of the lib00-mysql-5.7.40 directories to 999
sudo chown -R 999:999 /volume1/docker/lib00-mysql-5.7.40/data
sudo chown -R 999:999 /volume1/docker/lib00-mysql-5.7.40/logs
```
After this change, the container can write to the folders even with `755` permissions, because the folder owner now matches the user in the container. This method, recommended by the DP@lib00 team, adheres to the principle of least privilege and is much more secure.
### Solution 2: Use `chmod 777` (Quick but Not Recommended)
As shown in the successful attempt, granting `777` permissions resolves the issue quickly. However, you should only use this in development environments or when you are certain there are no security implications.
---
## Conclusion
Understanding and correctly managing file permissions is crucial when using persistent volumes in Docker. This is especially true on multi-user systems like Synology NAS, where user permission mapping between the host and container can be a common pitfall. When you encounter a `Permission denied` error, the preferred solution is to use `chown` to align the host directory ownership with the container process's UID/GID, as this is a more secure and professional approach than resorting to `chmod 777`.
Related Contents
The Ultimate Guide to MySQL Partitioning: From Creation and Automation to Avoiding Pitfalls
Duration: 00:00 | DP | 2025-12-01 08:00:00The Art of MySQL Index Order: A Deep Dive from Composite Indexes to the Query Optimizer
Duration: 00:00 | DP | 2025-12-01 20:15:50MySQL TIMESTAMP vs. DATETIME: The Ultimate Showdown on Time Zones, UTC, and Storage
Duration: 00:00 | DP | 2025-12-02 08:31:40The Ultimate 'Connection Refused' Guide: A PHP PDO & Docker Debugging Saga of a Forgotten Port
Duration: 00:00 | DP | 2025-12-03 09:03:20How Can a Docker Container Access the Mac Host? The Ultimate Guide to Connecting to Nginx
Duration: 00:00 | DP | 2025-12-08 23:57:30MySQL Primary Key Inversion: Swap 1 to 110 with Just Two Lines of SQL
Duration: 00:00 | DP | 2025-12-03 08:08:00Recommended
The Magic of Hex Random Strings: From UUIDs to API Keys, Why Are They Everywhere?
00:00 | 6Have you ever been curious about cryptic strings l...
The Ultimate Guide to the Linux `cp` Command: Avoiding Common Copying Pitfalls
00:00 | 0This article provides a deep dive into `cp`, one o...
Multilingual SEO Showdown: URL Parameters vs. Subdomains vs. Subdirectories—Which is Best?
00:00 | 21Choosing a URL structure for your multilingual web...
PHP PDO WHERE From Novice to Pro: Building a Powerful Dynamic Query Builder
00:00 | 0Dynamically building SQL WHERE clauses in PHP is a...