From ed5de613fbef9e7f1bee42323c940748167e17b7 Mon Sep 17 00:00:00 2001 From: Reza Gharabaghi <40915667+mrgharabaghi@users.noreply.github.com> Date: Thu, 10 Oct 2024 10:17:12 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20New=20tutorial=20series=20-=20"Dock?= =?UTF-8?q?erizing=20MariaDB=20with=20Alpine=20Linux"=20(#945)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Dockerizing MariaDB with Alpine Linux * Fix mariadb-server.cnf config * Spelling and formatting updates * Add the license block --------- Co-authored-by: svenja.michal <84835304+svenja11@users.noreply.github.com> --- .../01.en.md | 429 ++++++++++++++++++ .../02.en.md | 376 +++++++++++++++ .../03.en.md | 197 ++++++++ 3 files changed, 1002 insertions(+) create mode 100644 tutorials/dockerizing-mariadb-with-alpine-linux/01.en.md create mode 100644 tutorials/dockerizing-mariadb-with-alpine-linux/02.en.md create mode 100644 tutorials/dockerizing-mariadb-with-alpine-linux/03.en.md diff --git a/tutorials/dockerizing-mariadb-with-alpine-linux/01.en.md b/tutorials/dockerizing-mariadb-with-alpine-linux/01.en.md new file mode 100644 index 000000000..4fde2d72d --- /dev/null +++ b/tutorials/dockerizing-mariadb-with-alpine-linux/01.en.md @@ -0,0 +1,429 @@ +--- +SPDX-License-Identifier: MIT +path: "/tutorials/dockerizing-mariadb-with-alpine-linux" +slug: "dockerizing-mariadb-with-alpine-linux" +date: "2024-10-09" +title: "Dockerizing MariaDB with Alpine Linux" +short_description: "The official MariaDB Docker image uses Red Hat Linux, which is large in size. In this tutorial you are able to setup your database on Alpine Linux." +tags: ["Database", "MariaDB", "Docker", "Alpine", "Lang:SQL"] +author: "Reza Gharabaghi" +author_link: "https://github.com/mrgharabaghi" +author_img: "https://avatars.githubusercontent.com/u/40915667" +author_description: "" +language: "en" +available_languages: ["en"] +header_img: "header-1" +cta: "dedicated" +--- + +## Introduction + +The official MariaDB Docker image uses [Red Hat Linux][redhat], which is large in size. In this tutorial you will see how to setup your database on [Alpine Linux][alpine]. + +I use [Alpine Linux][alpine] as the base Docker image for most of my applications. Why? because Alpine is designed with security in mind. The `C` library used is [musl] and the base tools are all in [BusyBox][busybox]. Those are normally found in embedded systems and are smaller than the tools found in GNU/Linux systems. + +Another great part of Alpine is their package manager called [Alpine Package Keeper][apk]. For example, you can find and install most of the popular packages with the `apk` command. In this series I want to show you how to install `MariaDB` and import or export your database data with ease. + +> This tutorial is split into multiple parts. + +## Series index + +1. Dockerizing MariaDB with Alpine Linux (You are here) +2. [Import and Export data in Dockerized MariaDB][second_tutorial] +3. [Connect to Dockerized MariaDB with Node.js via Unix socket][third_tutorial] + +**Prerequisites** + +* Server with Rocky Linux 9 + +## Step 1 - Install Docker + +First of all you have to install Docker on your `VPS`. I purchased a [Rocky Linux 9][rocky] instance on [Hetzner Cloud][hetzner]. +If you have another Linux distribution, there are very straightforward steps on the official [Docker website][docker_install], which you can use. + +```sh +# Update your instance +dnf -y update + +# Install useful packages +dnf -y install \ + epel-release \ + bash-completion + +# Reboot your Linux instance +reboot +``` +```sh +# Add Docker repo +dnf config-manager \ + --add-repo \ + https://download.docker.com/linux/centos/docker-ce.repo + +# Install Docker +dnf -y install \ + docker-ce \ + docker-ce-cli \ + containerd.io \ + docker-compose-plugin + +# Enable and start Docker service +systemctl --now enable docker +``` + +## Step 2 - Project structure + +This is our project directory structure. + +> Directories are marked with `/` at the end of them. + +```md +maria/ +│ +├─── Dockerfile +├─── main.sh +│ +├─── data/ +├─── logs/ +├─── socket/ +├─── dump/ +│ │ +│ ├─── import/ +│ └─── export/ +│ +└─── config/ + │ + ├─── my.cnf + └─── my.cnf.d/ + │ + └─── mariadb-server.cnf +``` + +```sh +# Create project directory +mkdir /maria + +# Change the current working directory to maria/ +cd /maria + +# Add the directories +mkdir -p data logs socket dump/import dump/export config/my.cnf.d + +# Add the files +touch Dockerfile main.sh config/my.cnf config/my.cnf.d/mariadb-server.cnf +``` + +## Step 3 - Build your image + +After installing Docker, we have to create our Docker image. +As you may know, Docker images are immutable, which means they can't be modified once created. +For this reason, we should use Docker volumes. With volumes you are able to share files between your main Linux instance (Rocky Linux 9) and a Docker container. + +This is our `Dockerfile` config file and instructions about how Docker should build the image. + +---------------------------------- + +**Dockerfile** + +```md +# Use Alpine as the base image +FROM alpine:3.20 + +# Copy the main shell script to image +COPY ["main.sh", "/usr/local/bin/"] + +RUN \ + # Add MariaDB packages + apk add --no-cache \ + mariadb \ + mariadb-client; \ + # Give execute permission to main.sh + chmod +x /usr/local/bin/main.sh + +# Specify the start point of our image +ENTRYPOINT ["main.sh"] +``` + +## Step 4 - Shell script + +So far you have done many steps, perfect. + +It's time to write the most important part of your project. The `main.sh` is the controller and the start point of the project. + +At this stage I show you how the bash script handles our `MariaDB` program. +We need to start and stop `MariaDB` with that bash script. + +---------------------------------- + +**main.sh** + +```sh +#!/bin/ash + +set -e + +signal_terminate_trap() { + # + # Shutdown MariaDB with mariadb-admin + # https://mariadb.com/kb/en/mariadb-admin/ + mariadb-admin shutdown & + # + # Wait for mariadb-admin until sucessfully done (exit) + wait $! + echo "MariaDB shut down successfully" +} + +trap "signal_terminate_trap" SIGTERM + +# Run +if [ "$REQUEST" == "run" ]; then + echo "Starting MariaDB ..." + # + # Run MariaDB with exec bash command + exec mariadbd & + # + # Wait for MariaDB until stopped by Docker + wait $! + exit 1 +fi + +# Initialize +if [ "$REQUEST" == "initialize" ]; then + initialize_status="MariaDB is already initialized" + + if [ ! -f "$DIR_DATA/ibdata1" ]; then + initialize_status="MariaDB initialization done" + + # Initialize MariaDB with mariadb-install-db + # https://mariadb.com/kb/en/mariadb-install-db/ + mariadb-install-db \ + --user=$USER \ + --datadir=$DIR_DATA \ + --auth-root-authentication-method=socket & + # + # Wait for mariadb-install-db until sucessfully done (exit) + wait $! + fi + + echo $initialize_status +fi +``` + +- `set -e` command + - Tell bash to exit the script if any command fails. +- `signal_terminate_trap` function + - Every bash script will exit eventually, whether our script is completely done or fails. We need to catch that exit and figure out why our script wants to exit. +- `trap` command + - This command helps us to catch the terminate signal (`SIGTERM`) of our process. In the first param of `trap` we specify the `signal_terminate_trap` function and in the second param we specify the termination signal (`SIGTERM`). +- `if` statement + - When we start our Docker container, we pass an environment variable to the container and we call it `REQUEST`. I will tell you more about this later. +- `--auth-root-authentication-method` + - In this tutorial series we will connect to MariaDB via Unix socket. The common way for connecting to a database is TCP connection (`127.0.0.1:3306`). Opening an extra port equals less security. Hackers try to connect to a database via open ports like `3306`. Unix sockets are only available for processes inside our Linux machine. + +**SIGTERM important note:** +By default, Docker sends a `SIGTERM` signal to the main process of the container (`main.sh`) when you try to stop your container with the `docker stop container_name` command. + +- Documents link: + - [SIGTERM][sig_term] signal + - [Docker container stop][docker_stop] + +
+ +----------- + +Now it's time to build the image. + +```sh +# Build +docker build --rm -t maria:1.0.0 --file Dockerfile ./ + +# Check Docker images on your Linux machine +docker image list --all +``` + +- I use `--rm` flag to clean up the temporary container and remove the filesystem after the build is complete. +- Specify the name of your image and its version with `-t`. +- Specify `Dockerfile` with `--file` flag. + +## Step 5 - MariaDB config files + +Check the `MariaDB` official documents page. + +- [Server System Variables][maria_sys_vars] +- [Configuring MariaDB with Option Files][maria_option_files] + +---------------------------------- + +**config/my.cnf** + +```md +[mysqld] +symbolic-links=0 +!includedir /etc/my.cnf.d +``` + +---------------------------------- + +**config/my.cnf.d/mariadb-server.cnf** + +```md +[client] +socket=/run/maria/maria.sock + +[mysql] +default-character-set=utf8mb4 + +[mysqld] +pid-file=/run/maria/maria.pid +skip-networking + +innodb_buffer_pool_size=64M +performance_schema=OFF + +[mysqld_safe] +log_error=/var/log/maria/error_safe.log + +[mariadbd] +user=mysql + +datadir=/var/lib/maria/ +socket=/run/maria/maria.sock + +character_set_server=utf8mb4 + +log_output=FILE + +general_log +general_log_file=/var/log/maria/general.log + +slow_query_log +slow_query_log_file=/var/log/maria/slow.log +long_query_time=3 + +log_error=/var/log/maria/error.log +log_warnings=2 +``` + +## Step 6 - Initialize MariaDB + +In this step we want to initialize our MariaDB for the first time. Remember, you should do this step only one time. +After that, `MariaDB` will generate required files in the `/maria/data/` directory inside the `Rocky Linux 9` instance. +These config files are required every time you want to run `MariaDB`. + +To prevent permission errors, give the ownership of the `data` and `socket` directories to the `mysql` user. + +```sh +# 100:101 -> equals to -> mysql:mysql in MariaDB container +chown -R 100:101 /maria/data/ /maria/socket/ /maria/dump/ +``` + +It's time to initialize MariaDB with the `docker run` command. + +```sh +# Initialize +docker run \ + --rm \ + --name maria_initialize \ + --user mysql \ + --env REQUEST=initialize \ + --env USER=mysql \ + --env DIR_DATA="/var/lib/maria" \ + -v /maria/config/my.cnf:/etc/my.cnf:ro \ + -v /maria/config/my.cnf.d/:/etc/my.cnf.d/:ro \ + -v /maria/data/:/var/lib/maria/ \ + maria:1.0.0 +``` + +- With the `docker run` command you are able to start your `MariaDB` container. +- We are using the Docker volume feature with the `-v` flag. Check the official Docker docs [here][docker_volumes]. +- I define multiple environment variables which will pass to the container. One of them is `--env REQUEST=initialize`. Step back and take a look at the [Shell script][step_4] step and you will see we are using the `REQUEST` environment variable in the `if [ "$REQUEST" == "initialize" ]` line of `main.sh`. + +Done, and now your Dockerized `MariaDB` is available. + +## Step 7 - Running MariaDB + +And now, we want to run the `MariaDB` image in `detach` mode. + +```sh +docker run \ + --detach \ + --name maria_detach \ + --restart always \ + --user mysql \ + --env REQUEST=run \ + -v /maria/config/my.cnf:/etc/my.cnf:ro \ + -v /maria/config/my.cnf.d/:/etc/my.cnf.d/:ro \ + -v /maria/data/:/var/lib/maria/ \ + -v /maria/logs/:/var/log/maria/ \ + -v /maria/socket/:/run/maria/ \ + maria:1.0.0 +``` + +If you want to check the status of your container, you should use `docker ps -a` command and you will see something like this in your terminal: + +``` +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +f0a2ac1365b7 maria:1.0.0 "main.sh" 5 minutes ago Up 5 seconds maria_detach +``` + +In order to stop your container, use the `docker stop maria_detach` command. + +---------------------------------- + +Go ahead and read the [second tutorial][second_tutorial] and see how to import your database data into the `MariaDB` container. + +If you don't have any SQL data and want to connect to your `MariaDB` via Unix socket, go to the [third tutorial][third_tutorial] and see how to do it with [Node.js][nodejs]. + +## Conclusion + +In this tutorial you've learned how to Dockerize `MariaDB` on [Alpine Linux][alpine] and manage the Docker process with bash script. + +##### License: MIT + + + +[redhat]: https://hub.docker.com/u/redhat +[alpine]: https://hub.docker.com/_/alpine +[musl]: https://www.musl-libc.org/ +[busybox]: https://hub.docker.com/_/busybox +[apk]: https://docs.alpinelinux.org/user-handbook/0.1a/Working/apk.html + +[second_tutorial]: /tutorials/dockerizing-mariadb-with-alpine-linux/import-and-export-data +[third_tutorial]: /tutorials/dockerizing-mariadb-with-alpine-linux/connect-via-unix-socket + +[rocky]: https://rockylinux.org/ +[hetzner]: https://www.hetzner.com/cloud/ +[docker_install]: https://docs.docker.com/engine/install/ +[sig_term]: https://www.gnu.org/software/libc/manual/html_node/Termination-Signals.html#index-SIGTERM +[docker_stop]: https://docs.docker.com/reference/cli/docker/container/stop/ +[maria_sys_vars]: https://mariadb.com/kb/en/server-system-variables/ +[maria_option_files]: https://mariadb.com/kb/en/configuring-mariadb-with-option-files/ +[docker_volumes]: https://docs.docker.com/engine/storage/volumes/ +[step_4]: #step-4---shell-script +[nodejs]: https://nodejs.org/en diff --git a/tutorials/dockerizing-mariadb-with-alpine-linux/02.en.md b/tutorials/dockerizing-mariadb-with-alpine-linux/02.en.md new file mode 100644 index 000000000..b0284385e --- /dev/null +++ b/tutorials/dockerizing-mariadb-with-alpine-linux/02.en.md @@ -0,0 +1,376 @@ +--- +SPDX-License-Identifier: MIT +path: "/tutorials/dockerizing-mariadb-with-alpine-linux/import-and-export-data" +slug: "dockerizing-mariadb-with-alpine-linux/import-and-export-data" +date: "2024-10-09" +title: "Import and Export data in Dockerized MariaDB" +short_description: "Import and Export database data with a fresh MariaDB Docker container." +tags: ["Database", "MariaDB", "Docker", "Alpine", "Lang:SQL"] +author: "Reza Gharabaghi" +author_link: "https://github.com/mrgharabaghi" +author_img: "https://avatars.githubusercontent.com/u/40915667" +author_description: "" +language: "en" +available_languages: ["en"] +header_img: "header-2" +cta: "dedicated" +--- + +## Introduction + +In the [previous tutorial][first_tutorial] we installed Docker on a [Rocky Linux][rocky] instance and created a fresh `MariaDB` Docker image. + +Now, it's time to import and export your data. + +> This tutorial is split into multiple parts. + +## Series index + +1. [Dockerizing MariaDB with Alpine Linux][first_tutorial] +2. Import and Export data in Dockerized MariaDB (You are here) +3. [Connect to Dockerized MariaDB with Node.js via Unix socket][third_tutorial] + +**Prerequisites** + +* Server with Rocky Linux 9 + +## Step 1 - Update the bash script + +If you haven't read the first tutorial, go to [this][first_tutorial] link and start from there. + +In order to import or export data, we have to add more scripts to `main.sh`. You might say: "What if I add a new script file for this purpose?" Adding a new script file would make our project more complex and we don't want that. + +It's better to keep the Docker container process in one script and avoid multiple processes. + +I added three new sections to `main.sh`. First one is the `dump` function, and other two sections are `Import` and `Export`. + +---------------------------------- + +**main.sh** + +```sh +#!/bin/ash + +set -e + +signal_terminate_trap() { + mariadb-admin shutdown & + wait $! + echo "MariaDB shut down successfully" +} + +trap "signal_terminate_trap" SIGTERM + +# Run +if [ "$REQUEST" == "run" ]; then + echo "Starting MariaDB ..." + exec mariadbd & + wait $! + exit 1 +fi + +# Initialize +if [ "$REQUEST" == "initialize" ]; then + initialize_status="MariaDB is already initialized" + + if [ ! -f "$DIR_DATA/ibdata1" ]; then + initialize_status="MariaDB initialization done" + + mariadb-install-db \ + --user=$USER \ + --datadir=$DIR_DATA \ + --auth-root-authentication-method=socket & + wait $! + fi + + echo $initialize_status +fi + +# dump function will be used for export operation. +# +# This function has two parameters +# First param is "DATABASE_NAME" +# and the second one is "export_path". +# +# As you know, we use these params +# in the function body like this: +# $1 is the first param +# $2 is the second one +# +dump() { + # Export database data with mariadb-dump + # + # Official mariadb-dump docs + # https://mariadb.com/kb/en/mariadb-dump/ + # + mariadb-dump \ + -u mysql \ + --skip-opt \ + --add-drop-table \ + --create-options \ + --quick \ + --single-transaction \ + --set-charset \ + --skip-comments \ + --add-drop-database \ + --add-drop-trigger \ + --triggers \ + --default-character-set=utf8mb4 \ + --databases $1 \ + --result-file="$2/data_$1.sql" & + # + # Wait for mariadb-dump until sucessfully done (exit) + wait $! +} + +# Import +# +# Read the note about .sql files you want to import +# in Step 2. +if [ "$REQUEST" == "import" ]; then + exec mariadbd & + # + # Wait 5 seconds for MariaDB to start + sleep 5 & + wait $! + + # Search for .sql files in the import directory + for i in $DIR_DUMP/import/*.sql; do + # + # Use mariadb client to import .sql files + # into database. + mariadb < $i & + wait $! + done + + mariadb-admin shutdown & + wait $! + echo "Import operation successfully done" + exit 1 +fi + +# Export +# +# Read the note about export operation +# in Step 3. +if [ "$REQUEST" == "export" ]; then + exec mariadbd & + sleep 5 & + wait $! + + # Use dump function to export our data + # into the export directory. + # + # DATABASE_NAME is one of our environment variables + # that comes from Docker's --env flag. + # You will see how to set that in Step 3. + dump $DATABASE_NAME "$DIR_DUMP/export" + + # Shutdown MariaDB with mariadb-admin + # https://mariadb.com/kb/en/mariadb-admin/ + mariadb-admin shutdown & + wait $! + echo "Export operation successfully done" + exit 1 +fi +``` + +Now it's time to build the new image. + +```sh +# Build +docker build --rm -t maria:2.0.0 --file Dockerfile ./ + +# Check Docker images on your Linux machine +docker image list --all +``` + +- I use `--rm` flag to clean up the temporary container and remove the filesystem after the build is complete. +- Specify the name of your image and its version with `-t`. +- Specify `Dockerfile` with `--file` flag. + +## Step 2 - Import data + +How does the import operation work? + +First of all, you have to copy your `.sql` files into this `/maria/dump/import/` directory of the Rocky Linux 9 instance. + +I give you an example to see how it works. + +```md +maria/ +│ +└─── dump/ + │ + └─── import/ + │ + └─── data_tennis.sql +``` + +In the `data_tennis.sql`, I assume that you have a database named `tennis` and a table called `players`. + +
+
+Click here for commands to add a database + +```shellsession +[root@rocky-linux]# docker ps +[root@rocky-linux]# docker exec -it /bin/sh +/ $ mysql -u mysql -p +MariaDB [(none)]> CREATE DATABASE tennis; +MariaDB [(none)]> USE tennis; +MariaDB [(tennis])]> CREATE TABLE players ( + id INT(11) NOT NULL AUTO_INCREMENT, + name VARCHAR(40) NOT NULL, + gender VARCHAR(10) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; +MariaDB [(tennis])]> SHOW TABLES; +``` + +
+
+ +**dump/import/data_tennis.sql** + +```sql +DROP DATABASE IF EXISTS tennis; + +CREATE DATABASE + IF NOT EXISTS tennis + DEFAULT CHARACTER SET utf8mb4 + COLLATE utf8mb4_unicode_ci; + +USE tennis; +DROP TABLE IF EXISTS players; + +CREATE TABLE `players` ( + id int(11) NOT NULL AUTO_INCREMENT, + name varchar(40) NOT NULL, + gender varchar(10) NOT NULL, + PRIMARY KEY (id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +INSERT INTO players VALUES (1, 'Novak Djokovic', 'Male'); +INSERT INTO players VALUES (2, 'Maria Sharapova', 'Female'); +INSERT INTO players VALUES (3, 'Roger Federer', 'Male'); +``` + +Very good, you're ready for the import operation. + +---------------------------------- + +As you can see below, I specify our request environment variable like this `--env REQUEST=import`. Docker will pass this variable into the container's main process (`main.sh`). + +- We use the `REQUEST` variable in this line of `main.sh`: + - `if [ "$REQUEST" == "import" ]; then` + +It's time to use `docker run` command. + +```sh +# Import +docker run \ + --rm \ + --name maria_import \ + --user mysql \ + --env REQUEST=import \ + --env USER=mysql \ + --env DIR_DATA="/var/lib/maria" \ + --env DIR_DUMP="/var/lib/maria_dump" \ + -v /maria/config/my.cnf:/etc/my.cnf:ro \ + -v /maria/config/my.cnf.d/:/etc/my.cnf.d/:ro \ + -v /maria/data/:/var/lib/maria/ \ + -v /maria/dump/:/var/lib/maria_dump/ \ + -v /maria/logs/:/var/log/maria/ \ + -v /maria/socket/:/run/maria/ \ + maria:2.0.0 +``` + +You will see the `Import operation successfully done` message in your terminal. + +
+
+Click here for commands to view the table + +```shellsession +[root@rocky-linux]# docker ps +[root@rocky-linux]# docker exec -it /bin/sh +/ $ mysql -u mysql -p +MariaDB [(none)]> USE tennis; +MariaDB [(tennis])]> SELECT * FROM players; +``` + +
+
+ +## Step 3 - Export data + +In this step you have to define your export request environment variable like this `--env REQUEST=export`, and specify the name of the database you want to export like this `--env DATABASE_NAME=tennis`. + +- We use the `REQUEST` variable in this line of `main.sh`: + - `if [ "$REQUEST" == "export" ]; then` + +- We use the `DATABASE_NAME` variable in this line of `main.sh`: + - `dump $DATABASE_NAME "$DIR_DUMP/export"` + +```sh +# Export +docker run \ + --rm \ + --name maria_export \ + --user mysql \ + --env REQUEST=export \ + --env USER=mysql \ + --env DIR_DATA="/var/lib/maria" \ + --env DIR_DUMP="/var/lib/maria_dump" \ + --env DATABASE_NAME=tennis \ + -v /maria/config/my.cnf:/etc/my.cnf:ro \ + -v /maria/config/my.cnf.d/:/etc/my.cnf.d/:ro \ + -v /maria/data/:/var/lib/maria/ \ + -v /maria/dump/:/var/lib/maria_dump/ \ + -v /maria/socket/:/run/maria/ \ + maria:2.0.0 +``` + +At the end, you will see the `Export operation successfully done` message in your terminal. + +Well done, you can see the exported `.sql` file in this `/maria/dump/export/` directory. + +## Conclusion + +In this tutorial, you were able to import and export your database data with a Dockerized MariaDB. + +##### License: MIT + + + +[first_tutorial]: /tutorials/dockerizing-mariadb-with-alpine-linux +[third_tutorial]: /tutorials/dockerizing-mariadb-with-alpine-linux/connect-via-unix-socket +[rocky]: https://rockylinux.org/ diff --git a/tutorials/dockerizing-mariadb-with-alpine-linux/03.en.md b/tutorials/dockerizing-mariadb-with-alpine-linux/03.en.md new file mode 100644 index 000000000..3f8d5e982 --- /dev/null +++ b/tutorials/dockerizing-mariadb-with-alpine-linux/03.en.md @@ -0,0 +1,197 @@ +--- +SPDX-License-Identifier: MIT +path: "/tutorials/dockerizing-mariadb-with-alpine-linux/connect-via-unix-socket" +slug: "dockerizing-mariadb-with-alpine-linux/connect-via-unix-socket" +date: "2024-10-09" +title: "Connect to Dockerized MariaDB with Node.js via Unix socket" +short_description: "With Node.js we are able to send our SQL queries to a Dockerized MariaDB." +tags: ["Database", "MariaDB", "Docker", "Node.js", "Lang:JS", "Lang:SQL"] +author: "Reza Gharabaghi" +author_link: "https://github.com/mrgharabaghi" +author_img: "https://avatars.githubusercontent.com/u/40915667" +author_description: "" +language: "en" +available_languages: ["en"] +header_img: "header-3" +cta: "dedicated" +--- + +## Introduction + +One of the easiest ways to connect and send SQL queries to `MariaDB` is the popular JavaScript runtime called [Node.js][nodejs]. + +We need the [MySQL][mysql2] library to interact with `MariaDB` and send a simple `SELECT` query. + +As I said in the [first tutorial][first_tutorial], the common way for connecting to a database is via a TCP connection (`127.0.0.1:3306`). Opening an extra port equals less security. Hackers try to connect to a database via open ports like `3306`. Unix sockets are only available for processes inside our Linux machine. + +Another advantage of Unix socket over TCP connection is the speed. + +For more informations, it's better to take a look at [this][ref1] and [this][ref2] link. + +> This tutorial is split into multiple parts. + +## Series index + +1. [Dockerizing MariaDB with Alpine Linux][first_tutorial] +2. [Import and Export data in Dockerized MariaDB][second_tutorial] +3. Connect to Dockerized MariaDB with Node.js via Unix socket (You are here) + +**Prerequisites** + +* Server with Rocky Linux 9 + +## Step 1 - Node.js structure + +For this tutorial I don't want to Dockerize the `Node.js` app, so I install `Node.js` with the `dnf` command in Rocky Linux. So simple: + +```bash +dnf -y install nodejs +``` + +And now you can check the version of `Node.js` with the `node -v` command. + +Every [Node.js][nodejs] project contains atleast one `package.json` file and a JavaScript entry point file, which I named `index.js`. + +Put these two files in a new directory, for example: + +``` +mkdir /nodejs-socket +cd /nodejs-socket +``` + +---------------------------------- + +**package.json** + +```json +{ + "name": "send_query", + "type": "module", + "version": "1.0.0", + "main": "index.js", + "dependencies": { + "mysql2": "^3.11.1" + } +} +``` + +---------------------------------- + +**index.js** + +```js +import mysql from 'mysql2/promise'; + +async function db_connection() { + const new_connection = await mysql.createConnection({ + user: 'root', + // This is the MariaDB Unix socket file + socketPath: '/maria/socket/maria.sock', + database: 'mysql' + }); + + return new_connection; +} + +async function main() { + const new_connection = await db_connection(); + const db_result = await new_connection.query('SELECT * FROM user;'); + new_connection.end(); + + console.log(db_result[0][0].User); + // mariadb.sys +} + +main(); +``` + +Now, you have to install `Node.js` dependencies with the `npm install` command. + +After installing dependencies, you will see the `node_modules` directory and the `package-lock.json` file in your `Nodes.js` directory. + +## Step 2 - Running Node.js + +It's time to run your code with the `node index.js` command. The `console.log()` statement will print the first user (`mariadb.sys`) of the query in terminal. + +---------------------------------- + +Now, we want to send a query and get all players from the `players` table in the `tennis` database. We created the `tennis` database in the [previous tutorial][second_tutorial]. Now, you have to update the `index.js` file and modify 3 lines: + +- Modify `database: 'mysql'` to `database: 'tennis'` +- Modify `SELECT * FROM user;` to `SELECT * FROM players;` +- Modify `console.log(db_result[0][0].User);` to `console.log(db_result[0]);` + +Now run this command again: + +```bash +node index.js +``` + +You will see an array like this: + +```js +[ + { + id: 1, + name: 'Novak Djokovic', + gender: 'Male' + }, + { + id: 2, + name: 'Maria Sharapova', + gender: 'Female' + }, + { + id: 3, + name: 'Roger Federer', + gender: 'Male' + } +] +``` + +Good job, this is the end point of the [Dockerizing MariaDB with Alpine Linux][first_tutorial] tutorial series. + +## Conclusion + +In this tutorial we send our SQL queries via Unix socket to Dockerized `MariaDB`. This series is a good point for you to work with Docker more and more. Isolating every app via Docker is very good, because Docker containers encapsulate apps and their dependencies, and ensure that they run consistently across different environments. + +For example, you can run your Dockerized `MariaDB` on any machine that has Docker already installed on it. + +##### License: MIT + + + +[first_tutorial]: /tutorials/dockerizing-mariadb-with-alpine-linux +[second_tutorial]: /tutorials/dockerizing-mariadb-with-alpine-linux/import-and-export-data + +[nodejs]: https://nodejs.org/en +[mysql2]: https://www.npmjs.com/package/mysql2 +[ref1]: https://stackoverflow.com/a/15952170/16537476 +[ref2]: https://lists.freebsd.org/pipermail/freebsd-performance/2005-February/001143.html