Skip to main content

How to deploy CakePHP to Fly.io

Start by copying the below Docker file template and make modifications. This guide is setup to use CakePHP 5 by default and assumes you are using a production database hosted separately from your cake server.

Deployment Architecture

Here's how your CakePHP application will be deployed on Fly.io:

graph TB
    subgraph "Development"
        Dev[Your Local CakePHP App]
        Git[Git Repository]
    end
    
    subgraph "Fly.io Platform"
        Proxy[Fly Proxy<br/>HTTPS Termination]
        
        subgraph "Docker Container"
            Apache[Apache Web Server<br/>Port 8080]
            PHP[PHP 8.1 + CakePHP 5]
            App[Your Application Code]
        end
        
        subgraph "External Services"
            DB[(Production Database<br/>MySQL/PostgreSQL)]
            S3[File Storage<br/>AWS S3]
        end
    end
    
    subgraph "Users"
        Browser[Web Browsers]
        API[API Clients]
    end
    
    Dev -->|Push Code| Git
    Git -->|Build Image| Apache
    Browser & API -->|HTTPS Requests| Proxy
    Proxy -->|Port 8080| Apache
    Apache <--> PHP
    PHP <--> App
    App <-->|Database Queries| DB
    App <-->|File Operations| S3
    
    style Apache fill:#FFE4B5
    style DB fill:#90EE90
    style Proxy fill:#87CEEB

Dockerfile Template

FROM ubuntu:22.04

# Install packages and PHP 8.1
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update -q
RUN apt-get install -qqy git-core composer libapache2-mod-php php-intl \
    php-mbstring php-zip php-xml php-codesniffer php-mysql php-pdo-sqlite \
    php-imagick php-curl

# Delete all the apt list files since they're big and get stale quickly
RUN rm -rf /var/lib/apt/lists/*

# Add apache config to enable .htaccess and do some stuff you want
COPY apache_default /etc/apache2/sites-available/000-default.conf
RUN sed -i -e "s/Listen 80/Listen 8080/" /etc/apache2/ports.conf
RUN sed -i -e "s/zend.assertions = -1/zend.assertions = 1/" /etc/php/8.1/apache2/php.ini
RUN sed -i -e "s/upload_max_filesize = 2M/upload_max_filesize = 20M/" /etc/php/8.1/apache2/php.ini
RUN sed -i -e "s/post_max_size = 8M/post_max_size = 20M/" /etc/php/8.1/apache2/php.ini

# Enable mod rewrite and listen to localhost
RUN a2enmod rewrite
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf

################################################################
# Deploy Cake3 app from source                                  #
################################################################

# Clone the application
RUN rm -rf /var/www/html
RUN git clone --depth=1 https://[GIT REPO YOU WANT TO USE].git /var/www/html

# Copy local app config and disable debug
COPY config/app_local.php /var/www/html/config/app_local.php
RUN sed -i -e "s/'DEBUG', true/'DEBUG', false/" /var/www/html/config/app_local.php

# Set workdir (no more cd from now)
WORKDIR /var/www/html

# Composer install dependencies
RUN composer -n install
RUN composer upgrade dumpautoload -o

# Set write permissions for webserver
RUN rm -rf tmp && rm -rf logs && mkdir tmp && mkdir logs
RUN chgrp -R www-data logs tmp
RUN chmod -R g+rw logs tmp

####################################################
# Expose port and run Apache webserver             #
####################################################

EXPOSE 8080
CMD ["/usr/sbin/apache2ctl", "-DFOREGROUND"]

Areas to modify

  1. This example uses Ubuntu 22.04
  2. Feel free to remove or add php extensions where it says apt get.
  3. Replace the git repo usr with your CakePHP git repo
  4. It copies your local app_local.php config and changes it from debug mode for production

Default apache configruation file

Feel free to change the default apache configuration file to what ever custom requirements you may have.

<VirtualHost *:8080>
        ServerAdmin webmaster@localhost

        DocumentRoot /var/www/html
        <Directory />
                Options FollowSymLinks
                AllowOverride None
        </Directory>
        <Directory /var/www/html>
                Options Indexes FollowSymLinks MultiViews
                # To make .htaccess work
                AllowOverride FileInfo
                Order allow,deny
                allow from all
        </Directory>

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        <Directory "/usr/lib/cgi-bin">
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        </Directory>

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel debug

        CustomLog ${APACHE_LOG_DIR}/access.log combined

	#
	# Set HTTPS environment variable if we came in over secure
	#  channel.
	SetEnvIf x-forwarded-proto https HTTPS=on

</VirtualHost>

Set up Fly.io

Run through the normal flyctl setup process and then deploy the docker image with the following commands. We assume that you have already set up flyctl and are authenticated.

fly launch

It should recognize the Docker file in the directory and set it up as a Docker deployment.

flyctl deploy --no-cache

It should only take a couple minutes to deploy depending on the size of your repo and that is it!

If you want to set up a custom domain, that can be done directly through flyct as well within minutes.

This setup gets you a scalable production ready CakePHP deployment.

Need help with your project or have questions?

We specialize in AI automation, custom integrations, and intelligent workflows tailored to your business needs.

Whether you need help deploying, building, implementing, or creating a solution - or just want expert guidance on your project - we're here to help.

Contact us today to discuss your project.