Docker MySQL 8 how to set --secure-file-priv - mysql

I would like to solve this problem:
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
with the official MySQL 8 image on docker.
the command:
SHOW VARIABLES LIKE "secure_file_priv";
gives:
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| secure_file_priv | NULL |
+------------------+-------+
1 row in set (0.01 sec)
Is it possible to overwrite the default value NULL for the --secure-file-priv by using the official MySQL 8 Docker image?
the default value in this image is set to NULL
config/my.cnf
Perfectly I would like to set just an environmental variable or parameter when using docker run or create instead of bringing my own config file.
but if this is not possible then how to use custom config file?
is it possible that custom file just overwrites this one parameter and leaves others as they are in the official image config?

According to this documentation, you can configure secure-file-priv through command-line by passing --secure-file-priv=dir_name
secure-file-priv possible values are: empty string, dirname or NULL as explained in the privous url.
From mysql-docker page:
Configuration without a cnf file: Many configuration options can be passed as flags to mysqld. This will give you the flexibility to customize the container without needing a cnf file. For example, if you want to change the default encoding and collation for all tables to use UTF-8 (utf8mb4) just run the following:
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
So in our case would be like this:
dir_name should be a directory inside your container otherwise you will get the following error: mysqld: Error on realpath() on 'dir_name' (Error 2 - No such file or directory)
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --secure-file-priv=dir_name
And now our change is committed in MySQL
mysql> SHOW VARIABLES LIKE "secure_file_priv";
+------------------+----------+
| Variable_name | Value |
+------------------+----------+
| secure_file_priv | dir_name |
+------------------+----------+
Alternatively, you can use a custom configuration file as explained in here:
Using a custom MySQL configuration file: The default configuration for MySQL can be found in /etc/mysql/my.cnf, which may !includedir additional directories such as /etc/mysql/conf.d or /etc/mysql/mysql.conf.d. Please inspect the relevant files and directories within the mysql image itself for more details.
If /my/custom/config-file.cnf is the path and name of your custom configuration file, you can start your mysql container like this (note that only the directory path of the custom config file is used in this command):
$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
This will start a new container some-mysql where the MySQL instance uses the combined startup settings from /etc/mysql/my.cnf and /etc/mysql/conf.d/config-file.cnf, with settings from the latter taking precedence.

Related

bash command for runniung multiple commands in docker container

I'm trying to set up a database with a table inside a docker container. For correct working of DB, I need to run the following command:
--default-authentication-plugin=mysql_native_password
ps: I don't understand what this command exactly is for, but it prevents some strange logs by setting the DB up.
For set up, I use docker-compose as follow:
db:
image: mysql
command: >
bash -c "--init-file /pictureapi_mydb_response.sql
&& --default-authentication-plugin=mysql_native_password"
volumes:
- ./pictureapi_mydb_response.sql:/pictureapi_mydb_response.sql
restart: always
ports:
- 3307:3306
environment:
MYSQL_ROOT_PASSWORD: ${DB_MYSQL_PASS}
source
I'm getting the following errors:
bash: --: invalid option
db_1 | Usage: bash [GNU long option] [option] ...
db_1 | bash [GNU long option] [option] script-file ...
db_1 | GNU long options:
db_1 | --debug
db_1 | --debugger\
How should I actually run two or more commands if "bash" instruction doesn't work?
The Docker Hub mysql image is configured so that, if the command: starts with -, the entire command is assumed to be mysqld startup options. It's not actually "a command", and you can't use bash to run it. If you need multiple startup options, just combine them together into a single command::
command: --init-file /pictureapi_mydb_response.sql --default-authentication-plugin=mysql_native_password
When you launch a Docker container, its "entrypoint" and "command" parts are combined into a single command, so the command is passed as additional arguments to the entrypoint if both are present. The most common pattern is that the command is a complete executable command on its own, but there's an alternate pattern where the entrypoint is (or provides) the main command to run and the command just provides extra options.
The Docker Hub mysql container has a rather involved entrypoint script, but it eventually concludes with this logic:
# if command starts with an option, prepend mysqld
if [ "${1:0:1}" = '-' ]; then
set -- mysqld "$#"
fi
That is, if you run a container with
command: --an-option-starting-with-minus
the actual command the container runs is mysqld --an-option-starting-with-minus. So if you have multiple mysqld options you need to set, you can just pass them as the "command" and they'll get handled appropriately.

