Laravel PlanetScale Issue "PDO::__construct(): open_basedir restriction in effect. File(/etc/ssl/cert.pem) is not within the allowed path(s): (/var/www/html:/dev/stdout:/tmp)"

I’m using PHP 8.1

2022-08-13T11:28:20.732 app[1769a109] sin [info] {"message":"SQLSTATE[HY000] [2002] (trying to connect via (null)) (SQL: select * from `games` where `end_price` is null and `pairs` = 1 order by `created_at` desc limit 1)","context":{"exception":{"class":"Illuminate\\Database\\QueryException","message":"SQLSTATE[HY000] [2002] (trying to connect via (null)) (SQL: select * from `games` where `end_price` is null and `pairs` = 1 order by `created_at` desc limit 1)","code":2002,"file":"/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connection.php:759","previous":{"class":"PDOException","message":"SQLSTATE[HY000] [2002] (trying to connect via (null))","code":2002,"file":"/var/www/html/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70","previous":{"class":"PDOException","message":"PDO::__construct(): open_basedir restriction in effect. File(/etc/ssl/cert.pem) is not within the allowed path(s): (/var/www/html:/dev/stdout:/tmp)","code":0,"file":"/var/www/html/vendor/laravel/framework/src/Illuminate/Database

fly.toml

# fly.toml file generated for some-api on 2022-08-13T15:07:07+08:00

app = "some-api"
kill_signal = "SIGINT"
kill_timeout = 5
processes = []

[build]
  [build.args]
    NODE_VERSION = "16"
    PHP_VERSION = "8.1"

[env]
  APP_ENV = "production"
  LOG_CHANNEL = "stderr"
  LOG_LEVEL = "info"
  LOG_STDERR_FORMATTER = "Monolog\\Formatter\\JsonFormatter"

  # DB
  DB_CONNECTION = "mysql"
  DB_HOST = "xxxxxxxx.psdb.cloud"
  DB_PORT = "3306"
  DB_DATABASE = "xxxxxxxx"
  DB_USERNAME = "xxxxxxxx"
  DB_PASSWORD = "xxxxxxxx"
  MYSQL_ATTR_SSL_CA = "/etc/ssl/cert.pem"


[experimental]
  allowed_public_ports = []
  auto_rollback = true

[[services]]
  http_checks = []
  internal_port = 8080
  processes = ["app"]
  protocol = "tcp"
  script_checks = []
  [services.concurrency]
    hard_limit = 25
    soft_limit = 20
    type = "connections"

  [[services.ports]]
    force_https = true
    handlers = ["http"]
    port = 80

  [[services.ports]]
    handlers = ["tls", "http"]
    port = 443

  [[services.tcp_checks]]
    grace_period = "1s"
    interval = "15s"
    restart_limit = 0
    timeout = "2s"

Dockerfile

# syntax = docker/dockerfile:experimental

# Default to PHP 8.1, but we attempt to match
# the PHP version from the user (wherever `flyctl launch` is run)
# Valid version values are PHP 7.4+
ARG PHP_VERSION=8.1
FROM serversideup/php:${PHP_VERSION}-fpm-nginx as base

LABEL fly_launch_runtime="laravel"

RUN apt-get update && apt-get install -y \
    git curl zip unzip rsync ca-certificates vim htop cron \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /var/www/html

# copy application code, skipping files based on .dockerignore
COPY . /var/www/html

RUN composer install --optimize-autoloader --no-dev \
    && mkdir -p storage/logs \
    && php artisan optimize:clear \
    && chown -R webuser:webgroup /var/www/html \
    && sed -i 's/protected \$proxies/protected \$proxies = "*"/g' app/Http/Middleware/TrustProxies.php \
    && echo "MAILTO=\"\"\n* * * * * webuser /usr/bin/php /var/www/html/artisan schedule:run" > /etc/cron.d/laravel \
    && rm -rf /etc/cont-init.d/* \
    && cp docker/nginx-websockets.conf /etc/nginx/conf.d/websockets.conf \
    && cp docker/nginx-default /etc/nginx/sites-available/default \
    && cp docker/entrypoint.sh /entrypoint \
    && chmod +x /entrypoint

# If we're using Octane...
RUN if grep -Fq "laravel/octane" /var/www/html/composer.json; then \
    rm -rf /etc/services.d/php-fpm; \
    if grep -Fq "spiral/roadrunner" /var/www/html/composer.json; then \
    mv docker/octane-rr /etc/services.d/octane; \
    if [ -f ./vendor/bin/rr ]; then ./vendor/bin/rr get-binary; fi; \
    rm -f .rr.yaml; \
    else \
    mv docker/octane-swoole /etc/services.d/octane; \
    fi \
    fi

# From our base container created above, we
# create our final image, adding in static
# assets that we generated above
FROM base

RUN chown -R webuser:webgroup /var/www/html/public

EXPOSE 8080

ENTRYPOINT ["/entrypoint"]

was able to fix it by changing the cert path to
MYSQL_ATTR_SSL_CA = “/etc/ssl/certs/ca-certificates.crt”

ahhh a bug! I just updated the base container used for Laravel apps.

okay, a few things:

  1. The ssl path now should be /etc/ssl/certs/ca-certificates.crt (previous file path was for Alpjne base containers but newest ones are based on Ubuntu
  2. It looks like the new containers have some open base dir config in place that needs to be changed. This file specifically (assuming php 8.1) docker-php/y-override-php-defaults.conf at dd6968f388c765136825f39d397a6c4abc234521 · serversideup/docker-php · GitHub

That file, within the container, is at /etc/php/8.1/fpm/pool.d/y-override-php-defaults.conf

That might be most easily edited with a sed find and replace command within the Dockerfile.

On my end i’ll open a PR to the base containers and can update our launcher so it takes care of that.

1 Like

Oh, perhaps we don’t need to care about the open_basedir setting, that would be pleasant!

The error message is misleading. Not sure why it did not say it cannot locate the file or something. Maybe it is still there and deliberately made not accessible by default?

1 Like