Compare commits
46 Commits
382e68769e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
678a8842f4 | ||
|
|
4ce000e95b | ||
|
|
cc882ea6fc | ||
|
|
ee557c6fd2 | ||
|
|
e17ac2af1f | ||
|
|
ab0be021e1 | ||
|
|
5fbaf0767e | ||
|
|
5707e3debb | ||
|
|
2c4b110f33 | ||
|
|
5b12eb2072 | ||
|
|
7a559a9021 | ||
| 4f2a435e2a | |||
|
|
1c29fbf958 | ||
|
|
7c4650f83b | ||
|
|
39abf1b5fc | ||
|
|
e45cfb5ebd | ||
|
|
246f6b2c0f | ||
|
|
075c6bfdf9 | ||
|
|
58e1bad1cf | ||
|
|
110c0f7291 | ||
|
|
2550a945a3 | ||
|
|
159dda3843 | ||
|
|
946f968ca0 | ||
|
|
58e36c420c | ||
|
|
7fb6a74a13 | ||
|
|
183d19848b | ||
|
|
f2081217af | ||
|
|
e9620052f7 | ||
|
|
3ca2983c68 | ||
|
|
676988fabb | ||
|
|
73b178fa2c | ||
|
|
8e8bfd1897 | ||
|
|
aaa043f06e | ||
|
|
74860f8a0d | ||
|
|
9d0bae2dea | ||
|
|
63c5c50578 | ||
|
|
632f143637 | ||
|
|
a4171330e5 | ||
|
|
af0d8cd9ac | ||
|
|
fa59a081d8 | ||
|
|
6f7b81f1da | ||
|
|
a12ee2e5aa | ||
|
|
c72e03f282 | ||
|
|
0cedc90031 | ||
| a6b2ea3a14 | |||
|
|
b5443ddcee |
18
.dockerignore
Normal file
18
.dockerignore
Normal file
@@ -0,0 +1,18 @@
|
||||
.git
|
||||
.gitignore
|
||||
.env
|
||||
vendor
|
||||
node_modules
|
||||
storage/logs/*
|
||||
storage/framework/cache/*
|
||||
storage/framework/sessions/*
|
||||
storage/framework/views/*
|
||||
bootstrap/cache/*
|
||||
tests
|
||||
.editorconfig
|
||||
.phpunit.result.cache
|
||||
phpunit.xml
|
||||
readme.md
|
||||
docker-compose.yml
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
13
.env.docker
Normal file
13
.env.docker
Normal file
@@ -0,0 +1,13 @@
|
||||
# Docker Environment Variables
|
||||
# Copy this file and configure for your external MySQL database
|
||||
|
||||
# Database Configuration - Update these to connect to your external MySQL
|
||||
DB_HOST=your-mysql-host
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=merchbay_admin
|
||||
DB_USERNAME=your-mysql-user
|
||||
DB_PASSWORD=your-mysql-password
|
||||
|
||||
# Application Configuration
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
26
.env.example
26
.env.example
@@ -1,25 +1,33 @@
|
||||
APP_ENV=local
|
||||
APP_DEBUG=true
|
||||
APP_KEY=SomeRandomString
|
||||
APP_URL=http://localhost
|
||||
# Application Configuration
|
||||
APP_ENV=production
|
||||
APP_DEBUG=false
|
||||
APP_KEY=base64:YOUR_APP_KEY_HERE
|
||||
APP_URL=https://merchbay.com
|
||||
|
||||
# Database Configuration - External MySQL
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_HOST=your-mysql-host
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=homestead
|
||||
DB_USERNAME=homestead
|
||||
DB_PASSWORD=secret
|
||||
DB_DATABASE=merchbay_admin
|
||||
DB_USERNAME=your-mysql-user
|
||||
DB_PASSWORD=your-mysql-password
|
||||
|
||||
# Traefik Domain Configuration
|
||||
DOMAIN=merchbay.com
|
||||
|
||||
# Cache & Session
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
# Redis (Optional)
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
# Mail Configuration
|
||||
MAIL_DRIVER=smtp
|
||||
MAIL_HOST=mailtrap.io
|
||||
MAIL_HOST=smtp.mailtrap.io
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
|
||||
23
.env.server.example
Normal file
23
.env.server.example
Normal file
@@ -0,0 +1,23 @@
|
||||
# Server .env file for Development Environment
|
||||
#
|
||||
# Instructions:
|
||||
# 1. SSH to your server: ssh webmaster@YOUR_SERVER_IP
|
||||
# 2. Create directory: mkdir -p /var/www/merchbay_admin_dev
|
||||
# 3. Create this file: nano /var/www/merchbay_admin_dev/.env
|
||||
# 4. Copy the content below (fill in YOUR_DB_PASSWORD)
|
||||
# 5. Save and secure: chmod 600 /var/www/merchbay_admin_dev/.env
|
||||
|
||||
APP_ENV=development
|
||||
APP_DEBUG=true
|
||||
APP_URL=https://dev-admin.merchbay.app
|
||||
DB_HOST=mysql
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=merchcbay_db
|
||||
DB_USERNAME=crewapp
|
||||
DB_PASSWORD=YOUR_DB_PASSWORD_HERE
|
||||
DOMAIN=dev-admin.merchbay.app
|
||||
|
||||
# Notes:
|
||||
# - DB_HOST=mysql (your MySQL container name on crew-app-net network)
|
||||
# - Replace YOUR_DB_PASSWORD_HERE with your actual MySQL password
|
||||
# - This file should NEVER be committed to git
|
||||
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 }}/merchbay_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 }}/merchbay_admin:buildcache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKER_REGISTRY_URL }}/merchbay_admin:buildcache,mode=max
|
||||
160
.gitea/workflows/deploy-dev.yml
Normal file
160
.gitea/workflows/deploy-dev.yml
Normal file
@@ -0,0 +1,160 @@
|
||||
name: Deploy Development
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
steps:
|
||||
# 1️⃣ Checkout code
|
||||
- name: Checkout code
|
||||
shell: sh
|
||||
run: |
|
||||
git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git /workspace/repo
|
||||
cd /workspace/repo
|
||||
git checkout $GITHUB_REF_NAME
|
||||
|
||||
# 2️⃣ Build image
|
||||
- name: Build Docker image
|
||||
shell: sh
|
||||
run: |
|
||||
cd /workspace/repo
|
||||
docker build -t merchbay_admin:dev .
|
||||
docker save merchbay_admin:dev | gzip > merchbay_admin_dev.tar.gz
|
||||
|
||||
# 3️⃣ Setup SSH
|
||||
- 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
|
||||
|
||||
# 4️⃣ Upload artifacts
|
||||
- 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/merchbay_admin_dev.tar.gz \
|
||||
/workspace/repo/docker-compose.dev.yml \
|
||||
${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/
|
||||
|
||||
# 5️⃣ Deploy on server
|
||||
- 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/merchbay_admin_dev"
|
||||
mkdir -p "$DEPLOY_DIR"
|
||||
|
||||
echo "📦 Loading image"
|
||||
docker load < /tmp/merchbay_admin_dev.tar.gz
|
||||
|
||||
echo "🧹 Removing old merchbay_admin images"
|
||||
docker images | grep merchbay_admin | grep -v "$(docker images merchbay_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 merchbay_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/merchbay_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
|
||||
|
||||
|
||||
# 6️⃣ Health check
|
||||
- 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.merchbay.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 merchbay_admin_app"
|
||||
echo ""
|
||||
echo " 2. Check app logs:"
|
||||
echo " docker logs merchbay_admin_app"
|
||||
echo ""
|
||||
echo " 3. Check Traefik logs:"
|
||||
echo " docker logs traefik"
|
||||
echo ""
|
||||
echo " 4. Test manually:"
|
||||
echo " curl -Ik https://dev-admin.merchbay.app"
|
||||
exit 1
|
||||
fi
|
||||
169
.gitea/workflows/deploy.yml
Normal file
169
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,169 @@
|
||||
name: Deploy Production (admin.merchbay.app)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
|
||||
steps:
|
||||
# 1️⃣ Checkout code
|
||||
- name: Checkout code
|
||||
shell: sh
|
||||
run: |
|
||||
git clone $GITHUB_SERVER_URL/$GITHUB_REPOSITORY.git /workspace/repo
|
||||
cd /workspace/repo
|
||||
git checkout $GITHUB_REF_NAME
|
||||
|
||||
# 2️⃣ Build image
|
||||
- name: Build Docker image
|
||||
shell: sh
|
||||
run: |
|
||||
cd /workspace/repo
|
||||
docker build -t merchbay_admin:latest .
|
||||
docker save merchbay_admin:latest | gzip > merchbay_admin.tar.gz
|
||||
|
||||
# 3️⃣ Setup SSH
|
||||
- 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
|
||||
|
||||
# 4️⃣ Upload artifacts
|
||||
- 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/merchbay_admin.tar.gz \
|
||||
/workspace/repo/docker-compose.prod.yml \
|
||||
${DEPLOY_USER}@${DEPLOY_HOST}:/tmp/
|
||||
|
||||
# 5️⃣ Deploy on server
|
||||
- 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/merchbay_admin"
|
||||
sudo mkdir -p "$DEPLOY_DIR"
|
||||
sudo chown $USER:$USER "$DEPLOY_DIR"
|
||||
|
||||
echo "📦 Loading image"
|
||||
docker load < /tmp/merchbay_admin.tar.gz
|
||||
|
||||
echo "🧹 Removing old merchbay_admin images"
|
||||
docker images | grep merchbay_admin | grep -v "$(docker images merchbay_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 "<22> Stopping and removing existing containers"
|
||||
docker compose down || true
|
||||
docker rm -f merchbay_admin_app || true
|
||||
|
||||
echo "<22>🚀 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 merchbay_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/merchbay_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
|
||||
|
||||
rm -f /tmp/merchbay_admin.tar.gz /tmp/docker-compose.prod.yml
|
||||
|
||||
echo "✅ Production deployment completed!"
|
||||
echo "🌐 Application available at: https://admin.merchbay.app"
|
||||
EOF
|
||||
|
||||
|
||||
# 6️⃣ Health check
|
||||
- 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.merchbay.app || echo "000")
|
||||
|
||||
if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "302" ] || [ "$HTTP_CODE" = "301" ]; then
|
||||
echo "✅ Health check passed! (HTTP $HTTP_CODE)"
|
||||
echo "🎉 Production deployment successful!"
|
||||
else
|
||||
echo "❌ Health check failed! (HTTP $HTTP_CODE)"
|
||||
echo ""
|
||||
echo "💡 Troubleshooting:"
|
||||
echo " 1. Check if container is running:"
|
||||
echo " docker ps | grep merchbay_admin_app"
|
||||
echo ""
|
||||
echo " 2. Check app logs:"
|
||||
echo " docker logs merchbay_admin_app"
|
||||
echo ""
|
||||
echo " 3. Check Traefik logs:"
|
||||
echo " docker logs traefik"
|
||||
echo ""
|
||||
echo " 4. Test manually:"
|
||||
echo " curl -Ik https://admin.merchbay.app"
|
||||
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"]
|
||||
@@ -16,7 +16,10 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
// Force HTTPS when behind a proxy (Traefik)
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
||||
\URL::forceSchema('https');
|
||||
}
|
||||
|
||||
Storage::extend('sftp', function ($app, $config) {
|
||||
return new Filesystem(new SftpAdapter($config));
|
||||
|
||||
45
docker-compose.dev.yml
Normal file
45
docker-compose.dev.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
services:
|
||||
app:
|
||||
image: merchbay_admin:dev
|
||||
container_name: merchbay_admin_app
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- APP_DEBUG=${APP_DEBUG:-true}
|
||||
- APP_URL=${APP_URL:-https://dev-admin.merchbay.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.merchbay.app)
|
||||
- "traefik.http.routers.merchbay-admin-dev.rule=Host(`dev-admin.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-dev.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls=true"
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.merchbay-admin-dev.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.merchbay-admin-dev-http.rule=Host(`dev-admin.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-dev-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-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: merchbay_admin:latest
|
||||
container_name: merchbay_admin_app
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- APP_DEBUG=${APP_DEBUG:-false}
|
||||
- APP_URL=${APP_URL:-https://merchbay.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 (merchbay.app)
|
||||
- "traefik.http.routers.merchbay-admin-prod.rule=Host(`merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-prod.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-admin-prod.tls=true"
|
||||
- "traefik.http.routers.merchbay-admin-prod.tls.certresolver=le"
|
||||
- "traefik.http.services.merchbay-admin-prod.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.merchbay-admin-prod-http.rule=Host(`merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-prod-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-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
|
||||
44
docker-compose.yml
Normal file
44
docker-compose.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
services:
|
||||
app:
|
||||
image: merchbay_admin:dev
|
||||
container_name: merchbay_admin_app
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- APP_DEBUG=${APP_DEBUG:-false}
|
||||
- APP_URL=${APP_URL:-http://localhost}
|
||||
- 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"
|
||||
- "traefik.http.routers.merchbay-admin-dev.rule=Host(`dev-admin.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-dev.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls=true"
|
||||
- "traefik.http.routers.merchbay-admin-dev.tls.certresolver=le"
|
||||
- "traefik.http.services.merchbay-admin-dev.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.merchbay-admin-dev-http.rule=Host(`dev-admin.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-admin-dev-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-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
|
||||
18
docker-entrypoint.sh
Normal file
18
docker-entrypoint.sh
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/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
|
||||
mkdir -p public/uploads
|
||||
|
||||
# Set proper permissions
|
||||
chown -R www-data:www-data storage bootstrap/cache public/uploads
|
||||
chmod -R 775 storage bootstrap/cache public/uploads
|
||||
|
||||
# Execute the main command
|
||||
exec "$@"
|
||||
181
readme.md
181
readme.md
@@ -1,27 +1,178 @@
|
||||
# Laravel PHP Framework
|
||||
# MerchBay 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 e-commerce 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.
|
||||
MerchBay Admin is a web-based administration interface designed to streamline business operations for custom merchandise and sportswear 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
|
||||
- **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
|
||||
|
||||
## 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+
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Using Docker (Recommended)
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repository-url>
|
||||
cd merchbay_admin
|
||||
|
||||
# Copy environment file
|
||||
cp .env.example .env
|
||||
|
||||
# Configure your environment variables
|
||||
vim .env
|
||||
|
||||
# Build and start containers
|
||||
docker-compose up -d
|
||||
|
||||
# Install dependencies
|
||||
docker exec merchbay_admin_app composer install
|
||||
|
||||
# Generate application key
|
||||
docker exec merchbay_admin_app php artisan key:generate
|
||||
|
||||
# Run migrations
|
||||
docker exec merchbay_admin_app php artisan migrate
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
```bash
|
||||
# Install PHP 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
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Key environment variables to configure:
|
||||
|
||||
- `APP_URL` - Application URL (e.g., https://admin.merchbay.app)
|
||||
- `DB_HOST` - Database host
|
||||
- `DB_DATABASE` - Database name
|
||||
- `DB_USERNAME` - Database username
|
||||
- `DB_PASSWORD` - Database password
|
||||
|
||||
### SSL/HTTPS Configuration
|
||||
|
||||
The application uses Traefik as a reverse proxy with automatic Let's Encrypt SSL certificates. Ensure your DNS is properly configured and the following Traefik labels are set in `docker-compose.yml`.
|
||||
|
||||
## Deployment
|
||||
|
||||
This project includes automated CI/CD pipelines via Gitea Actions:
|
||||
|
||||
- **Development**: Auto-deploys on push to `dev` branch
|
||||
- **Production**: Auto-deploys on push to `main`/`master` branch
|
||||
- **Manual Builds**: Trigger builds with custom tags
|
||||
|
||||
Refer to [DEPLOYMENT.md](DEPLOYMENT.md) and [DEPLOYMENT-PORTAINER.md](DEPLOYMENT-PORTAINER.md) for detailed deployment instructions.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
merchbay_admin/
|
||||
├── app/ # Application core files
|
||||
│ ├── Http/ # Controllers, middleware, routes
|
||||
│ ├── Models/ # Eloquent models
|
||||
│ └── Providers/ # Service providers
|
||||
├── config/ # Configuration files
|
||||
├── database/ # Migrations and seeds
|
||||
├── public/ # Public assets
|
||||
├── resources/ # Views, assets, lang files
|
||||
├── storage/ # Application storage
|
||||
├── .gitea/workflows/ # CI/CD pipelines
|
||||
└── docker-compose.yml # Docker configuration
|
||||
```
|
||||
|
||||
## Development
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Run PHPUnit tests
|
||||
docker exec merchbay_admin_app vendor/bin/phpunit
|
||||
|
||||
# Or locally
|
||||
./vendor/bin/phpunit
|
||||
```
|
||||
|
||||
### Artisan Commands
|
||||
|
||||
```bash
|
||||
# List all available commands
|
||||
docker exec merchbay_admin_app php artisan list
|
||||
|
||||
# Clear application cache
|
||||
docker exec merchbay_admin_app php artisan cache:clear
|
||||
|
||||
# Run database migrations
|
||||
docker exec merchbay_admin_app php artisan migrate
|
||||
```
|
||||
|
||||
## Security
|
||||
|
||||
- All HTTP traffic is automatically redirected to HTTPS
|
||||
- Environment variables are managed securely via `.env` files
|
||||
- SQL injection prevention via Eloquent ORM
|
||||
- CSRF protection enabled on all forms
|
||||
- XSS protection via Blade templating
|
||||
|
||||
For security vulnerabilities, please contact the development team directly.
|
||||
|
||||
## Documentation
|
||||
|
||||
Additional documentation is available:
|
||||
|
||||
- [Docker Setup Guide](README-DOCKER.md)
|
||||
- [Deployment Guide](DEPLOYMENT.md)
|
||||
- [Portainer Deployment](DEPLOYMENT-PORTAINER.md)
|
||||
- [Traefik SSL Configuration](TRAEFIK-SSL-CONFIG.md)
|
||||
|
||||
## Support
|
||||
|
||||
For issues, questions, or contributions, please contact the development team or open an issue in the repository.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
|
||||
This project is proprietary software. All rights reserved.
|
||||
|
||||
Reference in New Issue
Block a user