Dockerfile to define an application and its dependencies. However, in this case we can use MySQLās official container directly - no need for a custom Dockerfile!
Hereās how to run MySQL.
Create the App
Weāll run MySQL as a new app:y when prompted to tweak the default app settings. Then, on the Fly Launch page:
- Name the app whatever youād like. The name will become a hostname our application uses to connect to the database, such as
my-mysql.internal. - If youāre using MySQL 8, itās a good idea to add some additional RAM to the VM: we recommend selecting 2GB of VM Memory.
Configure the App
Letās create a volume straight-away. If you donāt create a volume, youāll lose all of your data on each deployment.fly.toml file that fly launch generated.
- We deleted the
[[http_service]]block and everything under it. We donāt need it! - In the
[env]section, we added two not-so-secret environment variables that MySQL will need to initialize itself.- The
MYSQL_USERhere should be any user butroot, which already exists.
- The
- We added the
[processes]section for the defaultappprocess, which lets us pass custom commands (overriding DockerāsCMD).- For MySQL 8+, youāll want to use the
mysql_native_passwordauthentication plugin. As shown in the fly.toml above, there are different syntax for setting this plugin based on the MySQL version. - If youāre using MySQL 5.7, your
appprocess can be simplified as shown in thefly.tomlexample above, as it usesmysql_native_passwordby default. - MySQL 8.0.32 to 8.3 must explicitly set this with the
--default-authentication-pluginflag. - Starting from MySQL 8.4, the
--default-authentication-pluginoption is deprecated. If youāre using 8.4+, you can make use of the--mysql-native-passwordflag instead.
- For MySQL 8+, youāll want to use the
Important: Set MySQLās data directory to a subdirectory of your mounted volume. Mounting a disk in Linux usually results in a
lost+found directory being created. However, MySQL wonāt initialize into a data directory unless itās completely empty. Thatās why you need to use a subdirectory of the mounted location: /data/mysql.Deploy the App
Weāre now ready to deploy the MySQL app! Go ahead and run:my-mysql.internal as the hostname. Any app that needs to access the database should set the hostname and username as environment variables, and create a secret for the database password.
Debugging Possible Errors
mysqld: Table 'mysql.plugin' doesn't exist
This error is an indicator that the mysql System Schema inside the MySQL data directory is empty. This can happen due to different reasons. One of them is when a MySQL app is previously deployed with --default-authentication-plugin, and it gets re-deployed with the updated syntax --mysql-native-password=ON.
The quickest way to fix this is to revise the --datadir flag to a different directory from what was previously set:
mysql system schema. Once done, redeploy your changes with fly deploy.
Access the database from outside
To connect to your MySQL database from outside of your Fly organization, you need a WireGuard connection. However,fly on your local machine can connect using user-mode WireGuard magic, without you having to set up your own WireGuard tunnel.
You can forward the MySQL server port to your local machine using fly proxy:
3306 port is already in use:
localhost:3306 and the username and password credentials from above:
Backups
Weāll take a snapshot of the created volume every day. We retain 5 days of snapshots. To restore a snapshot, make sure you have the latest version of the flyctl, and then create a new volume using the--snapshot-id flag.