PHP
Step-by-step guide to deploy a PHP application on Out Plane
This guide walks you through deploying a PHP application on Out Plane using Git-driven deployment with a Dockerfile.
Prerequisites
- An Out Plane account
- A GitHub account
- PHP 8.1+ installed on your machine
- Composer installed on your machine
- Git installed on your machine
Create the PHP App
Create a new directory for your project:
mkdir my-php-app
cd my-php-appCreate the directory structure:
mkdir publicCreate public/index.php:
<?php
header('Content-Type: application/json');
$route = $_SERVER['REQUEST_URI'];
$method = $_SERVER['REQUEST_METHOD'];
// Remove query string from route
$route = strtok($route, '?');
// Simple router
switch ($route) {
case '/':
echo json_encode([
'message' => 'Hello from Out Plane',
'php_version' => PHP_VERSION
]);
break;
case '/health':
echo json_encode(['status' => 'healthy']);
break;
default:
http_response_code(404);
echo json_encode(['error' => 'Not found']);
break;
}Create composer.json in the root directory:
{
"name": "example/my-php-app",
"description": "PHP application for Out Plane",
"type": "project",
"require": {
"php": ">=8.1"
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}Install dependencies (this creates composer.lock):
composer installCreate the Dockerfile
Create a file called Dockerfile in your project root:
FROM php:8.3-apache
# Enable Apache mod_rewrite
RUN a2enmod rewrite
# Set document root to public folder
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
# Configure Apache to listen on PORT environment variable
RUN sed -i 's/Listen 80/Listen ${PORT}/' /etc/apache2/ports.conf
RUN sed -i 's/:80/:${PORT}/' /etc/apache2/sites-available/000-default.conf
# Allow .htaccess overrides
RUN sed -i '/<Directory \/var\/www\/>/,/<\/Directory>/ s/AllowOverride None/AllowOverride All/' /etc/apache2/apache2.conf
WORKDIR /var/www/html
# Copy application files
COPY . .
# Set permissions
RUN chown -R www-data:www-data /var/www/html
# Default port
ENV PORT=8080
EXPOSE 8080
CMD ["apache2-foreground"]Create a .dockerignore file:
.git
.gitignore
vendor
*.md
.DS_Store
.env
docker-compose.ymlCreate public/.htaccess for URL rewriting:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]
</IfModule>Test Locally
Run the built-in PHP development server:
php -S localhost:8000 -t publicOpen http://localhost:8000 in your browser. You should see the JSON response.
Test the health endpoint at http://localhost:8000/health.
Push to GitHub
Initialize a Git repository and push to GitHub:
git init
git add .
git commit -m "Initial commit"
git remote add origin [email protected]:YOUR_USERNAME/my-php-app.git
git branch -M main
git push -u origin mainReplace YOUR_USERNAME with your GitHub username.
Deploy on Out Plane
Step 1: Install GitHub App
- Go to console.outplane.com
- Navigate to Applications from the sidebar
- Click Deploy Application
- If prompted, click Install GitHub App
- Select which repositories Out Plane can access
- Click Install and you'll be redirected back
Step 2: Select Repository
- Find your repository in the list
- Click to select it
- Choose the branch to deploy (default:
main) - Set Root Directory to
/
Step 3: Configure Build
| Setting | Value |
|---|---|
| Build Method | Select Dockerfile |
| Application Name | Enter a unique name (e.g., my-php-app) |
| Port | 8080 |
Step 4: Select Resources
| Instance | vCPU | RAM | Recommended For |
|---|---|---|---|
| op-20 | 0.5 | 512 MB | Development, small sites |
| op-46 | 1 | 1 GB | Production sites |
| op-82 | 2 | 2 GB | High traffic |
Step 5: Configure Scaling
- Min Scale: Set to
1for always-on, or0for scale-to-zero - Max Scale: Set based on expected traffic
Step 6: Environment Variables (Optional)
Click Add Variable to add environment variables:
| Key | Value |
|---|---|
APP_ENV | production |
APP_DEBUG | false |
Step 7: Deploy
- Review your configuration
- Click Create Application
- Wait for the build to complete (typically 2-3 minutes)
Step 8: Access Your App
Once the deployment status shows Ready:
- Go to the application Overview tab
- Find your domain:
my-php-app.outplane.app - Click to open your live application
Using Laravel
For Laravel applications, use this optimized Dockerfile:
FROM php:8.3-apache AS base
# Install system dependencies
RUN apt-get update && apt-get install -y \
git \
curl \
libpng-dev \
libonig-dev \
libxml2-dev \
zip \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Enable Apache mod_rewrite
RUN a2enmod rewrite
# Set document root
ENV APACHE_DOCUMENT_ROOT /var/www/html/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
# Configure port
RUN sed -i 's/Listen 80/Listen ${PORT}/' /etc/apache2/ports.conf
RUN sed -i 's/:80/:${PORT}/' /etc/apache2/sites-available/000-default.conf
WORKDIR /var/www/html
# Copy composer files first for caching
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --no-autoloader
# Copy application
COPY . .
# Generate autoloader and optimize
RUN composer dump-autoload --optimize
RUN php artisan config:cache
RUN php artisan route:cache
RUN php artisan view:cache
# Set permissions
RUN chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
ENV PORT=8080
EXPOSE 8080
CMD ["apache2-foreground"]Laravel Environment Variables
Add these environment variables in Out Plane:
| Key | Value |
|---|---|
APP_KEY | Your Laravel app key |
APP_ENV | production |
APP_DEBUG | false |
DATABASE_URL | Your database connection string |
Adding a Database
Step 1: Create a Database
- Go to Databases in the sidebar
- Click Create Database
- Choose a name, PostgreSQL version, and region
- Click Create Database
Step 2: Get Connection String
- Click on your database
- In the Overview tab, find the connection details
- Note the host, port, database name, username, and password
Step 3: Install PostgreSQL Extension
Update your Dockerfile to include the PostgreSQL extension:
FROM php:8.3-apache
RUN apt-get update && apt-get install -y libpq-dev \
&& docker-php-ext-install pdo pdo_pgsql \
&& rm -rf /var/lib/apt/lists/*
# ... rest of DockerfileStep 4: Connect in PHP
<?php
$databaseUrl = getenv('DATABASE_URL');
if ($databaseUrl) {
$dbParts = parse_url($databaseUrl);
$host = $dbParts['host'];
$port = $dbParts['port'] ?? 5432;
$dbname = ltrim($dbParts['path'], '/');
$user = $dbParts['user'];
$password = $dbParts['pass'];
try {
$pdo = new PDO(
"pgsql:host=$host;port=$port;dbname=$dbname",
$user,
$password,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
die("Database connection failed: " . $e->getMessage());
}
}Step 5: Add Environment Variable
- Go to your application in Out Plane
- Click Settings → Environment
- Add
DATABASE_URLwith your connection string - Click Save and redeploy
Using Nginx Instead of Apache
If you prefer Nginx, use this Dockerfile:
FROM php:8.3-fpm-alpine
# Install nginx
RUN apk add --no-cache nginx
WORKDIR /var/www/html
COPY . .
# Create nginx config
RUN echo 'server { \
listen ${PORT}; \
root /var/www/html/public; \
index index.php; \
location / { \
try_files $uri $uri/ /index.php?$query_string; \
} \
location ~ \.php$ { \
fastcgi_pass 127.0.0.1:9000; \
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; \
include fastcgi_params; \
} \
}' > /etc/nginx/http.d/default.conf
# Create startup script
RUN echo '#!/bin/sh\nphp-fpm -D\nnginx -g "daemon off;"' > /start.sh && chmod +x /start.sh
ENV PORT=8080
EXPOSE 8080
CMD ["/start.sh"]Automatic Deployments
Push to your branch to trigger automatic deployments:
git add .
git commit -m "Add new feature"
git push origin mainNext Steps
Buildpack alternative: Instead of Dockerfile, select Buildpack and add a Procfile with: web: heroku-php-apache2 public/