Migrate a Symfony app from heroku to Fly.io

thomas_ph35

Thomas

Posted on December 21, 2022

Migrate a Symfony app from heroku to Fly.io

A few days ago I noticed that one of my side projects hosted on Heroku was not running anymore.

The reason : No more free tier...

It was time to find an alternative to host my app for free.

Why Fly ?

There is not reason for that choice beside the fact that it manage to host my app for free.

Versions

My app is a Symfony 5.3 API, running with PHP 7.4

Dockerfile

Fly.io does have an integration for laravel but none for Symfony.
I had to find/create a Dockerfile.

I found some great ressources but none of them worked out of the box.

looking at this repo helped me : https://github.com/fly-apps/fly-hello-laravel/blob/main/Dockerfile

This is my edited Dockerfile

FROM alpine:3.14

LABEL fly_launch_runtime="Symfony"

RUN apk update

# add useful utilities
RUN apk add curl \
    zip \
    unzip \
    ssmtp \
    tzdata \
    openssl

# php, with assorted extensions we likely need
RUN apk add --no-cache --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ --allow-untrusted gnu-libiconv \
    && apk add -U --no-cache \
    # Packages
    tini \
    php7 \
    php7-amqp \
    php7-dev \
    php7-common \
    php7-apcu \
    php7-gd \
    php7-xmlreader \
    php7-bcmath \
    php7-ctype \
    php7-curl \
    php7-exif \
    php7-iconv \
    php7-intl \
    php7-json \
    php7-mbstring \
    php7-opcache \
    php7-openssl \
    php7-pcntl \
    php7-pdo \
    php7-mysqlnd \
    php7-pdo_mysql \
    php7-pdo_pgsql \
    php7-phar \
    php7-posix \
    php7-session \
    php7-xml \
    php7-xsl \
    php7-zip \
    php7-zlib \
    php7-dom \
    php7-redis \
    php7-fpm \
    php7-sodium \
    php7-tokenizer

# supervisor, to support running multiple processes in a single app
RUN apk add supervisor

# nginx (https://wiki.alpinelinux.org/wiki/Nginx)
RUN apk add nginx
# ... with custom conf
RUN cp /etc/nginx/nginx.conf /etc/nginx/nginx.old.conf && rm -rf /etc/nginx/http.d/default.conf

# htop, which is useful if need to SSH in to the vm
RUN apk add htop

# composer, to install Laravel's dependencies
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# add users (see https://www.getpagespeed.com/server-setup/nginx-and-php-fpm-what-my-permissions-should-be)
# 1. a user for the app and php-fpm to interact with it (execute)
RUN adduser -D -u 1000 -g 'app' app
# 2. a user for nginx is not needed because already have one
# ... and add the nginx user TO the app group else it won't have permission to access web files (as can see in /var/log/nginx/error.log)
RUN addgroup nginx app

# use a socket not port for php-fpm so php-fpm needs permission to write to thay folder (make sure the same .sock is in nginx.conf and in php-fpm's app.conf)
RUN mkdir /var/run/php && chown -R app:app /var/run/php

# working directory
RUN mkdir /var/www/html
WORKDIR /var/www/html

# copy app code across, skipping files based on .dockerignore
COPY . /var/www/html
# ... install Laravel dependencies
RUN composer install
# ... and make all files owned by app, including the just added /vendor
RUN chown -R app:app /var/www/html

# move the docker-related conf files out of the app folder to where on the vm they need to be
RUN rm -rf /etc/php7/php-fpm.conf
RUN rm -rf /etc/php7/php-fpm.d/www.conf
RUN mv docker/supervisor.conf /etc/supervisord.conf
RUN mv docker/nginx.conf /etc/nginx/nginx.conf
RUN mv docker/php.ini /etc/php7/conf.d/php.ini
RUN mv docker/php-fpm.conf /etc/php7/php-fpm.conf
RUN mv docker/app.conf /etc/php7/php-fpm.d/app.conf

# make sure can execute php files (since php-fpm runs as app, it needs permission e.g for /storage/framework/views for caching views)
RUN chmod -R 755 /var/www/html

# the same port nginx.conf is set to listen on and fly.toml references (standard is 8080)
EXPOSE 8080

# off we go (since no docker-compose, keep both nginx and php-fpm running in the same container by using supervisor) ...
ENTRYPOINT ["supervisord", "-c", "/etc/supervisord.conf"]
Enter fullscreen mode Exit fullscreen mode

I you want php8, just replace php7 with php8. (docker's magic)

I made a git repo if you want to browse the files of my 'docker' folder.

Databse

My database is hosted on a tinny VPS, so I didn't had to do anything.

If you want to host your db on fly, they offer free 3GB
postgres.

Alternative

I didn't tried Fly : turboku launcher, but it may be a simpler way to migrate.

see : https://fly.io/launch/heroku

With dockerfile your a not tied to a particular host, and can migrate smoothly between them.

Conclusion

If you are looking to migrate your Heroku app, save yourself a couple of hours and take a look at my repo : https://github.com/Thomas-Philippot/symfony-fly-starter

💖 💪 🙅 🚩
thomas_ph35
Thomas

Posted on December 21, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related