Compare commits
16 Commits
run-gcloud
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2fd4df26a | ||
|
|
fa2956e8b6 | ||
|
|
e8d21d22f8 | ||
|
|
03434cede5 | ||
|
|
609d014459 | ||
|
|
1d4b33ef9f | ||
|
|
14449ec0c1 | ||
|
|
89201a8432 | ||
|
|
e6ffc878dd | ||
|
|
807ac03d03 | ||
|
|
0a235a0ed2 | ||
|
|
c950a72fc8 | ||
|
|
564719412b | ||
|
|
cd4c7086bf | ||
|
|
0052044d6a | ||
|
|
d6a98811eb |
36
.env.local
Normal file
36
.env.local
Normal file
@@ -0,0 +1,36 @@
|
||||
APP_ENV=local
|
||||
APP_DEBUG=true
|
||||
APP_KEY=base64:YOUR_APP_KEY_HERE
|
||||
|
||||
DB_HOST=db
|
||||
DB_DATABASE=merchbay
|
||||
DB_USERNAME=merchbay
|
||||
DB_PASSWORD=secret
|
||||
DB_PORT=3306
|
||||
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
QUEUE_DRIVER=sync
|
||||
|
||||
# Local mail (logs to storage/logs/laravel.log)
|
||||
MAIL_DRIVER=log
|
||||
MAIL_HOST=localhost
|
||||
MAIL_PORT=1025
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
|
||||
# Local URLs
|
||||
APP_URL=http://localhost:8080
|
||||
PROD_PRIVATE=http://localhost:8080
|
||||
IMAGES_URL=http://localhost:8080
|
||||
UPLOAD_URL=http://localhost:8080/uploads/
|
||||
|
||||
# Test Captcha (for local dev)
|
||||
CAPTCHA_SITE_KEY=test_key
|
||||
CAPTCHA_SECRET_KEY=test_secret
|
||||
|
||||
# Analytics (optional for local)
|
||||
ANALYTICS_SITE_ID=
|
||||
ANALYTICS_CLIENT_ID=
|
||||
ANALYTICS_SERVICE_EMAIL=
|
||||
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
|
||||
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:buildcache
|
||||
cache-to: type=registry,ref=${{ secrets.DOCKER_REGISTRY_URL }}/merchbay:buildcache,mode=max
|
||||
161
.gitea/workflows/deploy-dev.yml
Normal file
161
.gitea/workflows/deploy-dev.yml
Normal file
@@ -0,0 +1,161 @@
|
||||
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:dev .
|
||||
docker save merchbay:dev | gzip > merchbay_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_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_dev"
|
||||
mkdir -p "$DEPLOY_DIR"
|
||||
|
||||
echo "📦 Loading image"
|
||||
docker load < /tmp/merchbay_dev.tar.gz
|
||||
|
||||
echo "🧹 Removing old merchbay images"
|
||||
docker images | grep merchbay | grep -v "$(docker images merchbay: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_*, PROD_PRIVATE, IMAGES_URL, UPLOAD_URL"
|
||||
echo " - MAIL_*, CAPTCHA_*, ANALYTICS_*"
|
||||
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_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_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.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_app"
|
||||
echo ""
|
||||
echo " 2. Check app logs:"
|
||||
echo " docker logs merchbay_app"
|
||||
echo ""
|
||||
echo " 3. Check Traefik logs:"
|
||||
echo " docker logs traefik"
|
||||
echo ""
|
||||
echo " 4. Test manually:"
|
||||
echo " curl -Ik https://dev.merchbay.app"
|
||||
exit 1
|
||||
fi
|
||||
181
.gitea/workflows/deploy.yml
Normal file
181
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,181 @@
|
||||
name: Deploy Production (merchbay.com)
|
||||
|
||||
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:latest .
|
||||
docker save merchbay:latest | gzip > merchbay.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.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"
|
||||
sudo mkdir -p "$DEPLOY_DIR"
|
||||
sudo chown $USER:$USER "$DEPLOY_DIR"
|
||||
|
||||
echo "<22> Stopping dev environment"
|
||||
DEV_DIR="/var/www/apps/merchbay_dev"
|
||||
if [ -d "$DEV_DIR" ]; then
|
||||
cd "$DEV_DIR"
|
||||
docker compose down || true
|
||||
cd -
|
||||
echo "✅ Dev environment stopped"
|
||||
echo "📋 Copying .env from dev to production"
|
||||
if [ -f "$DEV_DIR/.env" ]; then
|
||||
cp "$DEV_DIR/.env" "$DEPLOY_DIR/.env"
|
||||
echo "✅ .env file copied from dev to production"
|
||||
else
|
||||
echo "⚠️ No .env file found in dev directory"
|
||||
fi else
|
||||
echo "ℹ️ No dev environment found"
|
||||
fi
|
||||
|
||||
echo "📦 Loading image"
|
||||
docker load < /tmp/merchbay.tar.gz
|
||||
|
||||
echo "🧹 Removing dev images and old merchbay images"
|
||||
docker images | grep "merchbay:dev" | awk '{print $3}' | xargs -r docker rmi -f || true
|
||||
docker images | grep merchbay | grep -v "$(docker images merchbay: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_*, PROD_PRIVATE, IMAGES_URL, UPLOAD_URL"
|
||||
echo " - MAIL_*, CAPTCHA_*, ANALYTICS_*"
|
||||
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_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.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://merchbay.com"
|
||||
EOF
|
||||
|
||||
# 6️⃣ Health check
|
||||
- name: Health check
|
||||
shell: sh
|
||||
run: |
|
||||
echo "⏳ Waiting for app to be ready..."
|
||||
sleep 20
|
||||
|
||||
echo "🔍 Testing health check..."
|
||||
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" --max-time 30 https://merchbay.com || 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_app"
|
||||
echo ""
|
||||
echo " 2. Check app logs:"
|
||||
echo " docker logs merchbay_app"
|
||||
echo ""
|
||||
echo " 3. Check Traefik logs:"
|
||||
echo " docker logs traefik"
|
||||
echo ""
|
||||
echo " 4. Test manually:"
|
||||
echo " curl -Ik https://merchbay.com"
|
||||
exit 1
|
||||
fi
|
||||
125
DIGICERT_SSL_SETUP.md
Normal file
125
DIGICERT_SSL_SETUP.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# DigiCert SSL Certificate Setup for Production
|
||||
|
||||
## Certificate Files Required
|
||||
|
||||
From DigiCert, you'll receive these files:
|
||||
- `merchbay_com.crt` - Your domain certificate
|
||||
- `merchbay_com.key` - Private key (generated during CSR creation)
|
||||
- `DigiCertCA.crt` - Intermediate certificate
|
||||
- `TrustedRoot.crt` - Root certificate (optional)
|
||||
|
||||
## Step 1: Combine Certificate Chain (on your local machine)
|
||||
|
||||
```bash
|
||||
# Create full chain certificate
|
||||
cat merchbay_com.crt DigiCertCA.crt > merchbay.com.crt
|
||||
|
||||
# Copy private key
|
||||
cp merchbay_com.key merchbay.com.key
|
||||
```
|
||||
|
||||
## Step 2: Upload to Production Server
|
||||
|
||||
```bash
|
||||
# SSH to production server
|
||||
ssh PROD_DEPLOY_USER@PROD_DEPLOY_HOST
|
||||
|
||||
# Create certificates directory
|
||||
sudo mkdir -p /srv/certs
|
||||
sudo chmod 700 /srv/certs
|
||||
|
||||
# Exit SSH, then upload from local machine
|
||||
scp merchbay.com.crt PROD_DEPLOY_USER@PROD_DEPLOY_HOST:/tmp/
|
||||
scp merchbay.com.key PROD_DEPLOY_USER@PROD_DEPLOY_HOST:/tmp/
|
||||
|
||||
# SSH back to server and move files
|
||||
ssh PROD_DEPLOY_USER@PROD_DEPLOY_HOST
|
||||
sudo mv /tmp/merchbay.com.crt /srv/certs/
|
||||
sudo mv /tmp/merchbay.com.key /srv/certs/
|
||||
sudo chmod 600 /srv/certs/*
|
||||
sudo chown root:root /srv/certs/*
|
||||
```
|
||||
|
||||
## Step 3: Upload Traefik Configuration
|
||||
|
||||
```bash
|
||||
# From local machine
|
||||
scp traefik-certs.yml PROD_DEPLOY_USER@PROD_DEPLOY_HOST:/tmp/
|
||||
|
||||
# SSH to server
|
||||
ssh PROD_DEPLOY_USER@PROD_DEPLOY_HOST
|
||||
sudo mkdir -p /srv/traefik
|
||||
sudo mv /tmp/traefik-certs.yml /srv/traefik/dynamic-certs.yml
|
||||
sudo chmod 644 /srv/traefik/dynamic-certs.yml
|
||||
```
|
||||
|
||||
## Step 4: Update Traefik Container
|
||||
|
||||
Ensure your Traefik docker-compose.yml includes:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:v2.10
|
||||
command:
|
||||
- --providers.docker=true
|
||||
- --providers.docker.exposedbydefault=false
|
||||
- --providers.file.filename=/dynamic-certs.yml
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||
- --entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- /srv/certs:/srv/certs:ro
|
||||
- /srv/traefik/dynamic-certs.yml:/dynamic-certs.yml:ro
|
||||
networks:
|
||||
- traefik-public
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
## Step 5: Restart Traefik
|
||||
|
||||
```bash
|
||||
cd /opt/traefik # or wherever your traefik docker-compose.yml is
|
||||
docker compose restart traefik
|
||||
|
||||
# Verify certificate is loaded
|
||||
docker compose logs traefik | grep -i certificate
|
||||
```
|
||||
|
||||
## Step 6: Deploy merchbay Application
|
||||
|
||||
Once Traefik is configured, deploy merchbay:
|
||||
|
||||
```bash
|
||||
cd /var/www/merchbay
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
## Verification
|
||||
|
||||
```bash
|
||||
# Check certificate
|
||||
openssl s_client -connect merchbay.com:443 -servername merchbay.com < /dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -dates
|
||||
|
||||
# Should show:
|
||||
# subject=CN = merchbay.com
|
||||
# issuer=O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
|
||||
# notBefore=...
|
||||
# notAfter=...
|
||||
```
|
||||
|
||||
## Certificate Renewal
|
||||
|
||||
DigiCert certificates typically last 1-2 years. Set a reminder to renew 30 days before expiration and repeat Steps 1-3 and 5.
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Never commit `.key` files to git
|
||||
- Keep private keys secure (600 permissions)
|
||||
- Use strong encryption for private key storage
|
||||
- Consider using a certificate management system for automatic renewal
|
||||
104
Dockerfile
104
Dockerfile
@@ -1,46 +1,86 @@
|
||||
# Use the official PHP image based on Alpine Linux
|
||||
FROM php:5.6-fpm-alpine
|
||||
# Use PHP 7.0 with Apache (has native mcrypt support for Laravel 5.0)
|
||||
FROM php:7.0-apache
|
||||
|
||||
# Install system dependencies and PHP extensions
|
||||
RUN apk --update --no-cache add \
|
||||
nginx \
|
||||
# Update to use archived Debian repositories
|
||||
RUN sed -i 's|deb.debian.org|archive.debian.org|g' /etc/apt/sources.list \
|
||||
&& sed -i 's|security.debian.org|archive.debian.org|g' /etc/apt/sources.list \
|
||||
&& sed -i '/stretch-updates/d' /etc/apt/sources.list
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y --allow-unauthenticated \
|
||||
git \
|
||||
curl \
|
||||
libpng-dev \
|
||||
libjpeg-turbo-dev \
|
||||
freetype-dev \
|
||||
libzip-dev \
|
||||
libxml2-dev \
|
||||
libmcrypt-dev \
|
||||
zip \
|
||||
unzip \
|
||||
libmcrypt-dev \
|
||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
||||
&& docker-php-ext-install gd pdo pdo_mysql zip mcrypt
|
||||
libfreetype6-dev \
|
||||
libjpeg62-turbo-dev \
|
||||
openssh-client \
|
||||
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||
&& docker-php-ext-install -j$(nproc) gd
|
||||
|
||||
# Set the working directory in the container
|
||||
WORKDIR /var/www
|
||||
# Install PHP extensions (mcrypt is built-in for PHP 7.0)
|
||||
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath mcrypt tokenizer zip
|
||||
|
||||
# Clear cache
|
||||
# RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
# Enable Apache mod_rewrite
|
||||
RUN a2enmod rewrite
|
||||
|
||||
# Copy the Laravel application files to the container
|
||||
COPY . .
|
||||
# Install Composer (version 1.x for better compatibility with Laravel 5.0)
|
||||
COPY --from=composer:1.10 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
# Set appropriate permissions for Laravel storage and bootstrap cache
|
||||
RUN chown -R www-data:www-data storage bootstrap
|
||||
# Set working directory
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Install Composer
|
||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||
# Copy existing application directory contents
|
||||
COPY . /var/www/html
|
||||
|
||||
# Install Laravel dependencies
|
||||
RUN composer install --no-plugins --no-scripts
|
||||
# Create storage directories and set permissions
|
||||
RUN mkdir -p storage/framework/views \
|
||||
storage/framework/cache \
|
||||
storage/framework/sessions \
|
||||
storage/logs \
|
||||
bootstrap/cache
|
||||
|
||||
# Generate Laravel application key
|
||||
RUN php artisan key:generate
|
||||
# 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 directory for the socket and set permissions
|
||||
RUN mkdir -p /run/php && chown www-data:www-data /run/php
|
||||
# Create .env file if it doesn't exist
|
||||
RUN if [ ! -f .env ]; then cp .env.example .env; fi
|
||||
|
||||
# Copy the www.conf file to PHP-FPM pool.d directory
|
||||
# COPY www.conf /usr/local/etc/php-fpm.d/www.conf
|
||||
# Install PHP dependencies (Laravel 5.0 compatible)
|
||||
RUN composer install --no-dev --no-interaction --prefer-dist
|
||||
|
||||
# Expose port 9000 and start php-fpm server
|
||||
EXPOSE 9000
|
||||
CMD ["php-fpm"]
|
||||
# Generate application key
|
||||
RUN php artisan key:generate || true
|
||||
|
||||
# Run Laravel 5.0 optimization
|
||||
RUN php artisan clear-compiled && php artisan optimize
|
||||
|
||||
# Note: yakpro-po obfuscation requires PHP 7.1+, incompatible with PHP 7.0
|
||||
# For code protection with PHP 7.0, consider:
|
||||
# 1. ionCube Encoder (commercial, most secure)
|
||||
# 2. Keeping source code private and using proper access controls
|
||||
# 3. Using --optimize flag in composer (already done above)
|
||||
|
||||
# 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
|
||||
|
||||
# Copy entrypoint script
|
||||
COPY docker-entrypoint.sh /usr/local/bin/
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Expose port 80
|
||||
EXPOSE 80
|
||||
|
||||
# Use entrypoint to set up permissions before starting Apache
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
CMD ["apache2-foreground"]
|
||||
133
LOCAL_DEVELOPMENT.md
Normal file
133
LOCAL_DEVELOPMENT.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Local Development Setup for Merchbay
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. **Copy local environment file:**
|
||||
```bash
|
||||
cp .env.local .env
|
||||
```
|
||||
|
||||
2. **Build and start containers:**
|
||||
```bash
|
||||
docker-compose -f docker-compose.local.yml up -d --build
|
||||
```
|
||||
|
||||
3. **Generate application key:**
|
||||
```bash
|
||||
docker exec merchbay_app_local php artisan key:generate
|
||||
```
|
||||
|
||||
4. **Run migrations:**
|
||||
```bash
|
||||
docker exec merchbay_app_local php artisan migrate
|
||||
```
|
||||
|
||||
5. **Access the application:**
|
||||
- **App:** http://localhost:8080
|
||||
- **phpMyAdmin:** http://localhost:8081
|
||||
- Username: `merchbay`
|
||||
- Password: `secret`
|
||||
|
||||
## Development Commands
|
||||
|
||||
### View logs
|
||||
```bash
|
||||
# Application logs
|
||||
docker exec merchbay_app_local tail -f storage/logs/laravel.log
|
||||
|
||||
# Apache logs
|
||||
docker logs -f merchbay_app_local
|
||||
```
|
||||
|
||||
### Run artisan commands
|
||||
```bash
|
||||
docker exec merchbay_app_local php artisan [command]
|
||||
```
|
||||
|
||||
### Access container shell
|
||||
```bash
|
||||
docker exec -it merchbay_app_local bash
|
||||
```
|
||||
|
||||
### Database access
|
||||
```bash
|
||||
docker exec -it merchbay_db_local mysql -u merchbay -psecret merchbay
|
||||
```
|
||||
|
||||
### Clear caches
|
||||
```bash
|
||||
docker exec merchbay_app_local php artisan cache:clear
|
||||
docker exec merchbay_app_local php artisan config:clear
|
||||
docker exec merchbay_app_local php artisan view:clear
|
||||
```
|
||||
|
||||
### Stop containers
|
||||
```bash
|
||||
docker-compose -f docker-compose.local.yml down
|
||||
```
|
||||
|
||||
### Stop and remove volumes (clean slate)
|
||||
```bash
|
||||
docker-compose -f docker-compose.local.yml down -v
|
||||
```
|
||||
|
||||
## Debugging
|
||||
|
||||
### Enable Xdebug (if needed)
|
||||
Add to Dockerfile:
|
||||
```dockerfile
|
||||
RUN pecl install xdebug-2.9.8 && docker-php-ext-enable xdebug
|
||||
```
|
||||
|
||||
### Check container status
|
||||
```bash
|
||||
docker-compose -f docker-compose.local.yml ps
|
||||
```
|
||||
|
||||
### View all logs
|
||||
```bash
|
||||
docker-compose -f docker-compose.local.yml logs -f
|
||||
```
|
||||
|
||||
## Hot Reload Development
|
||||
|
||||
For live code changes without rebuilding:
|
||||
- Code changes in `.php` files are reflected immediately (via volume mount)
|
||||
- View changes are reflected immediately
|
||||
- Config/route changes require cache clearing
|
||||
|
||||
## Database Management
|
||||
|
||||
### Import SQL dump
|
||||
```bash
|
||||
docker exec -i merchbay_db_local mysql -u merchbay -psecret merchbay < dump.sql
|
||||
```
|
||||
|
||||
### Export database
|
||||
```bash
|
||||
docker exec merchbay_db_local mysqldump -u merchbay -psecret merchbay > dump.sql
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Permission issues
|
||||
```bash
|
||||
docker exec merchbay_app_local chown -R www-data:www-data storage bootstrap/cache
|
||||
docker exec merchbay_app_local chmod -R 775 storage bootstrap/cache
|
||||
```
|
||||
|
||||
### Reset everything
|
||||
```bash
|
||||
docker-compose -f docker-compose.local.yml down -v
|
||||
docker rmi merchbay_app:local
|
||||
rm .env
|
||||
cp .env.local .env
|
||||
docker-compose -f docker-compose.local.yml up -d --build
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The local setup uses a separate MySQL container
|
||||
- All code changes are live-mounted for easy development
|
||||
- Mail is logged to `storage/logs/laravel.log` instead of being sent
|
||||
- phpMyAdmin is available for easy database management
|
||||
@@ -34,10 +34,10 @@ class UserController extends Controller
|
||||
|
||||
$post_data = array(
|
||||
'isStoreOwner' => true,
|
||||
'store_order' => $countStoreOrder[0]->count_order,
|
||||
'store_income' => $storeIncome[0]->store_income,
|
||||
'store_product_count' => $countStoreProduct[0]->store_product_count,
|
||||
'store_published_product' => $countStorePublishedProduct[0]->store_published_product
|
||||
'store_order' => isset($countStoreOrder[0]->count_order) ? $countStoreOrder[0]->count_order : 0,
|
||||
'store_income' => isset($storeIncome[0]->store_income) ? $storeIncome[0]->store_income : 0,
|
||||
'store_product_count' => isset($countStoreProduct[0]->store_product_count) ? $countStoreProduct[0]->store_product_count : 0,
|
||||
'store_published_product' => isset($countStorePublishedProduct[0]->store_published_product) ? $countStorePublishedProduct[0]->store_published_product : 0
|
||||
);
|
||||
} else {
|
||||
$post_data = array(
|
||||
|
||||
@@ -15,7 +15,11 @@ class AppServiceProvider extends ServiceProvider {
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
// Force HTTPS URLs when behind a proxy (Traefik)
|
||||
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
|
||||
\URL::forceSchema('https');
|
||||
}
|
||||
|
||||
Blade::extend(function($value) {
|
||||
return preg_replace('/\@define(.+)/', '<?php ${1}; ?>', $value);
|
||||
});
|
||||
|
||||
58
docker-compose.dev.yml
Normal file
58
docker-compose.dev.yml
Normal file
@@ -0,0 +1,58 @@
|
||||
services:
|
||||
app:
|
||||
image: merchbay:dev
|
||||
container_name: merchbay_app_dev
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-development}
|
||||
- APP_DEBUG=${APP_DEBUG:-true}
|
||||
- APP_URL=${APP_URL:-https://dev.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}
|
||||
- PROD_PRIVATE=${PROD_PRIVATE}
|
||||
- IMAGES_URL=${IMAGES_URL}
|
||||
- UPLOAD_URL=${UPLOAD_URL}
|
||||
- FORCE_HTTPS=true
|
||||
- MAIL_DRIVER=${MAIL_DRIVER}
|
||||
- MAIL_HOST=${MAIL_HOST}
|
||||
- MAIL_PORT=${MAIL_PORT}
|
||||
- MAIL_USERNAME=${MAIL_USERNAME}
|
||||
- MAIL_PASSWORD=${MAIL_PASSWORD}
|
||||
- MAIL_ENCRYPTION=${MAIL_ENCRYPTION}
|
||||
- CAPTCHA_SITE_KEY=${CAPTCHA_SITE_KEY}
|
||||
- CAPTCHA_SECRET_KEY=${CAPTCHA_SECRET_KEY}
|
||||
- ANALYTICS_SITE_ID=${ANALYTICS_SITE_ID}
|
||||
- ANALYTICS_CLIENT_ID=${ANALYTICS_CLIENT_ID}
|
||||
- ANALYTICS_SERVICE_EMAIL=${ANALYTICS_SERVICE_EMAIL}
|
||||
volumes:
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./public/uploads:/var/www/html/public/uploads
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# Development environment (dev.merchbay.app)
|
||||
- "traefik.http.routers.merchbay-dev.rule=Host(`dev.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-dev.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-dev.tls=true"
|
||||
- "traefik.http.routers.merchbay-dev.tls.certresolver=le"
|
||||
- "traefik.http.services.merchbay-dev.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.merchbay-dev-http.rule=Host(`dev.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-dev-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-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
|
||||
81
docker-compose.local.yml
Normal file
81
docker-compose.local.yml
Normal file
@@ -0,0 +1,81 @@
|
||||
services:
|
||||
db:
|
||||
image: mariadb:10.6
|
||||
platform: linux/arm64
|
||||
container_name: merchbay_db_local
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_DATABASE: merchbay
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
MYSQL_USER: merchbay
|
||||
MYSQL_PASSWORD: secret
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
networks:
|
||||
- merchbay-local
|
||||
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
container_name: merchbay_app_local
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:80"
|
||||
environment:
|
||||
- APP_ENV=local
|
||||
- APP_DEBUG=true
|
||||
- APP_URL=http://localhost:8080
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=db
|
||||
- DB_PORT=3306
|
||||
- DB_DATABASE=merchbay
|
||||
- DB_USERNAME=merchbay
|
||||
- DB_PASSWORD=secret
|
||||
- PROD_PRIVATE=http://localhost:8080
|
||||
- IMAGES_URL=http://localhost:8080
|
||||
- UPLOAD_URL=http://localhost:8080/uploads/
|
||||
- MAIL_DRIVER=log
|
||||
- MAIL_HOST=localhost
|
||||
- MAIL_PORT=1025
|
||||
- MAIL_USERNAME=null
|
||||
- MAIL_PASSWORD=null
|
||||
- MAIL_ENCRYPTION=null
|
||||
- CAPTCHA_SITE_KEY=test_key
|
||||
- CAPTCHA_SECRET_KEY=test_secret
|
||||
- ANALYTICS_SITE_ID=
|
||||
- ANALYTICS_CLIENT_ID=
|
||||
- ANALYTICS_SERVICE_EMAIL=
|
||||
volumes:
|
||||
- ./:/var/www/html
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./public/uploads:/var/www/html/public/uploads
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- merchbay-local
|
||||
|
||||
phpmyadmin:
|
||||
image: arm64v8/phpmyadmin
|
||||
platform: linux/arm64
|
||||
container_name: merchbay_phpmyadmin
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8081:80"
|
||||
environment:
|
||||
PMA_HOST: db
|
||||
PMA_PORT: 3306
|
||||
MYSQL_ROOT_PASSWORD: root
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- merchbay-local
|
||||
|
||||
networks:
|
||||
merchbay-local:
|
||||
driver: bridge
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
57
docker-compose.prod.yml
Normal file
57
docker-compose.prod.yml
Normal file
@@ -0,0 +1,57 @@
|
||||
services:
|
||||
app:
|
||||
image: merchbay:latest
|
||||
container_name: merchbay_app_prod
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- APP_ENV=${APP_ENV:-production}
|
||||
- APP_DEBUG=${APP_DEBUG:-false}
|
||||
- APP_URL=${APP_URL:-https://merchbay.com}
|
||||
- DB_CONNECTION=mysql
|
||||
- DB_HOST=${DB_HOST}
|
||||
- DB_PORT=${DB_PORT:-3306}
|
||||
- DB_DATABASE=${DB_DATABASE}
|
||||
- DB_USERNAME=${DB_USERNAME}
|
||||
- DB_PASSWORD=${DB_PASSWORD}
|
||||
- PROD_PRIVATE=${PROD_PRIVATE}
|
||||
- IMAGES_URL=${IMAGES_URL}
|
||||
- UPLOAD_URL=${UPLOAD_URL}
|
||||
- FORCE_HTTPS=true
|
||||
- MAIL_DRIVER=${MAIL_DRIVER}
|
||||
- MAIL_HOST=${MAIL_HOST}
|
||||
- MAIL_PORT=${MAIL_PORT}
|
||||
- MAIL_USERNAME=${MAIL_USERNAME}
|
||||
- MAIL_PASSWORD=${MAIL_PASSWORD}
|
||||
- MAIL_ENCRYPTION=${MAIL_ENCRYPTION}
|
||||
- CAPTCHA_SITE_KEY=${CAPTCHA_SITE_KEY}
|
||||
- CAPTCHA_SECRET_KEY=${CAPTCHA_SECRET_KEY}
|
||||
- ANALYTICS_SITE_ID=${ANALYTICS_SITE_ID}
|
||||
- ANALYTICS_CLIENT_ID=${ANALYTICS_CLIENT_ID}
|
||||
- ANALYTICS_SERVICE_EMAIL=${ANALYTICS_SERVICE_EMAIL}
|
||||
volumes:
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./public/uploads:/var/www/html/public/uploads
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# Production environment (merchbay.com) - Uses DigiCert SSL
|
||||
- "traefik.http.routers.merchbay-prod.rule=Host(`merchbay.com`) || Host(`www.merchbay.com`)"
|
||||
- "traefik.http.routers.merchbay-prod.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-prod.tls=true"
|
||||
- "traefik.http.services.merchbay-prod.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect
|
||||
- "traefik.http.routers.merchbay-prod-http.rule=Host(`merchbay.com`) || Host(`www.merchbay.com`)"
|
||||
- "traefik.http.routers.merchbay-prod-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-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
|
||||
@@ -1,45 +1,74 @@
|
||||
version: '3'
|
||||
# ⚠️ DEPRECATED: Use docker-compose.dev.yml or docker-compose.prod.yml instead
|
||||
# This file is kept for reference only
|
||||
#
|
||||
# For development: docker-compose.dev.yml (dev.merchbay.app)
|
||||
# For production: docker-compose.prod.yml (merchbay.com)
|
||||
# For local dev: docker-compose.local.yml (localhost:8080)
|
||||
|
||||
services:
|
||||
|
||||
#PHP Service
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: digitalocean.com/php
|
||||
container_name: app
|
||||
image: merchbay:latest
|
||||
container_name: merchbay_app
|
||||
restart: unless-stopped
|
||||
tty: true
|
||||
environment:
|
||||
SERVICE_NAME: app
|
||||
SERVICE_TAGS: dev
|
||||
working_dir: /var/www
|
||||
- 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}
|
||||
- PROD_PRIVATE=${PROD_PRIVATE}
|
||||
- IMAGES_URL=${IMAGES_URL}
|
||||
- UPLOAD_URL=${UPLOAD_URL}
|
||||
- FORCE_HTTPS=true
|
||||
- MAIL_DRIVER=${MAIL_DRIVER}
|
||||
- MAIL_HOST=${MAIL_HOST}
|
||||
- MAIL_PORT=${MAIL_PORT}
|
||||
- MAIL_USERNAME=${MAIL_USERNAME}
|
||||
- MAIL_PASSWORD=${MAIL_PASSWORD}
|
||||
- MAIL_ENCRYPTION=${MAIL_ENCRYPTION}
|
||||
- CAPTCHA_SITE_KEY=${CAPTCHA_SITE_KEY}
|
||||
- CAPTCHA_SECRET_KEY=${CAPTCHA_SECRET_KEY}
|
||||
- ANALYTICS_SITE_ID=${ANALYTICS_SITE_ID}
|
||||
- ANALYTICS_CLIENT_ID=${ANALYTICS_CLIENT_ID}
|
||||
- ANALYTICS_SERVICE_EMAIL=${ANALYTICS_SERVICE_EMAIL}
|
||||
volumes:
|
||||
- ./:/var/www
|
||||
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
|
||||
- ./storage:/var/www/html/storage
|
||||
- ./public/uploads:/var/www/html/public/uploads
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
# Development environment (dev.merchbay.app)
|
||||
- "traefik.http.routers.merchbay-dev.rule=Host(`dev.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-dev.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-dev.tls=true"
|
||||
- "traefik.http.routers.merchbay-dev.tls.certresolver=letsencrypt"
|
||||
- "traefik.http.services.merchbay-dev.loadbalancer.server.port=80"
|
||||
# Production environment (merchbay.com) - Uses DigiCert SSL
|
||||
- "traefik.http.routers.merchbay-prod.rule=Host(`merchbay.com`) || Host(`www.merchbay.com`)"
|
||||
- "traefik.http.routers.merchbay-prod.entrypoints=websecure"
|
||||
- "traefik.http.routers.merchbay-prod.tls=true"
|
||||
- "traefik.http.services.merchbay-prod.loadbalancer.server.port=80"
|
||||
# HTTP to HTTPS redirect - Development
|
||||
- "traefik.http.routers.merchbay-dev-http.rule=Host(`dev.merchbay.app`)"
|
||||
- "traefik.http.routers.merchbay-dev-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-dev-http.middlewares=https-redirect"
|
||||
# HTTP to HTTPS redirect - Production
|
||||
- "traefik.http.routers.merchbay-prod-http.rule=Host(`merchbay.com`) || Host(`www.merchbay.com`)"
|
||||
- "traefik.http.routers.merchbay-prod-http.entrypoints=web"
|
||||
- "traefik.http.routers.merchbay-prod-http.middlewares=https-redirect"
|
||||
- "traefik.http.middlewares.https-redirect.redirectscheme.scheme=https"
|
||||
networks:
|
||||
- app-network
|
||||
- traefik-public
|
||||
- crew-app-net
|
||||
- default
|
||||
|
||||
#Nginx Service
|
||||
webserver:
|
||||
image: nginx:alpine
|
||||
container_name: webserver
|
||||
restart: unless-stopped
|
||||
tty: true
|
||||
ports:
|
||||
- "10003:80"
|
||||
- "10443:443"
|
||||
volumes:
|
||||
- ./:/var/www
|
||||
- ./nginx/conf.d/:/etc/nginx/conf.d/
|
||||
networks:
|
||||
- app-network
|
||||
|
||||
#Docker Networks
|
||||
networks:
|
||||
app-network:
|
||||
traefik-public:
|
||||
external: true
|
||||
crew-app-net:
|
||||
external: true
|
||||
default:
|
||||
driver: bridge
|
||||
#Volumes
|
||||
volumes:
|
||||
dbdata:
|
||||
driver: local
|
||||
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 "$@"
|
||||
176
readme.md
176
readme.md
@@ -1,23 +1,171 @@
|
||||
## Laravel PHP Framework
|
||||
# MerchBay
|
||||
|
||||
[](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 custom merchandise and apparel design platform built with Laravel 5.0, enabling users to create, customize, and order personalized products.
|
||||
|
||||
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.
|
||||
## 🚀 Tech Stack
|
||||
|
||||
Laravel is accessible, yet powerful, providing powerful 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.
|
||||
- **Framework:** Laravel 5.0
|
||||
- **PHP:** 7.0 with native mcrypt support
|
||||
- **Web Server:** Apache 2.4
|
||||
- **Database:** MySQL
|
||||
- **Container:** Docker with Apache
|
||||
- **Reverse Proxy:** Traefik (for SSL/TLS and routing)
|
||||
|
||||
## Official Documentation
|
||||
## 📋 Prerequisites
|
||||
|
||||
Documentation for the framework can be found on the [Laravel website](http://laravel.com/docs).
|
||||
- Docker and Docker Compose
|
||||
- Git
|
||||
- Access to deployment server (for production/dev deployments)
|
||||
|
||||
## Contributing
|
||||
## 🛠️ Local Development
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](http://laravel.com/docs/contributions).
|
||||
### Building the Docker Image
|
||||
|
||||
### License
|
||||
```bash
|
||||
docker build -t merchbay:dev .
|
||||
```
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT)
|
||||
### Running Locally
|
||||
|
||||
```bash
|
||||
# Create .env file from example
|
||||
cp .env.example .env
|
||||
|
||||
# Update .env with your local configuration
|
||||
# Set database credentials, mail settings, etc.
|
||||
|
||||
# Run with docker-compose (customize docker-compose.yml for local setup)
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
The following environment variables are required:
|
||||
|
||||
#### Database Configuration
|
||||
- `DB_HOST` - Database host
|
||||
- `DB_PORT` - Database port (default: 3306)
|
||||
- `DB_DATABASE` - Database name
|
||||
- `DB_USERNAME` - Database username
|
||||
- `DB_PASSWORD` - Database password
|
||||
|
||||
#### Application URLs
|
||||
- `APP_URL` - Application base URL
|
||||
- `PROD_PRIVATE` - Production private server URL
|
||||
- `IMAGES_URL` - Images server URL
|
||||
- `UPLOAD_URL` - Upload directory URL
|
||||
|
||||
#### Mail Configuration
|
||||
- `MAIL_DRIVER` - Mail driver (smtp)
|
||||
- `MAIL_HOST` - SMTP host
|
||||
- `MAIL_PORT` - SMTP port
|
||||
- `MAIL_USERNAME` - SMTP username
|
||||
- `MAIL_PASSWORD` - SMTP password
|
||||
- `MAIL_ENCRYPTION` - Encryption type (tls/ssl)
|
||||
|
||||
#### Third-Party Services
|
||||
- `CAPTCHA_SITE_KEY` - reCAPTCHA site key
|
||||
- `CAPTCHA_SECRET_KEY` - reCAPTCHA secret key
|
||||
- `ANALYTICS_SITE_ID` - Google Analytics site ID
|
||||
- `ANALYTICS_CLIENT_ID` - Google Analytics client ID
|
||||
- `ANALYTICS_SERVICE_EMAIL` - Google Analytics service email
|
||||
|
||||
## 🚢 Deployment
|
||||
|
||||
### Automated CI/CD with Gitea Actions
|
||||
|
||||
This project includes automated deployment workflows using Gitea Actions:
|
||||
|
||||
#### Development Deployment
|
||||
Push to the `dev` branch to automatically deploy to dev environment:
|
||||
```bash
|
||||
git push origin dev
|
||||
```
|
||||
- Deploys to: `https://dev.merchbay.app`
|
||||
|
||||
#### Production Deployment
|
||||
Push to the `main` or `master` branch to automatically deploy to production:
|
||||
```bash
|
||||
git push origin main
|
||||
```
|
||||
- Deploys to: `https://merchbay.app`
|
||||
|
||||
#### Docker Registry
|
||||
Create version tags to build and push to Docker registry:
|
||||
```bash
|
||||
git tag -a v1.0.0 -m "Release v1.0.0"
|
||||
git push origin v1.0.0
|
||||
```
|
||||
|
||||
### Workflow Files
|
||||
|
||||
- `.gitea/workflows/deploy-dev.yml` - Development deployment
|
||||
- `.gitea/workflows/deploy.yml` - Production deployment
|
||||
- `.gitea/workflows/build-push.yml` - Docker image build and push
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
merchbay/
|
||||
├── app/ # Application core
|
||||
│ ├── Http/ # Controllers, middleware, routes
|
||||
│ ├── Models/ # Database models
|
||||
│ └── Services/ # Business logic services
|
||||
├── config/ # Configuration files
|
||||
├── database/ # Migrations and seeds
|
||||
├── public/ # Public assets (images, CSS, JS)
|
||||
├── resources/ # Views and frontend assets
|
||||
├── storage/ # Application storage
|
||||
├── docker-compose.yml # Docker compose configuration
|
||||
├── Dockerfile # Docker image definition
|
||||
└── docker-entrypoint.sh # Container startup script
|
||||
```
|
||||
|
||||
## 🔧 Development Notes
|
||||
|
||||
### Storage Permissions
|
||||
|
||||
The Docker entrypoint automatically creates and sets proper permissions for:
|
||||
- `storage/framework/views`
|
||||
- `storage/framework/cache`
|
||||
- `storage/framework/sessions`
|
||||
- `storage/logs`
|
||||
- `bootstrap/cache`
|
||||
|
||||
### PHP Extensions
|
||||
|
||||
The following PHP extensions are installed:
|
||||
- pdo_mysql
|
||||
- mbstring
|
||||
- exif
|
||||
- pcntl
|
||||
- bcmath
|
||||
- mcrypt (native in PHP 7.0)
|
||||
- tokenizer
|
||||
- zip
|
||||
- gd (with freetype and jpeg support)
|
||||
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
### 500 Internal Server Error
|
||||
|
||||
1. Check container logs: `docker logs merchbay_app`
|
||||
2. Verify storage permissions are set correctly
|
||||
3. Ensure all environment variables are configured in `.env`
|
||||
4. Check database connectivity
|
||||
|
||||
### Storage Permission Issues
|
||||
|
||||
The entrypoint script automatically fixes permissions on container start. If issues persist:
|
||||
```bash
|
||||
docker exec merchbay_app chown -R www-data:www-data storage bootstrap/cache
|
||||
docker exec merchbay_app chmod -R 775 storage bootstrap/cache
|
||||
```
|
||||
|
||||
## 📄 License
|
||||
|
||||
Proprietary - All rights reserved
|
||||
|
||||
## 🤝 Support
|
||||
|
||||
For support and questions, contact the development team.
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
||||
|
||||
<title>Merchbay</title>
|
||||
<link rel="icon" href="{{ asset('public/favicon.ico') }}">
|
||||
<link rel="icon" href="{{ asset('/favicon.ico') }}">
|
||||
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;400;500;600;700;800;900&display=swap" rel="stylesheet">
|
||||
|
||||
<link href="{{ asset('public/assets/css/merchbay/styles.css') }}" rel="stylesheet">
|
||||
<!-- <link href="{{ asset('public/assets/login/css/style.css') }}" rel="stylesheet">
|
||||
<link href="{{ asset('public/assets/login/css/form-elements.css') }}" rel="stylesheet"> -->
|
||||
<link href="{{ asset('/assets/css/merchbay/styles.css') }}" rel="stylesheet">
|
||||
<!-- <link href="{{ asset('/assets/login/css/style.css') }}" rel="stylesheet">
|
||||
<link href="{{ asset('/assets/login/css/form-elements.css') }}" rel="stylesheet"> -->
|
||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-SB3QK6BR1N"></script>
|
||||
@@ -258,7 +258,7 @@
|
||||
}
|
||||
|
||||
function fetchCanada() {
|
||||
$.getJSON("{{ asset('/public/api/canada.json') }}", function(items) {
|
||||
$.getJSON("{{ asset('//api/canada.json') }}", function(items) {
|
||||
var states = [];
|
||||
|
||||
Object.keys(items).forEach(function(state) {
|
||||
@@ -307,7 +307,7 @@
|
||||
}
|
||||
|
||||
function fetchUSA() {
|
||||
$.getJSON("{{ asset('/public/api/usaCities.json') }}", function(data) {
|
||||
$.getJSON("{{ asset('//api/usaCities.json') }}", function(data) {
|
||||
var states = [];
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
|
||||
@@ -86,54 +86,6 @@
|
||||
</div>
|
||||
<!-- ./col -->
|
||||
</div>
|
||||
{{-- <div class="row">
|
||||
<div class="col-lg-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">Total Sales</h3>
|
||||
<div class="box-tools">
|
||||
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div class="well">
|
||||
<div class="form-group col-md-3">
|
||||
<label class="control-label">Select Year: <span class="required">*</span></label>
|
||||
<select type="text" class="form-control" placeholder="Select Select Year">
|
||||
<option value="2020">2020</option>
|
||||
<option value="2019">2019</option>
|
||||
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col-md-3">
|
||||
<label class="control-label">Select Month <span class="required">*</span></label>
|
||||
<select class="form-control" placeholder="Select Date">
|
||||
<option value="">January</option>
|
||||
<option value="">February</option>
|
||||
<option value="">March</option>
|
||||
<option value="">April</option>
|
||||
<option value="">May</option>
|
||||
<option value="">June</option>
|
||||
<option value="">July</option>
|
||||
<option value="">August</option>
|
||||
<option value="">September</option>
|
||||
<option value="">October</option>
|
||||
<option value="">November</option>
|
||||
<option value="">December</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
<div class="chart">
|
||||
<canvas id="myChart" style="height:350px"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /.box-body -->
|
||||
</div>
|
||||
</div>
|
||||
</div> --}}
|
||||
|
||||
@else
|
||||
<div class="text-center" id="homepage-logo">
|
||||
|
||||
@@ -13,37 +13,37 @@
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<!-- Bootstrap 3.3.6 -->
|
||||
<link rel="stylesheet" href="{{asset('/public/bower_components/AdminLTE/bootstrap/css/bootstrap.min.css')}}">
|
||||
<link rel="stylesheet" href="{{asset('/bower_components/AdminLTE/bootstrap/css/bootstrap.min.css')}}">
|
||||
<!-- Font Awesome -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
|
||||
<!-- Ionicons -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css">
|
||||
<!-- Theme style -->
|
||||
<link rel="stylesheet" href="{{asset('/public/bower_components/AdminLTE/dist/css/AdminLTE.min.css')}}">
|
||||
<link rel="stylesheet" href="{{asset('/bower_components/AdminLTE/dist/css/AdminLTE.min.css')}}">
|
||||
<!-- AdminLTE Skins. Choose a skin from the css/skins
|
||||
folder instead of downloading all of them to reduce the load. -->
|
||||
<link rel="stylesheet" href="{{asset('/public/bower_components/AdminLTE/dist/css/skins/_all-skins.min.css')}}">
|
||||
<link rel="stylesheet" href="{{asset('/bower_components/AdminLTE/dist/css/skins/_all-skins.min.css')}}">
|
||||
<!-- iCheck -->
|
||||
<link rel="stylesheet" href="{{asset('/public/bower_components/AdminLTE/plugins/iCheck/flat/blue.css')}}">
|
||||
<link rel="stylesheet" href="{{asset('/bower_components/AdminLTE/plugins/iCheck/flat/blue.css')}}">
|
||||
<!-- Date Picker -->
|
||||
<link rel="stylesheet" href="{{asset('/public/bower_components/AdminLTE/plugins/datepicker/datepicker3.css')}}">
|
||||
<link rel="stylesheet" href="{{asset('/bower_components/AdminLTE/plugins/datepicker/datepicker3.css')}}">
|
||||
<!-- Daterange picker -->
|
||||
<link rel="stylesheet" href="{{asset('/public/bower_components/AdminLTE/plugins/daterangepicker/daterangepicker.css')}}">
|
||||
<link rel="stylesheet" href="{{asset('/bower_components/AdminLTE/plugins/daterangepicker/daterangepicker.css')}}">
|
||||
<!-- bootstrap wysihtml5 - text editor -->
|
||||
<link rel="stylesheet" href="{{asset('/public/bower_components/AdminLTE/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css')}}">
|
||||
<link rel="stylesheet" href="{{asset('/bower_components/AdminLTE/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.min.css')}}">
|
||||
<!-- Select2 -->
|
||||
<link href="{{asset('/public/bower_components/AdminLTE/plugins/select2/select2.min.css')}}" rel="stylesheet" />
|
||||
<link href="{{asset('/bower_components/AdminLTE/plugins/select2/select2.min.css')}}" rel="stylesheet" />
|
||||
<!-- ekko-lightbox -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/ekko-lightbox/5.3.0/ekko-lightbox.css" rel="stylesheet">
|
||||
<!-- bootstrap-toggle -->
|
||||
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
|
||||
<!-- DataTables -->
|
||||
<link rel="stylesheet" href="{{ asset('/public/bower_components/AdminLTE/plugins/datatables.net-bs/css/dataTables.bootstrap.min.css') }}">
|
||||
<link rel="stylesheet" href="{{ asset('/bower_components/AdminLTE/plugins/datatables.net-bs/css/dataTables.bootstrap.min.css') }}">
|
||||
<!-- datepicker -->
|
||||
<link rel="stylesheet" href="{{ asset('/public/bower_components/AdminLTE/plugins/datepicker/datepicker3.css') }}">
|
||||
<link rel="stylesheet" href="{{ asset('/bower_components/AdminLTE/plugins/datepicker/datepicker3.css') }}">
|
||||
<!-- jquery-ui -->
|
||||
<link href="{{ asset('/public/assets/css/jquery-ui.css') }}" rel="stylesheet">
|
||||
<link href="{{asset('/public/designer/css/build.css')}}" rel="stylesheet">
|
||||
<link href="{{ asset('/assets/css/jquery-ui.css') }}" rel="stylesheet">
|
||||
<link href="{{asset('/designer/css/build.css')}}" rel="stylesheet">
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14"></script>
|
||||
@@ -628,41 +628,41 @@
|
||||
<!-- ./wrapper -->
|
||||
|
||||
<!-- jQuery 2.2.3 -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/plugins/jQuery/jquery-2.2.3.min.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/plugins/jQuery/jquery-2.2.3.min.js')}}"></script>
|
||||
<!-- Bootstrap 3.3.6 -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/bootstrap/js/bootstrap.min.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/bootstrap/js/bootstrap.min.js')}}"></script>
|
||||
|
||||
<!-- daterangepicker -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.11.2/moment.min.js"></script>
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/plugins/daterangepicker/daterangepicker.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/plugins/daterangepicker/daterangepicker.js')}}"></script>
|
||||
<!-- datepicker -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/plugins/datepicker/bootstrap-datepicker.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/plugins/datepicker/bootstrap-datepicker.js')}}"></script>
|
||||
<!-- Bootstrap WYSIHTML5 -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.min.js')}}"></script>
|
||||
<!-- Slimscroll -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/plugins/slimScroll/jquery.slimscroll.min.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/plugins/slimScroll/jquery.slimscroll.min.js')}}"></script>
|
||||
<!-- FastClick -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/plugins/fastclick/fastclick.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/plugins/fastclick/fastclick.js')}}"></script>
|
||||
<!-- AdminLTE App -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/dist/js/app.min.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/dist/js/app.min.js')}}"></script>
|
||||
<!-- AdminLTE dashboard demo (This is only for demo purposes)
|
||||
<script src="{{asset('/bower_components/AdminLTE/dist/js/pages/dashboard.js')}}"></script>-->
|
||||
<!-- AdminLTE for demo purposes -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/dist/js/demo.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/dist/js/demo.js')}}"></script>
|
||||
|
||||
<!-- Select2 -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
|
||||
<!-- validate jquery -->
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
|
||||
<!-- \priceformat -->
|
||||
<script src="{{asset('/public/designer/js/jquery.priceformat.min.js')}}"></script>
|
||||
<script src="{{asset('/designer/js/jquery.priceformat.min.js')}}"></script>
|
||||
<!-- ekko-lightbox -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ekko-lightbox/5.3.0/ekko-lightbox.js"></script>
|
||||
<!-- bootstrap-toggle -->
|
||||
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
||||
<!-- DataTables -->
|
||||
<script src="{{ asset('/public/bower_components/AdminLTE/plugins/datatables.net/js/jquery.dataTables.min.js') }}"></script>
|
||||
<script src="{{ asset('/public/bower_components/AdminLTE/plugins/datatables.net-bs/js/dataTables.bootstrap.min.js') }}"></script>
|
||||
<script src="{{ asset('/bower_components/AdminLTE/plugins/datatables.net/js/jquery.dataTables.min.js') }}"></script>
|
||||
<script src="{{ asset('/bower_components/AdminLTE/plugins/datatables.net-bs/js/dataTables.bootstrap.min.js') }}"></script>
|
||||
<script src="https://cdn.datatables.net/buttons/1.5.6/js/dataTables.buttons.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/buttons/1.5.6/js/buttons.flash.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
|
||||
@@ -671,9 +671,9 @@
|
||||
<script src="https://cdn.datatables.net/buttons/1.5.6/js/buttons.html5.min.js"></script>
|
||||
<script src="https://cdn.datatables.net/buttons/1.5.6/js/buttons.print.min.js"></script>
|
||||
<!-- datepicker -->
|
||||
<script src="{{asset('/public/bower_components/AdminLTE/plugins/datepicker/bootstrap-datepicker.js')}}"></script>
|
||||
<script src="{{asset('/bower_components/AdminLTE/plugins/datepicker/bootstrap-datepicker.js')}}"></script>
|
||||
<!-- jquery-ui -->
|
||||
<script src="{{ asset('/public/assets/js/jquery-ui.js') }}"></script>
|
||||
<script src="{{ asset('/assets/js/jquery-ui.js') }}"></script>
|
||||
{{-- Chartjs --}}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
|
||||
|
||||
@@ -1791,7 +1791,7 @@
|
||||
}
|
||||
|
||||
function fetchCanada() {
|
||||
$.getJSON("{{ asset('/public/api/canada.json') }}", function(items) {
|
||||
$.getJSON("{{ asset('/api/canada.json') }}", function(items) {
|
||||
var states = [];
|
||||
|
||||
Object.keys(items).forEach(function(state) {
|
||||
@@ -1840,7 +1840,7 @@
|
||||
}
|
||||
|
||||
function fetchUSA() {
|
||||
$.getJSON("{{ asset('/public/api/usaCities.json') }}", function(data) {
|
||||
$.getJSON("{{ asset('/api/usaCities.json') }}", function(data) {
|
||||
var states = [];
|
||||
|
||||
for (i = 0; i < data.length; i++) {
|
||||
|
||||
17
traefik-certs.yml
Normal file
17
traefik-certs.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
# Traefik Dynamic Configuration for Custom SSL Certificates
|
||||
# This file should be uploaded to /srv/traefik/dynamic/traefik-certs.yml on production server
|
||||
|
||||
tls:
|
||||
certificates:
|
||||
# Production SSL Certificate (DigiCert)
|
||||
# Note: merchbay.com.crt should be a bundle containing www_merchbay_com.crt + DigiCertCA.crt
|
||||
- certFile: /srv/certs/merchbay.com.crt
|
||||
keyFile: /srv/certs/merchbay.com.key
|
||||
stores:
|
||||
- default
|
||||
|
||||
stores:
|
||||
default:
|
||||
defaultCertificate:
|
||||
certFile: /srv/certs/merchbay.com.crt
|
||||
keyFile: /srv/certs/merchbay.com.key
|
||||
54
yakpro-po.cnf
Normal file
54
yakpro-po.cnf
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
// yakpro-po configuration for Laravel 5.0
|
||||
|
||||
$conf = new StdClass;
|
||||
|
||||
// Directories to obfuscate (relative to project root)
|
||||
$conf->t_directories = [
|
||||
'app'
|
||||
];
|
||||
|
||||
// Directories/files to skip
|
||||
$conf->t_skip = [
|
||||
'vendor',
|
||||
'storage',
|
||||
'bootstrap',
|
||||
'config',
|
||||
'database',
|
||||
'public',
|
||||
'resources',
|
||||
'tests',
|
||||
'.env',
|
||||
'.env.example',
|
||||
'artisan',
|
||||
'server.php'
|
||||
];
|
||||
|
||||
// Obfuscation options
|
||||
$conf->obfuscate_string_literal = false; // Don't obfuscate strings (can break Laravel)
|
||||
$conf->obfuscate_function_name = true; // Obfuscate function names
|
||||
$conf->obfuscate_class_name = true; // Obfuscate class names (except Laravel core)
|
||||
$conf->obfuscate_variable_name = true; // Obfuscate variable names
|
||||
$conf->obfuscate_property_name = true; // Obfuscate property names
|
||||
$conf->obfuscate_class_constant_name = true;
|
||||
$conf->obfuscate_constant_name = true;
|
||||
$conf->obfuscate_namespace_name = false; // Keep namespaces readable
|
||||
$conf->obfuscate_label_name = true;
|
||||
|
||||
// Keep Laravel framework methods/classes readable
|
||||
$conf->t_ignore_constants = ['APP_ENV', 'APP_DEBUG', 'APP_URL', 'APP_KEY'];
|
||||
$conf->t_ignore_methods = [
|
||||
'__construct', '__destruct', '__call', '__get', '__set',
|
||||
'boot', 'register', 'handle', 'middleware', 'authorize'
|
||||
];
|
||||
|
||||
// Scrambler mode
|
||||
$conf->scrambler = true;
|
||||
|
||||
// Allow multiple PHP versions
|
||||
$conf->allow_and_operator = true;
|
||||
|
||||
// Output directory (will be overridden in command)
|
||||
$conf->t_dir = null;
|
||||
|
||||
return $conf;
|
||||
Reference in New Issue
Block a user