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"]
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
Top comments (1)
Thanks for sharing! very useful !!