Skip to content

Commit

Permalink
Merge pull request #39 from mambelli/mysql_via_apptainer
Browse files Browse the repository at this point in the history
Using Apptainer to run the MySQL server and client in the mysql image
  • Loading branch information
michmx authored Aug 3, 2024
2 parents 3012629 + f52aff4 commit 27f2962
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
3 changes: 3 additions & 0 deletions _episodes/04-mysql-and-python.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,14 @@ We need the following URL components:
* Database Name: Name of the specific database to connect to.

So, the URL structure is : `Dialect+driver://username:password@hostname:port/databaseName`
or, if you use Apptainer and a socket file is: `Dialect+driver://username:password@localhost/databaseName?unix_socket=filePath`

And we create a engine using this db_url.
```python
# Define the MySQL database connection URL
db_url = "mysql+pymysql://root:mypassword@localhost:3306/metadata2"
# if using Apptainer uncomment the next line to define the URL using the socket file:
# db_url = "mysql+pymysql://root:mypassword@localhost/metadata2?unix_socket=/var/run/mysqld/mysql.sock"

# Create an SQLAlchemy engine
engine = create_engine(db_url)
Expand Down
33 changes: 24 additions & 9 deletions setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,35 @@ executing the following command:
apptainer --version
```

We will use the same image as in Option 1. Execute the following commands to run the MySQL server in an
Apptainer instance:
We will use the same image as in Option 1.
Appteiner images are readonly if overlayfs is not available, so we'll be mounting the socket and database directories. This allows also for some persistency.
Depending on the system settings unprivileged Apptainer may not be allowed to bind to ports, so we'll use a socket file to connect to the server.
First move to a local directory: the image is not small and disk access will be faster, e.g. `mkdir /scratch/<username>/mysql-apptainer; cd /scratch/<username>/mysql-apptainer`.
Then execute the following commands to run the MySQL server in an Apptainer instance (replace mypassword with your password):
```bash
apptainer instance start docker://mysql:latest myfirst-sqlserver --net --network-args "portmap=3306:3306/tcp" \
--env="MYSQL_ROOT_PASSWORD=mypassword"
echo "SET PASSWORD FOR 'root'@'localhost' = 'mypassword';" > .mysqlrootpw
mkdir -p ./mysql/var/lib/mysql/ ./mysql/run/mysqld
apptainer pull --name mysql.sif docker://mysql
apptainer instance start --bind ${PWD} --bind ${PWD}/mysql/var/lib/mysql/:/var/lib/mysql --bind ${PWD}/mysql/run/mysqld:/run/mysqld ./mysql.sif mysql
apptainer instance list # just to make sure the instance started
apptainer exec instance://mysql mysqld --init-file=${PWD}/.mysqlrootpw &
```

> ## TODO:
> It is not working out of the box. Need to figure out why.
{: .caution}
If you don't run the last command in background the terminal will be used by the server console and you'll have to use another terminal for other commands.

To test that if everything is up and running, execute the following command:
```bash
apptainer instance exec myfirst-sqlserver bash -c "mysql -uroot -pmypassword"
apptainer exec instance://mysql mysql -S /var/run/mysqld/mysql.sock -u root -pmypassword
```
Remember to use it also throughout the tutorial instead of the docker command.

You may want to use a different password and a safer way to run mysql id to avoid to put the password in the command line, e.g. save in mysqlclient.ini the following:
```
[client]
password="mypassword"
```
And then run with (--defaults-extra-file must be the first option):
```bash
apptainer exec instance://mysql mysql --defaults-extra-file=myconf -S /var/run/mysqld/mysql.sock -u root
```

If you are interested on learning more about Apptainer, take a look at the
Expand Down

0 comments on commit 27f2962

Please sign in to comment.