Overview
The Restaurant Management System includes a production-ready Dockerfile that packages the Laravel application with Apache web server. This guide covers building, running, and deploying the application using Docker.
Dockerfile Overview
The application uses a multi-stage build process with the following components:
Base Image : PHP 8.2 with Apache
PHP Extensions : PDO MySQL, PostgreSQL, GD, Zip, and more
Frontend : Node.js 18.x for asset compilation
Web Server : Apache with mod_rewrite enabled
Port : 8080 (Railway compatible)
Quick Start
Build Docker Image
Build the Docker image from the project root: docker build -t restaurant-management .
This process:
Installs system dependencies
Installs Composer and npm packages
Compiles frontend assets with Vite
Configures Apache
Run Container
Run the container with environment variables: docker run -d \
--name restaurant-app \
-p 8080:8080 \
-e APP_KEY="base64:your-app-key" \
-e DB_HOST="your-database-host" \
-e DB_DATABASE="restaurante" \
-e DB_USERNAME="your-username" \
-e DB_PASSWORD="your-password" \
restaurant-management
Dockerfile Breakdown
Base Image and System Dependencies
# Use PHP 8.2 with Apache
FROM php:8.2-apache
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
unzip \
libpng-dev \
libonig-dev \
libxml2-dev \
libzip-dev \
libsodium-dev \
libpq-dev \
default-mysql-client \
default-libmysqlclient-dev \
libfreetype6-dev \
libjpeg62-turbo-dev
The Dockerfile includes both MySQL and PostgreSQL client libraries for database flexibility.
PHP Extensions
# Configure and install PHP extensions
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install pdo_mysql pdo_pgsql mbstring exif pcntl bcmath gd zip sodium
Installed Extensions:
pdo_mysql - MySQL database support
pdo_pgsql - PostgreSQL database support
mbstring - Multibyte string handling
exif - Image metadata reading
pcntl - Process control
bcmath - Arbitrary precision mathematics
gd - Image processing (with JPEG and FreeType)
zip - ZIP archive handling
sodium - Modern cryptography
Composer Installation
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
Copies Composer from the official Composer image.
Node.js for Frontend Assets
# Install Node.js 18.x
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get update && apt-get install -y nodejs
Required for building Vite assets and Livewire components.
Apache Configuration
# Configure Apache
RUN a2enmod rewrite \
&& sed -i 's|/var/www/html|/var/www/html/public|g' /etc/apache2/sites-available/000-default.conf
This:
Enables mod_rewrite for Laravel routing
Sets document root to public/ directory
Application Setup
# Set working directory
WORKDIR /var/www/html
# Copy application files
COPY . .
# Set permissions
RUN chown -R www-data:www-data storage bootstrap/cache
# Install dependencies
RUN composer install --no-dev --optimize-autoloader
RUN npm install
# Build frontend assets
RUN npm run build
# Expose port 8080
EXPOSE 8080
# Start Apache
CMD [ "apache2-foreground" ]
The Dockerfile includes composer install --no-dev which excludes development dependencies. This is optimal for production but not for development.
Docker Compose Setup
Full Stack with MySQL
Create a docker-compose.yml file:
version : '3.8'
services :
app :
build : .
container_name : restaurant-app
ports :
- "8080:8080"
environment :
- APP_NAME=Restaurant Management
- APP_ENV=production
- APP_KEY=${APP_KEY}
- APP_DEBUG=false
- APP_URL=http://localhost:8080
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=restaurante
- DB_USERNAME=restaurant_user
- DB_PASSWORD=secret
depends_on :
- db
networks :
- restaurant-network
db :
image : mysql:8.0
container_name : restaurant-db
environment :
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=restaurante
- MYSQL_USER=restaurant_user
- MYSQL_PASSWORD=secret
volumes :
- mysql-data:/var/lib/mysql
networks :
- restaurant-network
ports :
- "3306:3306"
volumes :
mysql-data :
driver : local
networks :
restaurant-network :
driver : bridge
Run with Docker Compose
Run Migrations
docker-compose exec app php artisan migrate --force
Create Admin User
docker-compose exec app php artisan tinker
In Tinker: $user = new App\Models\ User ();
$user -> name = 'Admin' ;
$user -> email = '[email protected] ' ;
$user -> usertype = 'admin' ;
$user -> password = bcrypt ( 'password' );
$user -> save ();
Access Application
Navigate to http://localhost:8080
Development Docker Setup
For development with hot reload and debugging:
FROM php:8.2-apache
# Install dependencies (same as production)
RUN apt-get update && apt-get install -y \
git curl unzip libpng-dev libonig-dev libxml2-dev libzip-dev \
libsodium-dev libpq-dev default-mysql-client \
default-libmysqlclient-dev libfreetype6-dev libjpeg62-turbo-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install pdo_mysql pdo_pgsql mbstring exif pcntl bcmath gd zip sodium
# Install Xdebug for development
RUN pecl install xdebug && docker-php-ext-enable xdebug
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Install Node.js
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash - \
&& apt-get update && apt-get install -y nodejs
# Configure Apache
RUN a2enmod rewrite \
&& sed -i 's|/var/www/html|/var/www/html/public|g' /etc/apache2/sites-available/000-default.conf
WORKDIR /var/www/html
# Install dependencies with dev packages
COPY composer.json composer.lock ./
RUN composer install
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN chown -R www-data:www-data storage bootstrap/cache
EXPOSE 8080
CMD [ "apache2-foreground" ]
version : '3.8'
services :
app :
build :
context : .
dockerfile : Dockerfile.dev
volumes :
- .:/var/www/html
- /var/www/html/vendor
- /var/www/html/node_modules
environment :
- APP_ENV=local
- APP_DEBUG=true
ports :
- "8080:8080"
- "5173:5173" # Vite dev server
Environment Variables
Required Variables
APP_KEY = base64:your-generated-key
DB_HOST = db-hostname
DB_DATABASE = restaurante
DB_USERNAME = db-user
DB_PASSWORD = db-password
Optional Variables
APP_ENV = production
APP_DEBUG = false
APP_URL = http://localhost:8080
LOG_CHANNEL = stack
SESSION_DRIVER = database
CACHE_DRIVER = file
QUEUE_CONNECTION = sync
Pass environment variables using -e flag or --env-file: docker run --env-file .env.production restaurant-management
Volume Mounting
Persist Storage
docker run -d \
-v $( pwd ) /storage:/var/www/html/storage \
-v $( pwd ) /.env:/var/www/html/.env \
restaurant-management
Development with Live Reload
docker run -d \
-v $( pwd ) :/var/www/html \
-v /var/www/html/vendor \
-v /var/www/html/node_modules \
restaurant-management
Railway Deployment
The Dockerfile is optimized for Railway:
Connect Repository
Connect your GitHub repository to Railway
Add Environment Variables
In Railway dashboard, add: APP_KEY = your-app-key
DB_CONNECTION = mysql
DB_HOST = ${{ MYSQL_HOST }}
DB_PORT = ${{ MYSQL_PORT }}
DB_DATABASE = ${{ MYSQL_DATABASE }}
DB_USERNAME = ${{ MYSQL_USER }}
DB_PASSWORD = ${{ MYSQL_PASSWORD }}
Deploy
Railway automatically detects the Dockerfile and deploys
Run Migrations
In Railway CLI or dashboard: railway run php artisan migrate --force
Port 8080 is exposed specifically for Railway’s routing requirements.
Docker Commands Reference
Building
Build
Build with tag
Build without cache
docker build -t restaurant-management .
Running
Run detached
Run with name
Run interactive
docker run -d -p 8080:8080 restaurant-management
Management
View logs
Execute commands
Stop and remove
docker logs restaurant-app
# Follow logs
docker logs -f restaurant-app
Optimization Tips
Multi-stage Build
For smaller images, use multi-stage builds:
# Build stage
FROM php:8.2-apache as builder
WORKDIR /var/www/html
COPY . .
RUN composer install --no-dev --optimize-autoloader
RUN npm install && npm run build
# Production stage
FROM php:8.2-apache
WORKDIR /var/www/html
COPY --from=builder /var/www/html .
RUN a2enmod rewrite
EXPOSE 8080
CMD [ "apache2-foreground" ]
.dockerignore
Create .dockerignore to reduce build context:
node_modules
vendor
.git
.env
storage/logs/*
storage/framework/cache/*
storage/framework/sessions/*
storage/framework/views/*
.phpunit.cache
tests
Troubleshooting
Permission Issues
# Fix storage permissions
docker exec restaurant-app chown -R www-data:www-data storage bootstrap/cache
docker exec restaurant-app chmod -R 775 storage bootstrap/cache
Database Connection Failed
# Check if database container is running
docker-compose ps
# Test database connection
docker-compose exec app php artisan tinker
>>> DB::connection () ->getPdo ();
Apache Not Starting
# Check logs
docker logs restaurant-app
# Verify Apache configuration
docker exec restaurant-app apache2ctl -t
Build Failures
Common causes:
Network issues downloading packages
Insufficient disk space
Invalid composer.json or package.json
Solution: Build with --no-cache and check logs
Next Steps