phppdomariadb

In Docker: Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'cinema.movies' doesn't exist in


I tried to build a container for a PHP-apache app with MariaDB and PhpMyAdmin and i receive the error:

Fatal error: Uncaught PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'cinema.movies' doesn't exist in /var/www/html/app/DAO/MovieDAO.php:14 Stack trace: #0 /var/www/html/app/DAO/MovieDAO.php(14): PDOStatement->execute() #1 /var/www/html/app/Controllers/MovieController.php(16): App\DAO\MovieDAO->getAllMovies() #2 /var/www/html/resources/Views/home.php(5): App\Controllers\MovieController->getAllMovies() #3 /var/www/html/index.php(67): include_once('/var/www/html/r...') #4 {main} thrown in /var/www/html/app/DAO/MovieDAO.php on line 14

and if i try to go to port 8081 (PMA) i receive the error that i dont have access.

I cannot understand why i dont have access to the db, or why seems like that the db doesnt exist.

My yml file is:

services:
  web:
    image: php:8.2.18-apache
    container_name: cinema
    build: .
    ports:
      - "8080:80"
    environment:
      MYSQL_HOST: $(DB_HOST)
      MYSQL_DATABASE: $(DB_NAME)
      MYSQL_USER: $(DB_USER)
      MYSQL_PASSWORD: $(DB_PASS)
    volumes:
      - .:/var/www/html
    depends_on:
      - db
    env_file:
      - .env
    networks:
      - app-network

  db:
    image:  mariadb:10.4.32
    container_name: database
    restart: always
    environment:
      MARIADB_ALLOW_EMPTY_ROOT_PASSWORD: "1"
      MYSQL_HOST: $(DB_HOST)
      MYSQL_DATABASE: $(DB_NAME)
      MYSQL_USER: $(DB_USER)
      MYSQL_PASSWORD: $(DB_PASS)
      MARIADB_AUTO_UPGRADE: "1"
    volumes:
      - db_data:/var/lib/mysql
      - ./cinema.sql:/docker-entrypoint-initdb.d/cinema.sql
    env_file:
      - .env
    networks:
      - app-network

  phpmyadmin:
    image:  phpmyadmin:5.2.1
    container_name: phpmyadmin
    restart: always
    environment:
      PMA_HOST: $(DB_HOST)
      PMA_USER: $(DB_USER)
      PMA_PASSWORD: $(DB_PASS)
    ports:
      - "8081:80"
    depends_on:
      - db
    env_file:
      - .env
    networks:
      - app-network

volumes:
  db_data:

networks:
  app-network:
    driver: bridge

And the Dockerfile:

FROM php:8.2.18-apache

WORKDIR /var/www/html

RUN apt-get update && apt-get install -y \
    curl \
    git \
    zip \
    unzip \
    libpng-dev \
    libjpeg-dev \
    libfreetype6-dev \
    libonig-dev \
    libxml2-dev \
    libzip-dev && \
    docker-php-ext-configure gd --with-freetype --with-jpeg && \
    docker-php-ext-install -j$(nproc) gd && \
    docker-php-ext-install -j$(nproc) mysqli pdo pdo_mysql && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
    apt-get install -y nodejs && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN node -v && npm -v

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

COPY composer.json composer.lock ./
COPY package.json package-lock.json ./

RUN COMPOSER_ALLOW_SUPERUSER=1 composer install
RUN npm install

COPY . .

EXPOSE 80

I had that issue SQLSTATE[HY000] [2002] No such file or directory and i solve it by adding the volume to the db image and changing the db host directly in the .env file

Please someone can help me?


Solution

  • It looks like one of:

    a) The MariaDB data volume was initialized before the /docker-entrypoint-initdb.d got a entry to initialize the database with the missing table/view.

    or:

    b) you are accessing the web before MariaDB has completed initialization.

    The solution for b) is:

    services:
      web:
    ...
        depends_on:
          db:
            condition: service_healthy
    ...
      db:
    ...
        healthcheck:
          test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
          start_period: 10s
          interval: 10s
          timeout: 5s
          retries: 3
    ...
      phpmyadmin:
        depends_on:
          db:
            condition: service_healthy
    

    Also, don't pass MYSQL_HOST to the MariaDB container. For the others its where to connect. For the MariaDB container is meaningless.

    ref: https://mariadb.com/kb/en/using-healthcheck-sh/