Skip to main content
Version: CANARY 🚧

Installing BowPHP

Introduction​

BowPHP is a modern and elegant PHP micro-framework. Before creating your first application, make sure your environment meets the following requirements.

System requirements​

  • PHP >= 8.2
  • OpenSSL PHP Extension
  • PDO PHP Extension
  • Mbstring PHP Extension
  • XML PHP Extension
  • JSON PHP Extension
Development environments

If you use Laragon (Windows), XAMPP, or MAMP, these extensions are usually already installed and configured.

Creating a project​

BowPHP uses Composer to manage its dependencies. Make sure Composer is installed on your machine before continuing.

Installation via Composer​

composer create-project --prefer-dist bowphp/app nom-du-projet
Installing Composer

We recommend installing Composer globally on your machine. Check the official documentation for installation instructions.

If you're new to Composer, take the time to go through its documentation to understand how it works.

asciicast

Starting your project​

Go to the root of your project and start the development server:

cd nom-du-projet
php bow run:server --port=8080 --host=0.0.0.0

Open your browser and go to http://localhost:8080.

Default port

If you don't specify a port, the server starts on port 5000 by default:

php bow run:server
# Accessible at http://localhost:5000

Configuration​

Public folder​

After installation, configure your web server's document root to point to the public folder.

The index.php file located in this folder serves as the single entry point for all HTTP requests (the Front Controller pattern).

Configuration files​

All of BowPHP's configuration files are located in the config folder. Each option is documented to make it easy to customize your application.

Structure of the config folder:

  • app.php: Application configuration
  • database.php: Database configuration
  • mail.php: Email sending configuration
  • And many more...

Folder permissions​

The folders contained in var must have write permissions for the web server:

# On Linux/macOS
chmod -R 775 var/
chown -R www-data:www-data var/
Important

Make sure the web server has write permissions on the var folder so that logs, cache, and sessions work correctly.

Web server configuration​

Apache​

Bow includes a public/.htaccess file that handles URL rewriting to the front controller.

Requirement: The mod_rewrite module must be enabled.

# Enable mod_rewrite on Ubuntu/Debian
sudo a2enmod rewrite
sudo systemctl restart apache2

If the default .htaccess file doesn't work, try this alternative configuration:

Options +FollowSymLinks
RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

Nginx​

For Nginx, add this configuration to your site file:

/etc/nginx/sites-available/bow-app
server {
listen 80;
server_name example.com www.example.com;
root /var/www/bow-app/public;
index index.php;

# Logs
access_log /var/log/nginx/bow-app.access.log;
error_log /var/log/nginx/bow-app.error.log;

# Security - Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;

# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/json application/xml;

# Front Controller
location / {
try_files $uri $uri/ /index.php?$query_string;
}

# PHP-FPM
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}

# Static assets cache
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}

# Block access to sensitive files
location ~ /\.(env|git|htaccess) {
deny all;
}

location ~ ^/(var|vendor|config|migrations|seeders)/ {
deny all;
}
}

Nginx with SSL (HTTPS)​

/etc/nginx/sites-available/bow-app-ssl
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/bow-app/public;
index index.php;

# SSL certificates (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_stapling on;
ssl_stapling_verify on;

# Security headers
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}

location ~ /\.(env|git|htaccess) {
deny all;
}
}

Enabling the Nginx site​

# Create the symbolic link
sudo ln -s /etc/nginx/sites-available/bow-app /etc/nginx/sites-enabled/

# Test the configuration
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Docker​

To develop with Docker, create the following files at the root of the project:

Dockerfile
FROM php:8.2-fpm-alpine

# PHP extensions
RUN apk add --no-cache \
libpng-dev libjpeg-turbo-dev freetype-dev \
oniguruma-dev libxml2-dev zip unzip git curl \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install pdo pdo_mysql mbstring xml gd opcache

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

WORKDIR /var/www/html

COPY . .

RUN composer install --no-dev --optimize-autoloader \
&& chown -R www-data:www-data var/

EXPOSE 9000

CMD ["php-fpm"]
docker-compose.yml
services:
app:
build: .
volumes:
- .:/var/www/html
- ./var:/var/www/html/var
depends_on:
- mysql
- redis
networks:
- bow-network

nginx:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- .:/var/www/html
- ./docker/nginx.conf:/etc/nginx/conf.d/default.conf
depends_on:
- app
networks:
- bow-network

mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: bow_app
MYSQL_USER: bow
MYSQL_PASSWORD: secret
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
networks:
- bow-network

redis:
image: redis:alpine
ports:
- "6379:6379"
networks:
- bow-network

networks:
bow-network:
driver: bridge

volumes:
mysql-data:
docker/nginx.conf
server {
listen 80;
root /var/www/html/public;
index index.php;

location / {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
}
}
# Start the containers
docker-compose up -d

# Access the application
# http://localhost:8080

Deploying on shared hosting​

To deploy BowPHP on shared hosting:

  1. Move the index.php and .htaccess files from the public folder to the root of the project
  2. Update the paths in index.php so that they correctly point to the framework folders
  3. Use the following .htaccess configuration:
Options -indexes
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
</IfModule>

<Files ".env.*|server.php|bow|app/**|vendor/**|postman/*|var/**|seeders/*|templates/**|tests/**|migrations/**">
Order Allow,Deny
Deny from all
</Files>
Managing assets

For shared hosting, use the app_assets() helper for your static files and change the value of APP_ASSET_PREFIX to /public in your .env.json file. Bow will automatically handle the correct paths!

Next steps​

Now that your installation is complete, learn how to build your application:

Is something missing?

If you run into problems with the documentation or have suggestions to improve the documentation or the project in general, please open an issue for us, or send a tweet mentioning the Twitter account @bowframework or directly on github.