Docker Using a custom MySQL configuration file Always fail

Follow the documentation here,Always fail
Using a custom MySQL configuration file
The default configuration for MySQL can be found in /etc/mysql/my.cnf, which may !includedir additional directories such as /etc/mysql/conf.d or /etc/mysql/mysql.conf.d. Please inspect the relevant files and directories within the mysql image itself for more details.
If /my/custom/config-file.cnf is the path and name of your custom configuration file, you can start your mysql container like this (note that only the directory path of the custom config file is used in this command):
$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
This will start a new container some-mysql where the MySQL instance uses the combined startup settings from /etc/mysql/my.cnf and /etc/mysql/conf.d/config-file.cnf, with settings from the latter taking precedence.
Configuration without a cnf file
Many configuration options can be passed as flags to mysqld. This will give you the flexibility to customize the container without needing a cnf file. For example, if you want to change the default encoding and collation for all tables to use UTF-8 (utf8mb4) just run the following:
$ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
If you would like to see a complete list of available options, just run:
My version Docker version 18.09.7, build 2d0083d
The commands I run
docker run --name mysql2 -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=root -d mysql:8.0.16
My custom configuration file
[mysqld]
sql_mode="STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION"
I found the reason. Because I set the mysql.cnf permissions to 777.

How do I run mysqld as root in the official MySql docker image?

First off, I know not to run as root normally. I have an abnormal situation: I need to use mysqldump with the --tab argument, which requires permission to write to disk, and I want to use those files outside the Docker container. I could explain why running mysqld as root makes this easier, but isn't this question long enough? Running as root is safe in this case because the container will be used only for running tests and for updating DB backup scripts based on SQL migration scripts, and it will be started to do 1 job and then taken back down again.
When I google for how to run mysqld as root, I find the answer indirectly given in instructions on how to NOT run as root. Among other things in order to run mysqld as user_name:
Start the server as user user_name. Another alternative is to start mysqld as the Unix root user and use the --user=user_name option.
To start the server as the given user automatically at system startup time, specify the user name by adding a user option to the [mysqld] group of the /etc/my.cnf option file or the my.cnf option file in the server's data directory.
Do we do one of those? Both of those? I'll assume both just in case. But do they really mean /etc/my.cnf, or does that depend on the installation (e.g. what Linux distribution)? E.g. Docker image mysql:5.6 has /etc/mysql/my.cnf. The directions for the MySql Docker image advise mounting a volume at /etc/mysql/conf.d which is referenced in the aforementioned my.cnf. (Doing so overwrites 2 configuration files that are there by default, so I used a COPY command in my Dockerfile instead to merely add a config file.) The file does make it into the container:
root#4f612d10a690:/etc/mysql/conf.d# cat my.cnf
[mysqld]
user=root
One further requirement from the MySql manual is to add the --user=root argument to mysqld. The official MySql image calls mysqld via its CMD, so I override that in my Dockerfile. My CMD command does indeed run (it is run in 2 places in official MySql image's entrypoint script):
# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
mysql 1 0.1 2.8 1452788 472756 ? Ssl 14:24 0:01 mysqld --user=root
Note that mysqld has the --user=root command I provided, but is running as the mysql user, not as root.
Here's my full Dockerfile:
FROM mysql:5.6
VOLUME ["/var/lib/mysql-files"]
COPY ["my.cnf", "/etc/mysql/conf.d"]
CMD ["mysqld", "--user=root"]
My only guess as to why it's not running as root is that they mysql image's entrypoint script changes to the mysql user before running:
# allow the container to be started with `--user`
if [ ...blah... -a "$(id -u)" = '0' ]; then
...blah...
exec gosu mysql "$BASH_SOURCE" "$#"
fi
The above snippet basically says, if the user is root, then run the supplied arguments (the CMD + args in this case) as the mysql user.
Is running mysqld as root simply not supported by the official MySql Docker image?
Note: this is how to run mysqld process as SO's root user, and not how to get the root MySQL user.
I don't know whether exists a better approach but this works.
Viewing the official entrypoint.sh, it seems that it has no support of chaging the default mysql user
I realized how to run mysql as root but you need to have already initialized the data directory.
Step 1) Start a normal mysql in order to initialize a volume (the mysql entrypoint.sh will do that job):
docker run \
--rm \
-v $(pwd)/mysql/:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD="abc" \
mysql:5.6
Step 2) Stop and remove that container:
docker stop <container-id>
Step 3) Start again a new mysql process based on the data dir that has been created, but this time avoid to run the official mysql entrypoint:
docker run \
-v $(pwd)/mysql/:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD="abc" \
--entrypoint mysqld \
mysql:5.6 \
--user root
Step 4) Check it:
▶ docker exec -it 4add4d065c3e bash
root#4add4d065c3e:/# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 2.8 23.0 1314864 471104 ? Ssl 15:12 0:00 mysqld --user root
root 28 3.0 0.1 20248 3040 ? Ss 15:12 0:00 bash
root 34 0.0 0.1 17500 2068 ? R+ 15:12 0:00 ps aux

