Add Docker workflows and configuration for deployment and build processes
Some checks failed
Deploy Production (admin.crewsportswear.app) / deploy (push) Failing after 4m8s
Some checks failed
Deploy Production (admin.crewsportswear.app) / deploy (push) Failing after 4m8s
This commit is contained in:
57
.gitea/workflows/build-push.yml
Normal file
57
.gitea/workflows/build-push.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Build and Push Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Docker image tag (e.g., v1.0.0, latest)'
|
||||
required: false
|
||||
default: 'latest'
|
||||
push_to_registry:
|
||||
description: 'Push to registry?'
|
||||
required: false
|
||||
default: 'true'
|
||||
|
||||
jobs:
|
||||
build-and-push:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Login to Docker Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ${{ secrets.DOCKER_REGISTRY_URL }}
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
with:
|
||||
images: ${{ secrets.DOCKER_REGISTRY_URL }}/crew_admin
|
||||
tags: |
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
type=raw,value=latest
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=registry,ref=${{ secrets.DOCKER_REGISTRY_URL }}/crew_admin:buildcache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKER_REGISTRY_URL }}/crew_admin:buildcache,mode=max
|
||||
151
.gitea/workflows/deploy-dev.yml
Normal file
151
.gitea/workflows/deploy-dev.yml
Normal file
@@ -0,0 +1,151 @@
|
||||
name: Deploy Development
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
shell: sh
|
||||
run: |
|
||||
git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git /workspace/repo
|
||||
cd /workspace/repo
|
||||
git checkout $GITHUB_REF_NAME
|
||||
|
||||
- name: Build Docker image
|
||||
shell: sh
|
||||
run: |
|
||||
cd /workspace/repo
|
||||
docker build -t crew_admin:dev .
|
||||
docker save crew_admin:dev | gzip > crew_admin_dev.tar.gz
|
||||
|
||||
- name: Setup SSH
|
||||
shell: sh
|
||||
env:
|
||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_ed25519
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts
|
||||
|
||||
- name: Upload image and compose
|
||||
shell: sh
|
||||
env:
|
||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
run: |
|
||||
scp -i ~/.ssh/id_ed25519 \
|
||||
/workspace/repo/crew_admin_dev.tar.gz \
|
||||
/workspace/repo/docker-compose.dev.yml \
|
||||
${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/
|
||||
|
||||
- name: Deploy on server
|
||||
shell: sh
|
||||
env:
|
||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
|
||||
run: |
|
||||
ssh -i ~/.ssh/id_ed25519 $DEPLOY_USER@$DEPLOY_HOST << 'EOF'
|
||||
set -e
|
||||
|
||||
DEPLOY_DIR="/var/www/apps/crew_admin_dev"
|
||||
mkdir -p "$DEPLOY_DIR"
|
||||
|
||||
echo "Loading image"
|
||||
docker load < /tmp/crew_admin_dev.tar.gz
|
||||
|
||||
echo "Removing old crew_admin images"
|
||||
docker images | grep crew_admin | grep -v "$(docker images crew_admin:dev -q)" | awk '{print $3}' | xargs -r docker rmi -f || true
|
||||
|
||||
echo "Updating compose file"
|
||||
cp /tmp/docker-compose.dev.yml "$DEPLOY_DIR/docker-compose.yml"
|
||||
|
||||
cd "$DEPLOY_DIR"
|
||||
|
||||
echo "Checking .env file"
|
||||
if [ ! -f .env ]; then
|
||||
echo ".env file not found at $DEPLOY_DIR/.env"
|
||||
echo "Please create it first with required variables:"
|
||||
echo " - DB_*, IMAGES_DIRECTORY, PRODUCTION_PRIVATE_SERVER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Fixing .env permissions"
|
||||
sudo chown $USER:$USER .env
|
||||
sudo chmod 600 .env
|
||||
|
||||
echo "Ensure networks"
|
||||
docker network inspect traefik-public >/dev/null 2>&1 || \
|
||||
docker network create traefik-public
|
||||
docker network inspect crew-app-net >/dev/null 2>&1 || \
|
||||
docker network create crew-app-net
|
||||
|
||||
echo "Starting containers (env vars from .env file)"
|
||||
docker compose up -d
|
||||
|
||||
echo "Waiting for app container"
|
||||
sleep 15
|
||||
|
||||
if docker ps --format '{{.Names}}' | grep -q crew_admin_app; then
|
||||
echo "Clearing and rebuilding config cache"
|
||||
docker compose exec -T app php artisan config:clear
|
||||
docker compose exec -T app php artisan config:cache
|
||||
else
|
||||
echo "App container not running"
|
||||
docker compose logs
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Cleanup"
|
||||
rm -f /tmp/crew_admin_dev.tar.gz /tmp/docker-compose.dev.yml
|
||||
|
||||
echo "Aggressive Docker cleanup to reclaim space"
|
||||
docker image prune -af --filter "until=24h" || true
|
||||
docker container prune -f || true
|
||||
docker volume prune -f || true
|
||||
docker builder prune -af --filter "until=48h" || true
|
||||
echo "Docker space usage:"
|
||||
docker system df
|
||||
|
||||
echo "Deployment completed"
|
||||
EOF
|
||||
|
||||
|
||||
- name: Health check
|
||||
shell: sh
|
||||
run: |
|
||||
echo "Waiting for app to be ready..."
|
||||
sleep 20
|
||||
|
||||
echo "Testing health check (ignoring SSL cert for now)..."
|
||||
HTTP_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" --max-time 30 https://dev-admin.crewsportswear.app || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "301" ]; then
|
||||
echo "Health check passed! (HTTP $HTTP_CODE)"
|
||||
echo "Note: Using -k to ignore SSL cert. Check Traefik logs if cert not ready."
|
||||
else
|
||||
echo "Health check failed! (HTTP $HTTP_CODE)"
|
||||
echo ""
|
||||
echo "Troubleshooting:"
|
||||
echo " 1. Check if container is running:"
|
||||
echo " docker ps | grep crew_admin_app"
|
||||
echo " 2. Check container logs:"
|
||||
echo " docker logs crew_admin_app_dev"
|
||||
echo " 3. Check Traefik routing:"
|
||||
echo " docker logs traefik 2>&1 | grep crew-admin"
|
||||
echo " 4. Verify network connectivity:"
|
||||
echo " docker network inspect traefik-public"
|
||||
exit 1
|
||||
fi
|
||||
158
.gitea/workflows/deploy.yml
Normal file
158
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,158 @@
|
||||
name: Deploy Production (admin.crewsportswear.app)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
shell: sh
|
||||
run: |
|
||||
git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git /workspace/repo
|
||||
cd /workspace/repo
|
||||
git checkout $GITHUB_REF_NAME
|
||||
|
||||
- name: Build Docker image
|
||||
shell: sh
|
||||
run: |
|
||||
cd /workspace/repo
|
||||
docker build -t crew_admin:latest .
|
||||
docker save crew_admin:latest | gzip > crew_admin.tar.gz
|
||||
|
||||
- name: Setup SSH
|
||||
shell: sh
|
||||
env:
|
||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
run: |
|
||||
mkdir -p ~/.ssh
|
||||
chmod 700 ~/.ssh
|
||||
echo "$DEPLOY_SSH_KEY" > ~/.ssh/id_ed25519
|
||||
chmod 600 ~/.ssh/id_ed25519
|
||||
ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts
|
||||
|
||||
- name: Upload image and compose
|
||||
shell: sh
|
||||
env:
|
||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
run: |
|
||||
scp -i ~/.ssh/id_ed25519 \
|
||||
/workspace/repo/crew_admin.tar.gz \
|
||||
/workspace/repo/docker-compose.prod.yml \
|
||||
${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/
|
||||
|
||||
- name: Deploy on server
|
||||
shell: sh
|
||||
env:
|
||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
|
||||
|
||||
run: |
|
||||
ssh -i ~/.ssh/id_ed25519 $DEPLOY_USER@$DEPLOY_HOST << 'EOF'
|
||||
set -e
|
||||
|
||||
DEPLOY_DIR="/var/www/apps/crew_admin"
|
||||
sudo mkdir -p "$DEPLOY_DIR"
|
||||
sudo chown $USER:$USER "$DEPLOY_DIR"
|
||||
|
||||
echo "Loading image"
|
||||
docker load < /tmp/crew_admin.tar.gz
|
||||
|
||||
echo "Removing old crew_admin images"
|
||||
docker images | grep crew_admin | grep -v "$(docker images crew_admin:latest -q)" | awk '{print $3}' | xargs -r docker rmi -f || true
|
||||
|
||||
echo "Updating compose file"
|
||||
cp /tmp/docker-compose.prod.yml "$DEPLOY_DIR/docker-compose.yml"
|
||||
|
||||
cd "$DEPLOY_DIR"
|
||||
|
||||
echo "Checking .env file"
|
||||
if [ ! -f .env ]; then
|
||||
echo ".env file not found at $DEPLOY_DIR/.env"
|
||||
echo "Please create it first with required variables:"
|
||||
echo " - DB_*, IMAGES_DIRECTORY, PRODUCTION_PRIVATE_SERVER"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Fixing .env permissions"
|
||||
sudo chown $USER:$USER .env
|
||||
sudo chmod 600 .env
|
||||
|
||||
echo "Ensure networks"
|
||||
docker network inspect traefik-public >/dev/null 2>&1 || \
|
||||
docker network create traefik-public
|
||||
docker network inspect crew-app-net >/dev/null 2>&1 || \
|
||||
docker network create crew-app-net
|
||||
|
||||
echo "Stopping and removing existing containers"
|
||||
docker compose down || true
|
||||
docker rm -f crew_admin_app || true
|
||||
|
||||
echo "Starting containers (env vars from .env file)"
|
||||
docker compose up -d
|
||||
|
||||
echo "Waiting for app container"
|
||||
sleep 15
|
||||
|
||||
if docker ps --format '{{.Names}}' | grep -q crew_admin_app; then
|
||||
echo "Running migrations and clearing caches"
|
||||
docker compose exec -T app php artisan config:clear
|
||||
docker compose exec -T app php artisan config:cache
|
||||
else
|
||||
echo "App container not running"
|
||||
docker compose logs
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Cleanup"
|
||||
rm -f /tmp/crew_admin.tar.gz /tmp/docker-compose.prod.yml
|
||||
|
||||
echo "Aggressive Docker cleanup to reclaim space"
|
||||
docker image prune -af --filter "until=24h" || true
|
||||
docker container prune -f || true
|
||||
docker volume prune -f || true
|
||||
docker builder prune -af --filter "until=48h" || true
|
||||
echo "Docker space usage:"
|
||||
docker system df
|
||||
|
||||
echo "Production deployment completed!"
|
||||
echo "Application available at: https://admin.crewsportswear.app"
|
||||
EOF
|
||||
|
||||
|
||||
- name: Health check
|
||||
shell: sh
|
||||
run: |
|
||||
echo "Waiting for app to be ready..."
|
||||
sleep 20
|
||||
|
||||
echo "Testing health check (ignoring SSL cert for now)..."
|
||||
HTTP_CODE=$(curl -k -s -o /dev/null -w "%{http_code}" --max-time 30 https://admin.crewsportswear.app || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "301" ]; then
|
||||
echo "Health check passed! (HTTP $HTTP_CODE)"
|
||||
echo "Note: Using -k to ignore SSL cert. Check Traefik logs if cert not ready."
|
||||
else
|
||||
echo "Health check failed! (HTTP $HTTP_CODE)"
|
||||
echo ""
|
||||
echo "Troubleshooting:"
|
||||
echo " 1. Check if container is running:"
|
||||
echo " docker ps | grep crew_admin_app"
|
||||
echo " 2. Check container logs:"
|
||||
echo " docker logs crew_admin_app"
|
||||
echo " 3. Check Traefik routing:"
|
||||
echo " docker logs traefik 2>&1 | grep crew-admin"
|
||||
echo " 4. Verify network connectivity:"
|
||||
echo " docker network inspect traefik-public"
|
||||
exit 1
|
||||
fi
|
||||
78
Dockerfile
Normal file
78
Dockerfile
Normal file
@@ -0,0 +1,78 @@
|
||||
# Use PHP 7.4 with Apache (compatible with Laravel 5.2 and ARM64)
|
||||
FROM php:7.4-apache
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
git \
|
||||
curl \
|
||||
libpng-dev \
|
||||
libonig-dev \
|
||||
libxml2-dev \
|
||||
libzip-dev \
|
||||
zip \
|
||||
unzip \
|
||||
libfreetype6-dev \
|
||||
libjpeg62-turbo-dev \
|
||||
openssh-client \
|
||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
||||
&& docker-php-ext-install -j$(nproc) gd
|
||||
|
||||
# Install PHP extensions
|
||||
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath zip
|
||||
|
||||
# Enable Apache mod_rewrite
|
||||
RUN a2enmod rewrite
|
||||
|
||||
# Install Composer
|
||||
COPY --from=composer:1.10 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Copy existing application directory contents
|
||||
COPY . /var/www/html
|
||||
|
||||
# Copy and set permissions for entrypoint script
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Create storage directories and set permissions
|
||||
RUN mkdir -p storage/framework/views \
|
||||
storage/framework/cache \
|
||||
storage/framework/sessions \
|
||||
storage/logs \
|
||||
bootstrap/cache
|
||||
|
||||
# Set proper ownership and permissions
|
||||
RUN chown -R www-data:www-data /var/www/html \
|
||||
&& chmod -R 775 /var/www/html/storage \
|
||||
&& chmod -R 775 /var/www/html/bootstrap/cache
|
||||
|
||||
# Create .env file if it doesn't exist
|
||||
RUN if [ ! -f .env ]; then cp .env.example .env; fi
|
||||
|
||||
# Install PHP dependencies without running post-install scripts
|
||||
RUN composer install --no-dev --no-scripts --no-interaction
|
||||
|
||||
# Generate application key
|
||||
RUN php artisan key:generate
|
||||
|
||||
# Optimize autoloader
|
||||
RUN composer dump-autoload --optimize --no-dev
|
||||
|
||||
# Configure Apache DocumentRoot to point to Laravel's public directory
|
||||
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
|
||||
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
|
||||
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
|
||||
|
||||
# Suppress Apache ServerName warning
|
||||
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Set entrypoint
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
|
||||
# Start Apache
|
||||
CMD ["apache2-foreground"]
|
||||
45
docker-compose.dev.yml
Normal file
45
docker-compose.dev.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
services:
|
||||
app:
|
||||
image: crew_admin:dev
|
||||
container_name: crew_admin_app_dev
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- APP_DEBUG=${APP_DEBUG:-true}
|
||||
- APP_URL=${APP_URL:-https://dev-admin.crewsportswear.app}
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=${DB_HOST}
|
||||
- DB_PORT=${DB_PORT:-3306}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
- IMAGES_DIRECTORY=${IMAGES_DIRECTORY}
|
||||
- PRODUCTION_PRIVATE_SERVER=${PRODUCTION_PRIVATE_SERVER}
|
||||
volumes:
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./public/uploads:/var/www/html/public/uploads
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# Development environment (dev-admin.crewsportswear.app)
|
||||
- "traefik.http.routers.crew-admin-dev.rule=Host(`dev-admin.crewsportswear.app`)"
|
||||
- "traefik.http.routers.crew-admin-dev.entrypoints=websecure"
|
||||
- "traefik.http.routers.crew-admin-dev.tls=true"
|
||||
- "traefik.http.routers.crew-admin-dev.tls.certresolver=le"
|
||||
- "traefik.http.services.crew-admin-dev.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.crew-admin-dev-http.rule=Host(`dev-admin.crewsportswear.app`)"
|
||||
- "traefik.http.routers.crew-admin-dev-http.entrypoints=web"
|
||||
- "traefik.http.routers.crew-admin-dev-http.middlewares=https-redirect"
|
||||
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
|
||||
networks:
|
||||
- traefik-public
|
||||
- crew-app-net
|
||||
- default
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
crew-app-net:
|
||||
external: true
|
||||
default:
|
||||
driver: bridge
|
||||
45
docker-compose.prod.yml
Normal file
45
docker-compose.prod.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
services:
|
||||
app:
|
||||
image: crew_admin:latest
|
||||
container_name: crew_admin_app
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- APP_DEBUG=${APP_DEBUG:-false}
|
||||
- APP_URL=${APP_URL:-https://admin.crewsportswear.app}
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=${DB_HOST}
|
||||
- DB_PORT=${DB_PORT:-3306}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
- IMAGES_DIRECTORY=${IMAGES_DIRECTORY}
|
||||
- PRODUCTION_PRIVATE_SERVER=${PRODUCTION_PRIVATE_SERVER}
|
||||
volumes:
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./public/uploads:/var/www/html/public/uploads
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# Production environment (admin.crewsportswear.app)
|
||||
- "traefik.http.routers.crew-admin-prod.rule=Host(`admin.crewsportswear.app`)"
|
||||
- "traefik.http.routers.crew-admin-prod.entrypoints=websecure"
|
||||
- "traefik.http.routers.crew-admin-prod.tls=true"
|
||||
- "traefik.http.routers.crew-admin-prod.tls.certresolver=le"
|
||||
- "traefik.http.services.crew-admin-prod.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.crew-admin-prod-http.rule=Host(`admin.crewsportswear.app`)"
|
||||
- "traefik.http.routers.crew-admin-prod-http.entrypoints=web"
|
||||
- "traefik.http.routers.crew-admin-prod-http.middlewares=https-redirect"
|
||||
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
|
||||
networks:
|
||||
- traefik-public
|
||||
- crew-app-net
|
||||
- default
|
||||
|
||||
networks:
|
||||
traefik-public:
|
||||
external: true
|
||||
crew-app-net:
|
||||
external: true
|
||||
default:
|
||||
driver: bridge
|
||||
17
docker-entrypoint.sh
Normal file
17
docker-entrypoint.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Create storage directory structure if it doesn't exist
|
||||
mkdir -p storage/framework/views
|
||||
mkdir -p storage/framework/cache
|
||||
mkdir -p storage/framework/sessions
|
||||
mkdir -p storage/logs
|
||||
mkdir -p storage/app/public
|
||||
mkdir -p bootstrap/cache
|
||||
|
||||
# Set proper permissions
|
||||
chown -R www-data:www-data storage bootstrap/cache
|
||||
chmod -R 775 storage bootstrap/cache
|
||||
|
||||
# Execute the main command
|
||||
exec "$@"
|
||||
228
readme.md
228
readme.md
@@ -1,27 +1,225 @@
|
||||
# Laravel PHP Framework
|
||||
# Crew Admin Panel
|
||||
|
||||
[](https://travis-ci.org/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
[](https://packagist.org/packages/laravel/framework)
|
||||
A comprehensive administration platform built with Laravel 5.2 for managing custom sportswear operations, product catalogs, and customer relationships.
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable, creative experience to be truly fulfilling. Laravel attempts to take the pain out of development by easing common tasks used in the majority of web projects, such as authentication, routing, sessions, queueing, and caching.
|
||||
## Overview
|
||||
|
||||
Laravel is accessible, yet powerful, providing tools needed for large, robust applications. A superb inversion of control container, expressive migration system, and tightly integrated unit testing support give you the tools you need to build any application with which you are tasked.
|
||||
Crew Admin is a web-based administration interface designed to streamline business operations for Crew Sportswear's custom merchandise management. The platform provides robust tools for inventory control, order processing, and analytics.
|
||||
|
||||
## Official Documentation
|
||||
## Technology Stack
|
||||
|
||||
Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs).
|
||||
- **Framework**: Laravel 5.2
|
||||
- **PHP Version**: 7.4
|
||||
- **Web Server**: Apache 2.4
|
||||
- **Database**: MySQL (separate container)
|
||||
- **Reverse Proxy**: Traefik with Let's Encrypt SSL
|
||||
- **Containerization**: Docker & Docker Compose
|
||||
- **CI/CD**: Gitea Actions
|
||||
|
||||
## Contributing
|
||||
## Features
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions).
|
||||
- User authentication and role-based access control
|
||||
- Product and inventory management
|
||||
- Order processing and tracking
|
||||
- Customer relationship management
|
||||
- Analytics and reporting dashboard
|
||||
- RESTful API endpoints
|
||||
- Secure HTTPS communication
|
||||
- Automated deployment workflows
|
||||
|
||||
## Security Vulnerabilities
|
||||
## Requirements
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell at taylor@laravel.com. All security vulnerabilities will be promptly addressed.
|
||||
- Docker Engine 20.10+
|
||||
- Docker Compose 2.0+
|
||||
- PHP 7.4 (for local development)
|
||||
- Composer 1.x
|
||||
- MySQL 5.7+ or MariaDB 10.3+
|
||||
|
||||
## Deployment
|
||||
|
||||
### Production Deployment
|
||||
|
||||
Production is automatically deployed via Gitea Actions when pushing to `main` or `master` branch.
|
||||
|
||||
**Production URL**: https://admin.crewsportswear.app
|
||||
|
||||
```bash
|
||||
# Trigger production deployment
|
||||
git push origin main
|
||||
```
|
||||
|
||||
The deployment workflow:
|
||||
1. Builds Docker image
|
||||
2. Transfers image to production server via SSH
|
||||
3. Deploys to `/var/www/apps/crew_admin`
|
||||
4. Runs migrations and cache clearing
|
||||
5. Performs health check
|
||||
|
||||
### Development Deployment
|
||||
|
||||
Development environment is automatically deployed when pushing to `dev` branch.
|
||||
|
||||
**Development URL**: https://dev-admin.crewsportswear.app
|
||||
|
||||
```bash
|
||||
# Trigger dev deployment
|
||||
git push origin dev
|
||||
```
|
||||
|
||||
### Manual Deployment
|
||||
|
||||
```bash
|
||||
# Build and deploy production
|
||||
docker compose -f docker-compose.prod.yml up -d --build
|
||||
|
||||
# Build and deploy development
|
||||
docker compose -f docker-compose.dev.yml up -d --build
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Create a `.env` file in the deployment directory with:
|
||||
|
||||
```env
|
||||
# Application
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_KEY=base64:your-32-character-key-here
|
||||
APP_URL=https://admin.crewsportswear.app
|
||||
|
||||
# Database (external MySQL container)
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=mysql_container_name
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=crew_admin
|
||||
DB_USERNAME=crew_admin_user
|
||||
DB_PASSWORD=your-secure-password
|
||||
|
||||
# Additional configuration
|
||||
IMAGES_DIRECTORY=/path/to/images
|
||||
PRODUCTION_PRIVATE_SERVER=http://internal-server
|
||||
```
|
||||
|
||||
### SSL/HTTPS Configuration
|
||||
|
||||
The application uses Traefik as a reverse proxy with automatic Let's Encrypt SSL certificates. The certresolver is set to `le` in `docker-compose.prod.yml`:
|
||||
|
||||
```yaml
|
||||
traefik.http.routers.crew-admin.tls=true
|
||||
traefik.http.routers.crew-admin.tls.certresolver=le
|
||||
```
|
||||
|
||||
Ensure your DNS points to the server before deployment.
|
||||
|
||||
## Docker Networks
|
||||
|
||||
The application requires two Docker networks:
|
||||
|
||||
- `traefik-public`: External network for Traefik routing
|
||||
- `crew-app-net`: Internal network for inter-service communication
|
||||
|
||||
These are automatically created by the deployment script.
|
||||
|
||||
## Local Development
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
composer install
|
||||
|
||||
# Copy environment file
|
||||
cp .env.example .env
|
||||
|
||||
# Generate application key
|
||||
php artisan key:generate
|
||||
|
||||
# Configure database in .env file
|
||||
# Run migrations
|
||||
php artisan migrate
|
||||
|
||||
# Start development server
|
||||
php artisan serve
|
||||
```
|
||||
|
||||
## Gitea Workflows
|
||||
|
||||
### Production Deployment Workflow
|
||||
- **File**: `.gitea/workflows/deploy.yml`
|
||||
- **Trigger**: Push to `main` or `master`
|
||||
- **Target**: `/var/www/apps/crew_admin`
|
||||
- **Domain**: admin.crewsportswear.app
|
||||
|
||||
### Development Deployment Workflow
|
||||
- **File**: `.gitea/workflows/deploy-dev.yml`
|
||||
- **Trigger**: Push to `dev`
|
||||
- **Target**: `/var/www/apps/crew_admin_dev`
|
||||
- **Domain**: dev-admin.crewsportswear.app
|
||||
|
||||
### Docker Registry Build Workflow
|
||||
- **File**: `.gitea/workflows/build-push.yml`
|
||||
- **Trigger**: Version tag (e.g., `v1.0.0`)
|
||||
- **Action**: Builds and pushes to Docker registry
|
||||
|
||||
## Required Secrets
|
||||
|
||||
Configure these secrets in your Gitea repository settings:
|
||||
|
||||
- `DEPLOY_SSH_KEY`: SSH private key for deployment server
|
||||
- `DEPLOY_HOST`: Deployment server hostname/IP
|
||||
- `DEPLOY_USER`: SSH username for deployment
|
||||
|
||||
## Artisan Commands
|
||||
|
||||
Common commands for cache management:
|
||||
|
||||
```bash
|
||||
# Clear all caches
|
||||
docker exec crew_admin_app php artisan cache:clear
|
||||
docker exec crew_admin_app php artisan config:clear
|
||||
docker exec crew_admin_app php artisan view:clear
|
||||
|
||||
# Rebuild caches
|
||||
docker exec crew_admin_app php artisan config:cache
|
||||
docker exec crew_admin_app php artisan route:cache
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container Not Starting
|
||||
|
||||
```bash
|
||||
# Check container logs
|
||||
docker logs crew_admin_app
|
||||
|
||||
# Check if networks exist
|
||||
docker network ls | grep -E "traefik-public|crew-app-net"
|
||||
|
||||
# Recreate networks if needed
|
||||
docker network create traefik-public
|
||||
docker network create crew-app-net
|
||||
```
|
||||
|
||||
### SSL Certificate Issues
|
||||
|
||||
```bash
|
||||
# Check Traefik logs
|
||||
docker logs traefik 2>&1 | grep crew-admin
|
||||
|
||||
# Verify DNS is pointing correctly
|
||||
dig admin.crewsportswear.app
|
||||
```
|
||||
|
||||
### Database Connection Issues
|
||||
|
||||
```bash
|
||||
# Verify database container is running
|
||||
docker ps | grep mysql
|
||||
|
||||
# Check network connectivity
|
||||
docker exec crew_admin_app ping mysql_container_name
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
|
||||
Proprietary software for Crew Sportswear operations.
|
||||
|
||||
Reference in New Issue
Block a user