Good morning
Currently I have an application running within AWS through the ElasticBeanstalk infrastructure, this application is made with the Laravel 10 tool and has nginx as a server.
My mission is to transform this EB application into a docker solution using AWS ECS, I have already developed several different images and different ways of implementing the system, but I have reached a point where every time I try to log into my system, it presents a error 419, which is directly related to the CRSF Token. To continue my tests, I added the login page to the exception of this CSRF Token, and from that, every time I try to log into my system it loops to the login page again.
Login done > http://localhost:8000/dashboard > http://localhost:8000/login > http://localhost:8000/
As I work exclusively with infrastructure and did not participate in the initial creation of the project, I don’t know exactly what information to provide, but I can pass on what I changed to get to my login page. I currently have the following tests carried out:
-
I tested running the application in two different containers, one for the application itself and the other for nginx, which is the most recommended thing to do;
-
I tested setting up a single container that has the application and nginx in the same container, not being the best option for production but made for testing purposes;
-
I test locally with a database running on my local machine, so the tests done on my machine have the ‘host’ configuration within docker-compose, when I test within the ECS environment I use an endpoint from my VPC
As I am adapting a project initially developed for ElasticBeanstalk, the Nginx part is very simple, many of the necessary things were automated by EB
To be simpler, I’ll tell you how I’m doing it using the concept of just 1 container, since in all the methods I reached the same point:
Dockerfile:
FROM php:8.1-fpm
# set your user name, ex: user=bernardo
ARG USER=laravel
ARG PASS=laravel
ARG uid=1000
RUN useradd -m -s /bin/bash $USER && echo "$USER:$PASS" | chpasswd
ARG COMPOSER_ALLOW_SUPERUSER=1
ENV DEBIAN_FRONTEND noninteractive
# Install Programs
RUN apt-get update
&& apt-get install -y curl
libpng-dev
libonig-dev
libxml2-dev
wget
curl
gnupg2
software-properties-common
apt-transport-https
ca-certificates
lsb-release
zip
unzip
nodejs
npm
redis
nano
nginx
inetutils-ping
libicu-dev
zlib1g-dev
libzip-dev
libcurl4-openssl-dev
# PHP_CPPFLAGS are used by the docker-php-ext-* scripts
ENV PHP_CPPFLAGS="$PHP_CPPFLAGS -std=c++11"
RUN docker-php-ext-install xml gd mbstring zip curl mysqli soap bcmath exif pdo pdo_mysql
RUN pecl install mongodb && docker-php-ext-enable mongodb
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Get latest Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Create system user to run Composer and Artisan Commands
#RUN useradd -G www-data,root -u $uid -d /home/$USER $USER
RUN mkdir -p /home/$USER/.composer &&
chown -R $USER:$USER /home/$USER
# Set working directory
WORKDIR /var/app/current
# Copies the .env file into the container
COPY .env.example .env
# COPY .env.dev .env
# Copy Laravel application files
COPY . /var/app/current
# Copy custom configurations PHP
COPY docker/php/custom.ini /etc/php/conf.d/custom.ini
COPY docker/nginx/laravel.conf /etc/nginx/conf.d/laravel.conf
COPY entrypoint.sh /etc/entrypoint.sh
# Runs composer install and npm install to start the project
RUN composer install && npm install
RUN touch /var/app/current/storage/logs/laravel.log
RUN chmod -R gu+w storage/
RUN chmod -R guo+w storage/
RUN chmod -R 777 bootstrap/cache/
RUN chown ${USER}:${USER} -R ./storage
RUN chmod +x /etc/entrypoint.sh
# Switches to user Laravel
USER $user
EXPOSE 9000
EXPOSE 8000
# EXPOSE 80
EXPOSE 3306
ENTRYPOINT ["/etc/entrypoint.sh"]
Docker-compose:
version: "3.7"
services:
laravel-solo:
stdin_open: true
tty: true
container_name: app
ports:
- 8000:8000
network_mode: host
image: laravel-solo
volumes:
- ./:/var/app/current
- ./docker/nginx/laravel.conf:/etc/nginx/sites-enabled/default
- ./docker/nginx/laravel.conf:/etc/nginx/conf.d/laravel.conf
.conf file:
server {
listen 8000;
listen [::]:8000;
server_name localhost;
root /var/app/current/public;
index index.php;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains; preload" always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1;mode=block" always;
client_max_body_size 100M;
# Redirect to HTTPS
if ($http_x_forwarded_proto = "http") {
return 301 https://$host$request_uri;
}
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
gzip_static on;
}
# location = /favicon.ico { access_log off; log_not_found off; }
# location = /robots.txt { access_log off; log_not_found off; }
error_page 404 /index.php;
location ~ .php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass localhost:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~ /.(?!well-known).* {
deny all;
}
}
If I’m missing any more details that you need, please let me know, as I don’t know the PHP/Laravel part very well.
2
Answers
Just a quick update on my problem:
I decided to take a step back and recreate my Dockerfile once more, and i found this image: wyveo/nginx-php-fpm.
I used it to create my environment and i was not only able to surpass the looping error but also shrink significantly my docker image. This image gave me a complete environment with Nginx and PHP-FPM that are already set up for Laravel projects. It also facilitate to upload to ECS, since it hasn't many layers of complexicity anymore like volumes, etc..
Here's the DockerFile image:
This image has by default the
/usr/share/nginx
directory as root, but you're able to change it for anoter one with no problems, you just need to adapt a custom .conf file and upload it like i did on the DockerfileMy default.conf file
While this is more a qualified guess, than something I can test in your case, it’s probably because of your Nginx configuration, specifically the HTTPS redirection.
You should remove that configuration and let the Application Load Balancer (a part of the ECS AWS service) handle the traffic proxying, when adding a HTTPS certificate.
I would also recommend skipping Nginx and go directly to something like Laravel Octane (or even just simply go with FrankenPHP (also supported via Laravel Octane).
With FrankenPHP, you could shave your Laravel application’s Dockerfile to something like:
This will make a single image for you, that you can use for easy autoscaling and single image tasks in ECS.