Docker container with MySQL not writing in the log file

I am working on an existing Dockerfile that I have been asked to modify as less as possible. The docker image is based on a CentOS Linux image and is supposed to contain a MySQL service.
I want to enable the verbose logging for all the queries (i.e. general_log and general_log_file variables on the /etc/my.cnf file).
The MySQL service needs to be run in the mysqld_safe mode and I've checked that the configuration lines I am adding (see below the printf) are after the [mysqld_safe] line in the /etc/my.cnf file, so I am assuming this setting should be fine.
What I've done so far is adding to the Dockerfile the following statements:
RUN groupadd -r mysql && useradd -r -g mysql mysql
# [...] Lots of Mysql stuff regarding importing DBs etc.
# Adding some more configuration details to the database service
RUN printf '\n%s\n%s\n%s\n\n' '# Set General Log to log all the queries' 'general_log=1' 'general_log_file=/var/log/mysql_general.log' >> /etc/my.cnf
# Getting the new log file prepared to get written by the MySQL service
RUN touch /var/log/mysql_general.log
RUN chown mysql.mysql /var/log/mysql_general.log
# MySQL Port
EXPOSE 3306
ENTRYPOINT ["mysqld_safe"]
After building the docker image and running the docker container I see this in the /var/log folder:
-rw-r-----. 1 mysql mysql 5108 Nov 20 17:07 mysqld.log
-rw-r--r--. 1 mysql mysql 3880 Nov 20 17:44 mysql_general.log
If I grep the mysqld.log for keywords like ERROR or general I can not find anything interesting. The mysql_general.log file is empty.
I see this also this:
mysql> show variables like '%general_log%';
+------------------+----------------------------+
| Variable_name | Value |
+------------------+----------------------------+
| general_log | OFF |
| general_log_file | /var/run/mysqld/mysqld.log |
+------------------+----------------------------+
2 rows in set (0.00 sec)
mysql>
I am not able to get the SQL queries written in the log file, why?

How to determine which my.cnf mysql is using

Is there a way I can figure out which my.cnf mysql is currently using? The reason is because it's using the correct socket file to connect, but I can't figure out exactly which (if any) my.cnf it's using or trying to use so I can manually set the correct path on my local machine.
$ strace -f -e trace=open mysql 2>&1 | grep $SEARCH_STRING
where usually SEARCH_STRING='cnf' or SEARCH_STRING='ini'
The default extentions for the mysql configuration file are '.cnf' and '.ini' (see http://dev.mysql.com/doc/refman/5.1/en/option-files.html)
A bit hackish:
$ strace mysql 2>&1 | grep 'open' | grep '.cnf'
open("/etc/mysql/my.cnf", O_RDONLY|O_LARGEFILE) = 3
open("/home/reto/.my.cnf", O_RDONLY|O_LARGEFILE) = 3