Search code examples
phpmysqldocker

How to import database inside dockerfile?


I have a project developed with PHP and I want to move it inside a Docker container. I want to import database automatically inside Dockerfile.

If I import the database after building the container all works fine (docker exec -it my-laravel-app bash then mysql -u user -p1993 -h db bsp < /var/www/database/bsp.sql).

I get the error failed to solve: process "/bin/sh -c wait-for-it -t 30 ${DB_HOST}:${DB_PORT} if [ -f /var/www/database/bsp.sql ]; then mysql -u ${DB_USERNAME} -p${DB_PASSWORD} -h ${DB_HOST} ${DB_DATABASE} < /var/www/database/bsp.sql; fi" did not complete successfully: exit code: 2.

Dockerfile

# Set the base image for subsequent instructions
FROM php:8.2-fpm

# Install dependencies
RUN apt-get update && apt-get install -y \
    build-essential \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    curl \
    unzip \
    git \
    libzip-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    default-mysql-client \
    wait-for-it \
    libpng-dev && \
    docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

# Set working directory
WORKDIR /var/www

# Remove default server definition
RUN rm -rf /var/www/html

# Copy existing application directory contents
COPY . /var/www

# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www

# Change current user to www
USER www-data

ENV DB_HOST=db
ENV DB_PORT=3306
ENV DB_DATABASE=bsp
ENV DB_USERNAME=user
ENV DB_PASSWORD=1993

# Wait for the database to be ready and import SQL dump
USER root
RUN wait-for-it -t 30 ${DB_HOST}:${DB_PORT} \
if [ -f /var/www/database/bsp.sql ]; then \
    mysql -u ${DB_USERNAME} -p${DB_PASSWORD} -h ${DB_HOST} ${DB_DATABASE} < /var/www/database/bsp.sql; \
fi
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]

Solution

  • I've did it, thanks for your answers! This is the complete docker-compose.yml file. I've used /docker-entrypoint-initdb.d/ directory where I placed the database to be imported.

    services:
      app:
        build:
          context: .
          dockerfile: Dockerfile
        image: my-laravel-app
        container_name: my-laravel-app
        restart: unless-stopped
        working_dir: /var/www
        volumes:
          - ./:/var/www
          - ./.env:/var/www/.env
        environment:
          - APP_ENV=local
        networks:
          - app-network
    
      nginx:
        image: nginx:alpine
        container_name: my-nginx
        ports:
          - "8000:80"
          - "${VITE_PORT:-5173}:${VITE_PORT:-5173}"
        volumes:
          - ./:/var/www
          - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
          - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
        depends_on:
          - app
        networks:
          - app-network        
    
      node:
        platform: linux/arm64/v8
        build:
          context: .
          dockerfile: Dockerfile.node
        image: my-laravel-node
        container_name: my-laravel-node
        ports:
          - "3000:3000"
        restart: unless-stopped
        working_dir: /var/www
        volumes:
          - ./:/var/www
          - /var/www/node_modules
        networks:
          - app-network
    
      db:
        platform: linux/x86_64
        image: mysql:8.0
        container_name: my-mysql
        restart: unless-stopped
        environment:
          MYSQL_DATABASE: ${DB_DATABASE}
          MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
          MYSQL_PASSWORD: ${DB_PASSWORD}
          MYSQL_USER: ${DB_USERNAME}
        volumes:
          - dbdata:/var/lib/mysql
          - ./data.sql:/docker-entrypoint-initdb.d/data-dump.sql  
        networks:
          - app-network
        ports:
          - "3306:3306"
    
    networks:
      app-network:
        driver: bridge
    
    volumes:
      dbdata:
        driver: local