Which is the right way to run laravel migrations using Google Cloud Run and Google Cloud SQL
Asked Answered
A

3

1

I came here to expose the specific way that i found to run migrations into a Google Cloud Run project using Google Cloud SQL and Laravel, which is simple, i just connect from my .env laravel to Cloud SQL (using Cloud SQL Proxy) and from my local console i run the migrations with the classic command php artisan migrate.

I have never found another way to run migrations as i'm currently making them and actually i have never found more information about it, so that is the question:

Is there another simply and secure way to run laravel migrations to Google Cloud Run than running them in local enviroment?

Audrey answered 16/6, 2021 at 20:5 Comment(2)
The best way is to perform the migration outside your app code, in your CI/CD pipeline for example.Actaeon
I recommend that you perform the database setup (migrations) before deploying Cloud Run. Review other items such as sessions and cookies and enable storing them in the database instead of local files in the container. There are tools available to monitor file system activity. In most cases, you want any files that Laravel or your application creates locally to be stored in the database or on Cloud Storage. Cloud Run does not have storage persistence.Frausto
C
3

Short version (very short version):

  1. Create a new file and call it anything (e.g. "db-migration.sh") and add following :
#!/bin/bash

# Run Laravel migration (by force, since it would be a prod-environment)
php artisan migrate --force

# Run Apache in "foreground" mode (the default mode that runs in Docker)
apache2-foreground
  1. Add following 2 lines to your Dockerfile
# Make the file executable, or use "chmod 777" instead of "chmod +x"
RUN chmod +x /var/www/html/db-migration.sh

# This will run the shell file at the time when container is up-and-running successfully (and NOT at the BUILD time)
ENTRYPOINT ["/var/www/html/db-migration.sh"]

Assumptions:

  • Docker image is having PHP/Apache combination (and not Alpine/Nginx version)
  • Cloud Run is configured correctly
  • Cloud SQL is up-and-running and attached correctly with Cloud Run

Check "Logs" tab of Cloud Run service to verify if the migrations executed successfully (screenshot of a test migration attached) enter image description here

Carlocarload answered 7/9, 2021 at 13:14 Comment(4)
This is the right way to do it. Having the migration being part of the service start-up at run time.Estrus
you should also lock the database so that multiple deployments don't try to run migrations at the same time. gist.github.com/markkimsal/3f9009dceef8eabdd41df72959e71eb1Estrus
I'm searching the good way too. But doing this will start the migration at every cold start. The cold start will be slower even if there is nothing to migrate ? And what happened if cloud run create 5 instances and each instances try to apply the same migration ? Using gcr.io/google-appengine/exec-wrapper isn't the safer way ?Saavedra
Triggering the entrypoint command does not really adds to the cold-start time. Above comment by @Estrus about locking the DB when running migrations would prevent duplicate triggers/executions - have not tried it though.Carlocarload
N
0

You may make use of app-engine-exec-wrapper, which is a helper for Cloud SQL Auth proxy. It will help you connect with the database securely. This is an example of how you would use it for Django applications:

  - id: "apply migrations"
    name: "gcr.io/google-appengine/exec-wrapper"
    args:
      [
        "-i",
        "gcr.io/$PROJECT_ID/${_SERVICE_NAME}",
        "-s",
        "${PROJECT_ID}:${_REGION}:${_INSTANCE_NAME}",
        "-e",
        "SETTINGS_NAME=${_SECRET_SETTINGS_NAME}",
        "--",
        "python",
        "manage.py",
        "migrate",
      ]

You can visit their github page to know more about this.

Nadya answered 31/8, 2021 at 9:31 Comment(0)
C
-1

You can add a controller function to execute an Artisan command if called using HTTP Post Request.

For instance, use this controller function for /migrate path on your app (registered with Route::post in your routes file).

public function migrate(Request $request)
{
    Artisan::call('migrate');
}

And you can execute the Artisan migrate command by sending a HTTP Request to /migrate

curl -request POST \
     --header "Content-Type: application/json" \
     https://you-cloud-run-app-url.run.app/migrate

But the downside of this solution is security. You have to make your own middleware to secure this action from un-allowed request (or use an OAuth2 protocol).

Reference:

Cobham answered 16/6, 2021 at 22:59 Comment(1)
Thanks, i recieve "Undefined constant 'STDIN'" error when i run this, do you know why?Audrey

© 2022 - 2024 — McMap. All rights reserved.