早上好
目前我有一个通过 ElasticBeanstalk 基础设施在 AWS 中运行的应用程序,该应用程序是使用 Laravel 10 工具制作的,并使用 nginx 作为服务器。
我的任务是使用 AWS ECS 将这个 EB 应用程序转变为 docker 解决方案,我已经开发了几种不同的映像和不同的系统实现方式,但我已经达到了每次尝试登录系统时都会出现问题的程度。出现错误 419,该错误与 CRSF Token 直接相关。为了继续我的测试,我将登录页面添加到了这个 CSRF 令牌的例外中,从此以后,每次我尝试登录我的系统时,它都会再次循环到登录页面。
Login done > http://localhost:8000/dashboard > http://localhost:8000/login > http://localhost:8000/
由于我专门处理基础设施,并且没有参与项目的初始创建,因此我不知道要提供哪些信息,但我可以传递我更改的内容以访问我的登录页面。我目前进行了以下测试:
我测试了在两个不同的容器中运行应用程序,一个用于应用程序本身,另一个用于 nginx,这是最推荐的做法;
我测试了设置一个容器,将应用程序和 nginx 放在同一个容器中,这不是生产的最佳选择,而是用于测试目的;
我使用本地计算机上运行的数据库进行本地测试,因此在我的计算机上完成的测试在 docker-compose 中具有“主机”配置,当我在 ECS 环境中测试时,我使用来自我的 VPC 的端点
由于我正在改编最初为ElasticBeanstalk开发的项目,Nginx部分非常简单,许多必要的事情都由EB自动化了
为了更简单,我将告诉您我是如何使用 1 个容器的概念来做到这一点的,因为在所有方法中我都达到了相同的点:
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 撰写:
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 文件:
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;
}
}
如果我缺少您需要的更多详细信息,请告诉我,因为我不太了解 PHP/Laravel 部分。
虽然这更像是一个合格的猜测,而不是我可以在你的情况下测试的东西,但这可能是因为你的 Nginx 配置,特别是 HTTPS 重定向。
添加 HTTPS 证书时,您应该删除该配置并让 Application Load Balancer(ECS AWS 服务的一部分)处理流量代理。
我还建议跳过 Nginx 并直接使用 Laravel Octane 之类的东西(或者甚至只是简单地使用 FrankenPHP (也通过 Laravel Octane 支持)。
使用 FrankenPHP,您可以将 Laravel 应用程序的 Dockerfile 精简为如下内容:
FROM dunglas/frankenphp as build
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV SERVER_NAME=http://
RUN install-php-extensions redis intl pdo_pgsql pgsql @composer
FROM build as app
WORKDIR /app
COPY . /app
RUN composer install
这将为您制作单个图像,您可以使用它在 ECS 中轻松执行自动缩放和单个图像任务。