feat: update

This commit is contained in:
tiennm99 committed 2025-03-25 22:04:48 +07:00
1 parent d1b1654cff
commit 7a63d20424
8 files changed
+348 -122

No files matched your search

+26
View File
@@ -0,0 +1,26 @@
# Application
APP_NAME=TastyIgniter
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://your-domain.com
# TastyIgniter specific
IGNITER_LOCATION_MODE=multiple
IGNITER_CARTE_KEY=
# Database
DB_DATABASE=tastyigniter
DB_USERNAME=tastyigniter
DB_PASSWORD=your_secure_password
DB_PREFIX=ti_
MYSQL_ROOT_PASSWORD=your_secure_root_password
# Mail
MAIL_MAILER=log
MAIL_FROM_ADDRESS=noreply@your-domain.com
MAIL_FROM_NAME=TastyIgniter
# Deployment
PORT=80
STACK_NAME=tastyigniter
+12 -2
View File
@@ -12,11 +12,16 @@ RUN apt-get update && apt-get install -y \
zip \
unzip \
default-mysql-client \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng-dev \
libwebp-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# Install PHP extensions
RUN docker-php-ext-install \
RUN docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp \
&& docker-php-ext-install \
pdo_mysql \
mbstring \
exif \
@@ -27,7 +32,8 @@ RUN docker-php-ext-install \
xml \
intl \
ctype \
tokenizer
tokenizer \
opcache
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
@@ -47,6 +53,10 @@ RUN mkdir -p /var/www/html/storage && \
chown -R www-data:www-data /var/www/html && \
chmod -R 755 /var/www/html
# Configure PHP
COPY docker/php/php.ini /usr/local/etc/php/conf.d/custom.ini
COPY docker/php/www.conf /usr/local/etc/php-fpm.d/www.conf
# Entrypoint script
ENTRYPOINT ["entrypoint.sh"]
+97 -71
View File
@@ -1,104 +1,130 @@
# TastyIgniter Docker Setup
# TastyIgniter Docker Compose
This repository contains Docker configuration files to quickly set up a TastyIgniter v4.0+ environment. The setup includes:
This repository contains a Docker Compose setup for TastyIgniter, making it easy to deploy on Coolify or any other Docker-compatible platform.
- PHP 8.3 with all required extensions
- MySQL 8 database
## Features
- PHP 8.3 with FPM
- Nginx web server
- Automated installation process
- Properly configured scheduler and queue workers
- MySQL 8 database
- Queue worker for background jobs
- Cron job for scheduled tasks
- Persistent volumes for data storage
- Health checks for all services
- Environment variable configuration
## Prerequisites
- Docker and Docker Compose installed on your system
- Basic understanding of Docker concepts
- Docker
- Docker Compose
- Coolify (for deployment)
## Directory Structure
```
tastyigniter-docker/
├── docker/
│ ├── entrypoint.sh
│ └── nginx/
│ └── default.conf
├── docker-compose.yml
├── Dockerfile
└── README.md
```
## Setup Instructions
1. Create the directory structure as shown above:
## Quick Start
1. Clone this repository:
```bash
mkdir -p tastyigniter-docker/docker/nginx
git clone https://github.com/yourusername/tastyigniter-docker-compose.git
cd tastyigniter-docker-compose
```
2. Copy all the configuration files into their respective directories.
2. Copy the example environment file:
```bash
cp .env.example .env
```
3. Start the Docker environment:
3. Edit the `.env` file with your configuration:
```bash
nano .env
```
4. Start the containers:
```bash
cd tastyigniter-docker
docker-compose up -d
```
4. The setup will:
- Create a new TastyIgniter project
- Set up the database connection
- Run the non-interactive installation
- Configure the proper permissions
- Set up scheduled tasks and queue processing
## Deployment on Coolify
5. Access TastyIgniter:
- Frontend: http://localhost
- Admin panel: http://localhost/admin
- Default admin credentials:
- Username: admin
- Email: admin@example.com
- Password: admin123
1. Push this repository to your Git provider (GitHub, GitLab, etc.)
## Configuration Options
2. In Coolify:
- Create a new service
- Select "Docker Compose" as the deployment method
- Connect your Git repository
- Set the following environment variables from the `.env.example` file
- Deploy the service
You can customize the installation by modifying the environment variables in the `docker-compose.yml` file:
### Required Environment Variables
- `APP_URL`: Your application URL
- `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`: Database connection details
- `ADMIN_USER`, `ADMIN_EMAIL`, `ADMIN_PASSWORD`: Administrator account details
Make sure to set these environment variables in Coolify:
## Persistent Storage
- `APP_KEY`: Generate a random 32-character string
- `APP_URL`: Your domain name
- `DB_PASSWORD`: Secure database password
- `MYSQL_ROOT_PASSWORD`: Secure root password
- `IGNITER_CARTE_KEY`: Your TastyIgniter Carte key (if using)
The setup uses Docker volumes for:
- MySQL data: Stored in the `dbdata` volume
- TastyIgniter storage: Mapped to the `./storage` directory on your host
### Volume Management
## Production Deployment
The following volumes are automatically managed by Coolify:
- `dbdata`: MySQL database data
- `tastyigniter`: Application files
- `tastyigniter-storage`: Application storage
Before deploying to production, make sure to:
### Health Checks
1. Change all default passwords
2. Set `APP_DEBUG=false`
3. Generate a unique `APP_KEY`
4. Configure proper SSL/TLS in the Nginx configuration for HTTPS
The deployment includes health checks for:
- Application container (PHP-FPM)
- Nginx web server
- MySQL database
## Development
To run in development mode:
1. Set `APP_ENV=local` in your `.env` file
2. Set `APP_DEBUG=true` in your `.env` file
3. Run `docker-compose up -d`
## Maintenance
### Database Backup
To backup the database:
```bash
docker-compose exec db mysqldump -u root -p tastyigniter > backup.sql
```
### Logs
View logs for all services:
```bash
docker-compose logs -f
```
View logs for a specific service:
```bash
docker-compose logs -f app
docker-compose logs -f nginx
docker-compose logs -f db
```
## Troubleshooting
If you encounter issues:
1. If the application fails to start:
- Check the logs: `docker-compose logs -f app`
- Verify environment variables are set correctly
- Ensure all required ports are available
1. Check the logs: `docker-compose logs -f app`
2. Verify database connectivity: `docker-compose exec app php artisan db:monitor`
3. Check container status: `docker-compose ps`
4. Ensure proper permissions on the storage directory
2. If the database connection fails:
- Check the database logs: `docker-compose logs -f db`
- Verify database credentials in `.env`
- Ensure the database container is running: `docker-compose ps`
### Common Issues
3. If the web server is not accessible:
- Check nginx logs: `docker-compose logs -f nginx`
- Verify port configuration in `.env`
- Check if the domain is properly configured
**Missing PHP extensions**
## License
If you see errors about missing PHP extensions like `ext-intl`, the Dockerfile has been updated to include this. However, if you encounter other missing extensions, you can add them to the Dockerfile by:
1. Adding the required dev packages to the `apt-get install` command
2. Adding the extension to the `docker-php-ext-install` command
**Composer installation failures**
If the composer installation fails, you can modify the entrypoint script to use the `--ignore-platform-req` flag. This is included as a fallback in the updated entrypoint script.
This project is licensed under the MIT License - see the LICENSE file for details.
+46 -23
View File
@@ -8,22 +8,22 @@ services:
container_name: tastyigniter-app
restart: unless-stopped
environment:
- APP_NAME=TastyIgniter
- APP_ENV=production
- APP_KEY=
- APP_DEBUG=false
- APP_URL=http://localhost
- IGNITER_LOCATION_MODE=multiple
- IGNITER_CARTE_KEY=
- APP_NAME=${APP_NAME:-TastyIgniter}
- APP_ENV=${APP_ENV:-production}
- APP_KEY=${APP_KEY}
- APP_DEBUG=${APP_DEBUG:-false}
- APP_URL=${APP_URL}
- IGNITER_LOCATION_MODE=${IGNITER_LOCATION_MODE:-multiple}
- IGNITER_CARTE_KEY=${IGNITER_CARTE_KEY}
# Database configuration
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=tastyigniter
- DB_USERNAME=tastyigniter
- DB_PASSWORD=secret_password
- DB_PREFIX=ti_
- DB_DATABASE=${DB_DATABASE:-tastyigniter}
- DB_USERNAME=${DB_USERNAME:-tastyigniter}
- DB_PASSWORD=${DB_PASSWORD}
- DB_PREFIX=${DB_PREFIX:-ti_}
# Cache and Session
- BROADCAST_DRIVER=log
@@ -33,44 +33,61 @@ services:
- SESSION_LIFETIME=120
# Mail Configuration
- MAIL_MAILER=log
- MAIL_FROM_ADDRESS=noreply@tastyigniter.tld
- MAIL_FROM_NAME=TastyIgniter
- MAIL_MAILER=${MAIL_MAILER:-log}
- MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS:-noreply@tastyigniter.tld}
- MAIL_FROM_NAME=${MAIL_FROM_NAME:-TastyIgniter}
volumes:
- tastyigniter:/var/www/html
- tastyigniter-storage:/var/www/html/storage
depends_on:
- db
db:
condition: service_healthy
networks:
- tastyigniter-network
healthcheck:
test: ["CMD", "php", "artisan", "--version"]
interval: 30s
timeout: 10s
retries: 3
nginx:
image: nginx:alpine
container_name: tastyigniter-nginx
restart: unless-stopped
ports:
- "80:80"
- "${PORT:-80}:80"
volumes:
- tastyigniter:/var/www/html
- ./docker/nginx:/etc/nginx/conf.d
depends_on:
- app
app:
condition: service_healthy
networks:
- tastyigniter-network
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80"]
interval: 30s
timeout: 10s
retries: 3
db:
image: mysql:8
container_name: tastyigniter-db
restart: unless-stopped
environment:
- MYSQL_DATABASE=tastyigniter
- MYSQL_USER=tastyigniter
- MYSQL_PASSWORD=secret_password
- MYSQL_ROOT_PASSWORD=root_password
- MYSQL_DATABASE=${DB_DATABASE:-tastyigniter}
- MYSQL_USER=${DB_USERNAME:-tastyigniter}
- MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
volumes:
- dbdata:/var/lib/mysql
networks:
- tastyigniter-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD}"]
interval: 30s
timeout: 10s
retries: 3
cron:
build:
@@ -82,7 +99,8 @@ services:
volumes:
- tastyigniter:/var/www/html
depends_on:
- app
app:
condition: service_healthy
networks:
- tastyigniter-network
@@ -96,15 +114,20 @@ services:
volumes:
- tastyigniter:/var/www/html
depends_on:
- app
app:
condition: service_healthy
networks:
- tastyigniter-network
volumes:
dbdata:
name: ${STACK_NAME:-tastyigniter}_dbdata
tastyigniter:
name: ${STACK_NAME:-tastyigniter}_app
tastyigniter-storage:
name: ${STACK_NAME:-tastyigniter}_storage
networks:
tastyigniter-network:
name: ${STACK_NAME:-tastyigniter}_network
driver: bridge
+73 -8
View File
@@ -1,9 +1,43 @@
#!/bin/bash
set -e
# Function to log messages
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
# Function to check if a command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to validate environment variables
validate_env() {
local required_vars=("DB_HOST" "DB_DATABASE" "DB_USERNAME" "DB_PASSWORD")
local missing_vars=()
for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
missing_vars+=("$var")
fi
done
if [ ${#missing_vars[@]} -ne 0 ]; then
log "ERROR: Missing required environment variables: ${missing_vars[*]}"
exit 1
fi
}
# Create log directory if it doesn't exist
mkdir -p /var/log/php
chown -R www-data:www-data /var/log/php
# Validate environment variables
validate_env
# Check if TastyIgniter is already installed
if [ ! -f /var/www/html/composer.json ] || [ ! -d /var/www/html/vendor ]; then
echo "Installing TastyIgniter..."
log "Installing TastyIgniter..."
# Create new TastyIgniter project
composer create-project tastyigniter/tastyigniter:^v4.0 /tmp/tastyigniter --prefer-dist --no-interaction --no-progress
@@ -11,40 +45,71 @@ if [ ! -f /var/www/html/composer.json ] || [ ! -d /var/www/html/vendor ]; then
cp -a /tmp/tastyigniter/. /var/www/html/
rm -rf /tmp/tastyigniter
echo "TastyIgniter files installed"
log "TastyIgniter files installed"
fi
# Set proper permissions
log "Setting proper permissions..."
chown -R www-data:www-data /var/www/html
chmod -R 755 /var/www/html
chmod -R 775 /var/www/html/storage
chmod -R 775 /var/www/html/bootstrap/cache
# Generate app key if not set
if [ -z "$APP_KEY" ]; then
log "Generating application key..."
php artisan key:generate
fi
# Wait for database to be ready
echo "Waiting for database to be ready..."
log "Waiting for database to be ready..."
max_tries=30
counter=1
while ! mysql -h "$DB_HOST" -u "$DB_USERNAME" -p"$DB_PASSWORD" -e "SELECT 1" >/dev/null 2>&1; do
sleep 1
if [ $counter -ge $max_tries ]; then
log "ERROR: Database connection failed after $max_tries attempts"
exit 1
fi
log "Database connection attempt $counter/$max_tries failed, retrying in 2 seconds..."
sleep 2
counter=$((counter + 1))
done
echo "Database connection established"
log "Database connection established"
# Run TastyIgniter installer in non-interactive mode if not installed
if [ ! -f .env ] || ! grep -q "IGNITER_INSTALLED=true" .env; then
echo "Running TastyIgniter installer..."
log "Running TastyIgniter installer..."
php artisan igniter:install --no-interaction
# Mark as installed in .env
echo "IGNITER_INSTALLED=true" >> .env
echo "TastyIgniter installed successfully"
log "TastyIgniter installed successfully"
else
echo "TastyIgniter already installed"
log "TastyIgniter already installed"
fi
# Run database migrations if needed
log "Running database migrations..."
php artisan migrate --force
# Clear and cache configuration
log "Clearing and caching configuration..."
php artisan config:clear
php artisan config:cache
php artisan route:clear
php artisan route:cache
php artisan view:clear
php artisan view:cache
# Set proper permissions again after all operations
log "Setting final permissions..."
chown -R www-data:www-data /var/www/html
chmod -R 755 /var/www/html
chmod -R 775 /var/www/html/storage
chmod -R 775 /var/www/html/bootstrap/cache
log "Entrypoint script completed successfully"
# Execute the main command
exec "$@"
+42 -18
View File
@@ -1,40 +1,49 @@
server {
listen 80;
server_name localhost;
server_name ${APP_URL:-localhost};
root /var/www/html/public;
index index.php;
# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Gzip compression
gzip on;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied expired no-cache no-store private auth;
gzip_types application/javascript application/x-javascript application/json
text/css text/plain text/xml application/xml
image/svg+xml image/x-icon
application/vnd.ms-fontobject application/x-font-ttf font/opentype;
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
charset utf-8;
client_max_body_size 100M;
fastcgi_read_timeout 1800;
# Logs
access_log /var/log/nginx/access.log combined buffer=512k flush=1m;
error_log /var/log/nginx/error.log warn;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_read_timeout 1800;
fastcgi_send_timeout 1800;
fastcgi_connect_timeout 1800;
}
# Deny access to . files
@@ -55,18 +64,33 @@ server {
}
# Deny access to sensitive files
location ~* \.(env|log|git|key|md|yml|yaml|conf)$ {
location ~* \.(env|log|git|key|md|yml|yaml|conf|ini|lock|json|sql)$ {
deny all;
}
# Assets caching
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires max;
log_not_found off;
access_log off;
add_header Cache-Control "public, no-transform";
try_files $uri =404;
}
access_log off;
error_log /var/log/nginx/error.log error;
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny access to composer files
location ~ composer\.(json|lock)$ {
deny all;
}
# Deny access to storage files
location ~ /storage/.*\.(php|php5|sh|pl|py|jsp|asp|htm|html|shtml|js)$ {
deny all;
}
}
+31
View File
@@ -0,0 +1,31 @@
[PHP]
; Production settings
display_errors = Off
display_startup_errors = Off
error_reporting = E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED
log_errors = On
error_log = /var/log/php/error.log
memory_limit = 256M
max_execution_time = 60
max_input_time = 60
post_max_size = 100M
upload_max_filesize = 100M
max_input_vars = 3000
; Session settings
session.gc_maxlifetime = 1440
session.gc_probability = 1
session.gc_divisor = 100
; OpCache settings
opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 4000
opcache.revalidate_freq = 60
opcache.fast_shutdown = 1
opcache.enable_file_override = 0
; Date settings
date.timezone = UTC
+21
View File
@@ -0,0 +1,21 @@
[www]
user = www-data
group = www-data
listen = 9000
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_requests = 500
php_admin_value[error_log] = /var/log/php/error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 256M
php_admin_value[max_execution_time] = 60
php_admin_value[max_input_time] = 60
php_admin_value[post_max_size] = 100M
php_admin_value[upload_max_filesize] = 100M
php_admin_value[max_input_vars] = 3000