简体   繁体   中英

Laravel Docker cannot execute PostgreSQL pg_restore

I'm running a docker container with Laravel 5 and I have PostgreSQL on my machine.

Everything works perfectly, except that I have waaaay to many data on my DB and that made seeding to take about 1 hour. The workaround I came up with is to restore a backup file (data only) that would seed the database for me in about 5 min.

Awesome! But...

Laravel is running inside the docker container, and PostgreSQL is not, so when Laravel does

  $cmd = "pg_restore -v -U pgadmin -d $database $path";

  exec($cmd);

I get an error saying that there is no pg_restore to execute.

  sh: 1: pg_restore: not found

So, finally, my question is: How can I make Laravel to be able to execute pg_restore?

Obs: it works when also running Laravel on the machine, but I really need to solve it with Laravel on docker and postgres outside.

Thanks in advance!

UPDATE:

I editted the docker-compose.yml and added the following line under volumes

./usr/bin/pg_restore:/usr/bin/pg_restore

Now the error is just

sh: 1: pg_restore: Permission denied

It means now it "sees" the pg_restore command but does not have rights to execute it, since it's running inside a docker container.... how can i solve this one?

Install the tools you need -inside- the container if you want to run them from -inside- the container.

So even though you might not want to run the database process, you still need the tools. Install it.

Just found the solution: Install postgres on the Dockerfile. Now it's able to restore databases because the pg_restore is installed in it. Trigger the pg_restore command from inside the docker, but using the same parameters from the .env file for the connection.

UPDATE:

The migration now does

    $database = 'database_name';
    $path     =  __DIR__ . "/database.backup";
    $ip       = env('DB_HOST');
    $port     = env('DB_PORT');
    $passw    = env('DB_PASSWORD');

    $cmd = "PGPASSWORD=\"$passw\" pg_restore -h $ip -p $port -v -U pgadmin -d $database $path";

    exec($cmd);

and it's working just fine!

UPDATE

Other answers are about installing the tools to your container. I suggest you not to do so as long as you are looking for a right way. Installing redundant tools to containers is a violation of the separation of concerns principle introduced by containers.

The usual way of resolving such problems is using the needed tools from the outside of container whenever possible, taking advantage of the ability to work over the network. And pg_restore enables you to do so.


You can run pg_restore from the outside of the container.

According to pg_restore --help , you can additionally specify host data such as hostname, port, etc. of the machine you want to run pg_restore against. Thus, all you need is to know the IP of your container and to have the PostgreSQL port exposed to the outside (which you already have, as far I as see).

Quick snippet:

pg_restore -h HOST_IP -p HOST_PORT -U USER -W PASSWORD

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM