I have deployed a Laravel application with Laradock.
I want to point out that the database connection works fine (users can register, login, ... etc.).
In order to back up the application, I have installed the Spatie's Laravel Backup package.
I set up all config variables accordingly as follows:
config/backup.php
<?php
return [
'backup' => [
/*
* The name of this application. You can use this name to monitor
* the backups.
*/
'name' => env('APP_NAME', 'laravel-backup'),
'source' => [
/*......*/
/*
* The names of the connections to the databases that should be backed up
* MySQL, PostgreSQL, SQLite and Mongo databases are supported.
*
* The content of the database dump may be customized for each connection
* by adding a 'dump' key to the connection settings in config/database.php.
* E.g.
* 'mysql' => [
* ...
* 'dump' => [
* 'excludeTables' => [
* 'table_to_exclude_from_backup',
* 'another_table_to_exclude'
* ]
* ],
* ],
*
* If you are using only InnoDB tables on a MySQL server, you can
* also supply the useSingleTransaction option to avoid table locking.
*
* E.g.
* 'mysql' => [
* ...
* 'dump' => [
* 'useSingleTransaction' => true,
* ],
* ],
*
* For a complete list of available customization options, see https://github.com/spatie/db-dumper
*/
'databases' => [
'mysql',
],
],
/*
* The database dump can be compressed to decrease diskspace usage.
*
* Out of the box Laravel-backup supplies
* Spatie\DbDumper\Compressors\GzipCompressor::class.
*
* You can also create custom compressor. More info on that here:
* https://github.com/spatie/db-dumper#using-compression
*
* If you do not want any compressor at all, set it to null.
*/
'database_dump_compressor' => null,
/*....*/
],
],
];
In Laravel Homestead the backup works fine.
$ php artisan backup:run
.
According to this package's docs, we need to specify the path to the mysqldump
binaries as follows:
config/database.php
//config/database.php
'connections' => [
'mysql' => [
'driver' => 'mysql'
...,
'dump' => [
'dump_binary_path' => '/path/to/the/binary', // only the path, so without `mysqldump` or `pg_dump`
'use_single_transaction',
'timeout' => 60 * 5, // 5 minute timeout
'exclude_tables' => ['table1', 'table2'],
'add_extra_option' => '--optionname=optionvalue',
]
],
This is what I got by default in that same file:
'mysql' => [
'driver' => 'mysql',
'url' => env('DATABASE_URL'),
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
'dump'=>[
'dump_binary_path' => env('DB_DUMP_PATH'), // only the path, so without `mysqldump` or `pg_dump`
'use_single_transaction',
'timeout' => 60 * 5, // 5 minute timeout
//'exclude_tables' => ['table1', 'table2'],
//'add_extra_option' => '--optionname=optionvalue',
'add_extra_option' => '--host='.env('DB_HOST'),
]
],
In my .env file:
DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DUMP_PATH='/usr/bin/'
If I execute the mysqldump
inside the MySQL container, it does work:
Usage: mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]
For more options, use mysqldump --help
However, If I run the backup command inside the workspace container,
artisan backup:run
I get the error:
Backup failed because: The dump process failed with exitcode 127 : Command not found : sh: 1: mysqldump: not found
Then how do I tell Laradock where the mysqldump binary path is located?
Is there a workaround? Maybe setting up a new container that connects the Workspace
with the MySQL
container?
Any alternative approach?
SOLVING with the help of Adrien
Right at the .env
file, I indeed found that the following variable is set to false:
### WORKSPACE #############################################
####
# ...
WORKSPACE_INSTALL_MYSQL_CLIENT=false
# ...
So i changed that to true:
### WORKSPACE #############################################
####
# ...
WORKSPACE_INSTALL_MYSQL_CLIENT=true
# ...
I saved and exited.
This also means that I don't have to make any more changes in the docker-compose.custom.yml
file
To apply that change, I executed (without having to stop any container)
$ docker-compose build workspace
$ docker-compose -f docker-compose.custom.yml up -d workspace
Then I got inside the container
$ docker exec -it my_workspace bash
Once inside I looked for mysqldump:
# which mysqldump
/usr/bin/mysqldump
Finally I could execute the Spatie's Laravel Backup package:
# artisan backup:run
Starting backup...
Dumping database xyz...
Determining files to backup...
Zipping x files and directories...
Created zip containing x files and directories. Size is x.x MB
Copying zip to disk named backMeUp...
Successfully copied zip to disk named backMeUp.
Backup completed!
And that did the trick!
Further Issue
That exact same error
The dump process failed with exitcode 127 : Command not found : sh: /usr/bin/mysqldump: not found
shows up when trying to run
artisan backup:run
from a Laravel scheduled task. That means that the php-worker
container does not have the mysql-client
(therefore, the mysqldump
) package installed.
Workaround I logged into the container as follows:
docker exec -it php-worker sh
Then I installed the mysql-client as follows:
/etc/supervisor/conf.d # apk add mysql-client
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
(1/3) Installing mariadb-common (10.5.17-r0)
(2/3) Installing mariadb-client (10.5.17-r0)
(3/3) Installing mysql-client (10.5.17-r0)
Executing busybox-1.32.1-r3.trigger
OK: 358 MiB in 107 packages
/etc/supervisor/conf.d # which mysqldump
/usr/bin/mysqldump
/etc/supervisor/conf.d # exit
That seemed to do the trick?
If so, a new question arises: how to include the mysql-client right from the php-worker Dockerfile?
Answering myself Well, I forgot to set to true all the variables related to "_INSTALL_MYSQL_CLIENT" ...
As mentioned here, edit laradock
.env
file and set:Then run:
That will update your
workspace
container and restart it.Connect to your container:
You should have access to
mysqldump
: