AWS App Runner + PHP

7 min read

Ok… so I was just trying to read the docs but now I’ve decided to actually test AWS App Runner out but instead of using Python I’ll go with PHP (cos I love deviating from the norm apparently and I wrote PHP for years :))

I’ll be trying to follow the AWS APP Runner Getting Started Guide which is based on python; so will try to work out along the way to be PHP.

I already have a github and AWS account to try this out with.

The guide points me to additional pre-reqs:

The “Setting up for App Runner” page talks about using an IAM user for admin access. I use Azure AD federated access to my AWS accounts, so this could get interesting as I found out with AWS Amplify attempts recently.

Ok so checking these, I’ve basically done it all except the repo. So I’ve logged into github.com and created a new blank private repository calling it zens-apprunner-test and cloned it locally.

First Problem

I don’t want to use the example as its python. So yeah. What files should I be putting into the repository is my first hurdle to overcome.

Having been having a read of the docs already I know about this page: https://docs.aws.amazon.com/apprunner/latest/dg/service-source-code-php.html

This is great. this has the information I’m after. It also tells me cruicially that the way I structure my repo is based on a decision I have to make.

Should I use supervisord or a start up script when starting up Apache or NGINX.

Never heard of supervisord before in my life so clicking the link to read more takes me off the supervisorid.org documentation. After a quick skim read, its just another means to control process start up and stop using centralised config files. Not too shabby. not sure I need to be that sexy right now so will stick to a startup script.

From the docs:

Alright… file structure for repository located and created!

Under the section PHP Runtimes it gives me examples for the apprunner.yaml contents.

Read the “Complete PHP application source” section that you have to expand as it has all the files above, and their contents. It covers both start up methods as well as both web servers so be sure to get the right files for your use case. In my case I chose Apache + Startup Script.

Ok so I can return back to the user guide now and go to the next step Step 1: Create an App Runner service.

Logged into the console, went to the AWS App Runner Service and then clicked create new app runner service.

Selected Github repository as the source and the had to connect Github to AWS…

I’m using my Git Org as well so I was able to select this successfully when installing another app.

Second Problem

No branch in list!

Guessing this was because I hadn’t actually committed my local code to the repo so I decided to do a commit and push.. sure enough now I get master to select from.

I’m going with Manual for my release to save me on cash. Note: This deviates from the Getting Started Guide. Guess I’ll have to learn how to manually deploy.

Because we’re using an apprunner.yaml file in the next screen I get to select this option:

Otherwise I’d have to fill out a bit more info.

Next page has a lot of settings one can fill out but I’m just entering the service name zens-apprunner-test and going with defaults.

Problem Three

Bah this form also needs an IAM Role to be selected under security, and I don’t have any that meet the criteria so its a blank list to select from. Off to create the IAM role next.

Problem Four

PEBKAC. I got lost in trying to create an IAM Instance Role for the service…

It’s optional Paul.. Optional! (found here)

Clicking next and moving on to clicking create & deploy after wasting 10 mins on roles..

Deployment takes forever and by the 8 min mark I received

Problem Five

“App Runner event logs” shows: “09-17-2023 06:36:28 PM [AppRunner] Invalid start command. Update the start command you provided during the App Runner service configuration and re-try. – CannotStartContainerError: ResourceInitializationError: failed to create new container runtime task: failed to create shim task: failed to create task: rpc error: code = Unknown desc = OCI runtime create failed: runc create failed: unable to start container process: exec: “./startup.sh”: permission denied: unknown”

Ug. So much for copy and paste winning here.

Checking back to the page that talks about the php files needed I see this:

I’m on Windows! How do I do this and have this as part of a git repo?! :\

git update-index –chmod=+x startup.sh

Did this and then re-committed the repo to Github. Obviously now I need to kick off another rebuild and to do this I used the Console clicking the orange rebuild button on the top right 🙂

Worthy to note my federated access hasn’t been a hinderance here to date.

Time to wait another 8 mins or so.. Game of Rocket League to kill the time!

