Laravel Docker Centos8 使用

fanyi 这个小工具,以前是直接跑在腾讯云的轻量服务器上的,用 Golang 写的,最近加了一个小功能,用 php 重写了,php 就要搭建各种环境,直接在腾讯云的轻量服务器上编译 php 不成功,主要是你 cpu 高,他就直接给你 kill 了,所以就用 docker 来解决。

构建 PHP 的运行环境

从 php:8.1-fpm 开始构建,安装上相关依赖,然后设置运行用户的相关权限。

vim Dockerfile
FROM php:8.1-fpm

# Arguments defined in docker-compose.yml
ARG user
ARG uid

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# 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/www

USER $user

编排文件

把 PHP,nginx,mysql 8.0 编排在一起。

vim docker-compose.yml
version: "3.7"
services:
  app:
    build:
      args:
        user: lighthouse
        uid: 1000
      context: ./
      dockerfile: Dockerfile
    image: travellist
    container_name: travellist-app
    restart: unless-stopped
    working_dir: /var/www/
    volumes:
      - ./:/var/www
    networks:
      - travellist

  db:
    image: mysql:8.0
    container_name: travellist-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./mysql/:/var/lib/mysql
    networks:
      - travellist

  nginx:
    image: nginx:alpine
    container_name: travellist-nginx
    restart: unless-stopped
    ports:
      - 8000:80
    volumes:
      - ./:/var/www
      - ./docker-compose/nginx:/etc/nginx/conf.d/
    networks:
      - travellist

networks:
  travellist:
    driver: bridge

权限的问题,如果 php 没有写的权限,一定是 user: lighthouse, uid: 1000
设置的不对,这个 user 必须在系统中存在,且 uid 一定要对。

Nginx 配置

容器里面的 nginx 需要把请求转发给 php-fpm

vim vim docker-compose/nginx/travellist.conf
server {
    listen 80;
    index index.php index.html;
    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/public;
    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass app: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 / {
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
}

负载 nginx 配置

为什么要加这个 nginx,其实也可以不加,主要是这个机器上我还跑了另外几个服务,所以才共用这个 负载 nginx。

 server {

        server_name  fanyi1.qishiya.com;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
                proxy_pass http://127.0.0.1:8000;
                proxy_set_header X-Forward-For $remote_addr;
                proxy_set_header Host  fanyi1.qishiya.com;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header  X-Appengine-Remote-Addr $remote_addr;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }




    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/fanyi.qishiya.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/fanyi.qishiya.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

在负载的 nginx,不加 host 的话,取不到 host,默认的资源依赖都变成 127.0.0.1

proxy_set_header Host  fanyi1.qishiya.com; 

Laravel 配置

一定要配置 APP_URL 和 ASSET_URL,不然取的资源的域名不对。

APP_URL=https://fanyi1.qishiya.com
ASSET_URL=https://fanyi1.qishiya.com

强制 https,laravel 在前端模板调用 {{ router(‘login’) }} 之类的指令时,默认是 http,修改如下代码,可以强制 https

namespace App\Providers;

use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        URL::forceScheme('https');
    }
}

laravel 初始化

服务跑起来后,需要对环境进行初始化。

docker compose exec app composer install

docker compose exec app php artisan key:generate

docker compose exec app php artisan migrate --force

参考

https://stackoverflow.com/questions/28402726/laravel-5-redirect-to-https

nginx-and-lets-encrypt-with-docker

发表评论