09-17-2023 06:51:24 PM [AppRunner] Performing health check on port '8080'.
09-17-2023 06:51:14 PM [AppRunner] Provisioning instances and deploying image for publicly accessible service.
09-17-2023 06:51:01 PM [AppRunner] Successfully built source code.
09-17-2023 06:49:39 PM [AppRunner] Starting source code build.
09-17-2023 06:49:38 PM [AppRunner] Successfully Validate configuration file.
09-17-2023 06:49:37 PM [AppRunner] Reading apprunner.yaml config file.
09-17-2023 06:49:10 PM [AppRunner] Successfully pulled source code.
09-17-2023 06:48:22 PM [AppRunner] Service status is set to OPERATION_IN_PROGRESS.
09-17-2023 06:36:48 PM [AppRunner] Deployment with ID : a76dc66c9fe74a74835b8f5db22052e1 failed.
09-17-2023 06:36:28 PM [AppRunner] Invalid start command. Update the start command you provided during the App Runner service configuration and re-try. - CannotStartContainerError: ResourceInitializationError: failed to create new container runtime task: failed to create shim task: failed to create task: rpc error: code = Unknown desc = OCI runtime create failed: runc create failed: unable to start container process: exec: "./startup.sh": permission denied: unknown
09-17-2023 06:34:21 PM [AppRunner] Performing health check on port '8080'.
09-17-2023 06:34:11 PM [AppRunner] Provisioning instances and deploying image for publicly accessible service.
09-17-2023 06:33:58 PM [AppRunner] Successfully built source code.
09-17-2023 06:32:36 PM [AppRunner] Starting source code build.
09-17-2023 06:32:35 PM [AppRunner] Successfully Validate configuration file.
09-17-2023 06:32:34 PM [AppRunner] Reading apprunner.yaml config file.
09-17-2023 06:32:07 PM [AppRunner] Successfully pulled source code.
09-17-2023 06:31:11 PM [AppRunner] Deployment Artifact :- Repo Type: Source; Repository: https://github.com/dunlop-geek-nz/zens-apprunner-test; Branch : master
09-17-2023 06:31:10 PM [AppRunner] Deployment with ID : a76dc66c9fe74a74835b8f5db22052e1 started. Triggering event : SERVICE_CREATE

Still having an issue on startup with permissions.. joy of joys.

Updated the apprunner.yaml to include the chmod in the build phase and when clicking on the rebuild button I note it says this:

So, question, does the rebuild pull down the latest code or did it cache it somewhere? i.e. Did my 2nd run not pull down the +x change and hence I’ve just failed twice on the same old code repo..

Reading the Rebuilding a failed apprunner service doc I find that there are two update modes. One with config and source changes and one without. So clearly the UI doesn’t seem to think I’ve updated the source code.

So I went to the Configuration tab, edited the config, refreshed the branch and then click Save and Rebuild just to be sure that the repo changes would be picked up.

Third times a charm right?

Well no, apparently even though its indented visually correctly it isn’t the right character used for linux to process the YAML properly. I mean seriously. common.

09-17-2023 07:19:31 PM [AppRunner] Your application stopped or failed to start. See logs for more information.  Container exit code: 1
09-17-2023 07:16:33 PM [AppRunner] Performing health check on port '8080'.
09-17-2023 07:16:23 PM [AppRunner] Provisioning instances and deploying image for publicly accessible service.
09-17-2023 07:16:12 PM [AppRunner] Successfully built source code.
09-17-2023 07:14:49 PM [AppRunner] Starting source code build.
09-17-2023 07:14:48 PM [AppRunner] Successfully Validate configuration file.
09-17-2023 07:14:47 PM [AppRunner] Reading apprunner.yaml config file.
09-17-2023 07:14:20 PM [AppRunner] Successfully pulled source code.
09-17-2023 07:13:25 PM [AppRunner] Service status is set to OPERATION_IN_PROGRESS.

Fun!

09-17-2023 07:17:00 PM exec ./startup.sh: no such file or directory

OMG.. checking github shows the file there and it is set to executable. hmmmm what is going on.

switched to entering a config rather than using a build file in the repo and tried again.

did it again! :\

switched to supervisord….

of course that worked….

Success. I have a Hello World PHP App hosted on AWS App Runner! 🙂

Files Used:

supervisord.conf

[supervisord]
nodaemon=true

[program:nginx]
command=nginx -g "daemon off;"
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

[program:php-fpm]
command=php-fpm -F
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

public/index.php

<html>
<head> <title>First PHP App</title> </head>
<body>
<?php
    print("Hello World!");
    print("<br>");
?>
</body>
</html>

apprunner.yaml

version: 1.0
runtime: php81
build:
  commands:
    build:
      - PYTHON=python2 amazon-linux-extras install epel
      - yum -y install supervisor
run:
  command: supervisord
  network:
    port: 8080
    env: APP_PORT