Compare commits
1 Commits
dev
...
unfinished
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02c7f4e2aa |
63
.dockerignore
Normal file
63
.dockerignore
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Git files
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.gitattributes
|
||||||
|
|
||||||
|
# Docker files
|
||||||
|
Dockerfile*
|
||||||
|
docker-compose*.yml
|
||||||
|
.dockerignore
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
README.md
|
||||||
|
DEPLOYMENT_GUIDE.md
|
||||||
|
*.md
|
||||||
|
|
||||||
|
# Development files
|
||||||
|
.env.example
|
||||||
|
.env.local
|
||||||
|
.env.testing
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Node modules and build files
|
||||||
|
node_modules/
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# Laravel specific
|
||||||
|
/vendor
|
||||||
|
/storage/logs/*
|
||||||
|
!/storage/logs/.gitkeep
|
||||||
|
/storage/framework/cache/*
|
||||||
|
!/storage/framework/cache/.gitkeep
|
||||||
|
/storage/framework/sessions/*
|
||||||
|
!/storage/framework/sessions/.gitkeep
|
||||||
|
/storage/framework/views/*
|
||||||
|
!/storage/framework/views/.gitkeep
|
||||||
|
/bootstrap/cache/*
|
||||||
|
!/bootstrap/cache/.gitkeep
|
||||||
|
|
||||||
|
# Testing
|
||||||
|
/tests
|
||||||
|
phpunit.xml
|
||||||
|
phpspec.yml
|
||||||
|
|
||||||
|
# Build tools
|
||||||
|
gulpfile.js
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
# Scripts
|
||||||
|
start-local.sh
|
||||||
|
rebuild.sh
|
||||||
229
DEPLOYMENT_GUIDE.md
Normal file
229
DEPLOYMENT_GUIDE.md
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
# Google Cloud Run Deployment Guide for Merchbay Laravel Application
|
||||||
|
|
||||||
|
This guide will help you deploy your Laravel 5 application to Google Cloud Run using the provided `cloudbuild.yaml` configuration.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. **Google Cloud Project**: Ensure you have a Google Cloud Project with billing enabled
|
||||||
|
2. **APIs Enabled**: Enable the following APIs:
|
||||||
|
- Cloud Build API
|
||||||
|
- Cloud Run API
|
||||||
|
- Container Registry API (or Artifact Registry API)
|
||||||
|
- Cloud SQL API (if using Cloud SQL)
|
||||||
|
- Secret Manager API (recommended for secrets)
|
||||||
|
|
||||||
|
3. **gcloud CLI**: Install and configure the Google Cloud CLI
|
||||||
|
|
||||||
|
## Pre-deployment Setup
|
||||||
|
|
||||||
|
### 1. Create Cloud SQL Instance (Recommended)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create MySQL instance
|
||||||
|
gcloud sql instances create merchbay-db \
|
||||||
|
--database-version=MYSQL_8_0 \
|
||||||
|
--tier=db-f1-micro \
|
||||||
|
--region=us-central1
|
||||||
|
|
||||||
|
# Create database
|
||||||
|
gcloud sql databases create merchbay --instance=merchbay-db
|
||||||
|
|
||||||
|
# Create user
|
||||||
|
gcloud sql users create laravel_user \
|
||||||
|
--instance=merchbay-db \
|
||||||
|
--password=YOUR_SECURE_PASSWORD
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Store Secrets in Secret Manager
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Application key (generate a new one)
|
||||||
|
echo "base64:$(openssl rand -base64 32)" | gcloud secrets create APP_KEY --data-file=-
|
||||||
|
|
||||||
|
# Database password
|
||||||
|
echo "YOUR_DB_PASSWORD" | gcloud secrets create DB_PASSWORD --data-file=-
|
||||||
|
|
||||||
|
# PayPal secrets
|
||||||
|
echo "YOUR_PAYPAL_LIVE_SECRET" | gcloud secrets create PAYPAL_LIVE_SECRET --data-file=-
|
||||||
|
echo "YOUR_PAYPAL_SANDBOX_SECRET" | gcloud secrets create PAYPAL_SANDBOX_SECRET --data-file=-
|
||||||
|
|
||||||
|
# Mail password
|
||||||
|
echo "YOUR_MAIL_PASSWORD" | gcloud secrets create MAIL_PASSWORD --data-file=-
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Update cloudbuild.yaml Variables
|
||||||
|
|
||||||
|
Update the substitution variables in `cloudbuild.yaml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
substitutions:
|
||||||
|
_SERVICE_NAME: 'merchbay-laravel'
|
||||||
|
_REGION: 'us-central1' # Change to your preferred region
|
||||||
|
_CLOUDSQL_INSTANCE: 'YOUR_PROJECT_ID:us-central1:merchbay-db'
|
||||||
|
_DB_DATABASE: 'merchbay'
|
||||||
|
_DB_USERNAME: 'laravel_user'
|
||||||
|
# ... other variables
|
||||||
|
```
|
||||||
|
|
||||||
|
## Deployment Steps
|
||||||
|
|
||||||
|
### 1. Set up Cloud Build Trigger
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Connect your repository to Cloud Build
|
||||||
|
gcloud builds triggers create github \
|
||||||
|
--repo-name=YOUR_REPO_NAME \
|
||||||
|
--repo-owner=YOUR_GITHUB_USERNAME \
|
||||||
|
--branch-pattern="^main$" \
|
||||||
|
--build-config=cloudbuild.yaml
|
||||||
|
|
||||||
|
# Or trigger manually
|
||||||
|
gcloud builds submit --config=cloudbuild.yaml .
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Manual Deployment (Alternative)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Set your project ID
|
||||||
|
export PROJECT_ID=your-project-id
|
||||||
|
|
||||||
|
# Build and deploy
|
||||||
|
gcloud builds submit --config=cloudbuild.yaml \
|
||||||
|
--substitutions=_PROJECT_ID=$PROJECT_ID,_SERVICE_NAME=merchbay-laravel
|
||||||
|
```
|
||||||
|
|
||||||
|
## Post-deployment Tasks
|
||||||
|
|
||||||
|
### 1. Run Database Migrations
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a one-time job for migrations
|
||||||
|
gcloud run jobs create laravel-migrate \
|
||||||
|
--image=gcr.io/$PROJECT_ID/merchbay-laravel:latest \
|
||||||
|
--region=us-central1 \
|
||||||
|
--set-env-vars="APP_ENV=production" \
|
||||||
|
--set-cloudsql-instances=$PROJECT_ID:us-central1:merchbay-db \
|
||||||
|
--command="php" \
|
||||||
|
--args="artisan,migrate,--force" \
|
||||||
|
--max-retries=1
|
||||||
|
|
||||||
|
# Execute the migration
|
||||||
|
gcloud run jobs execute laravel-migrate --region=us-central1 --wait
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Set up Custom Domain (Optional)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Map custom domain
|
||||||
|
gcloud run domain-mappings create \
|
||||||
|
--service=merchbay-laravel \
|
||||||
|
--domain=your-domain.com \
|
||||||
|
--region=us-central1
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configure Load Balancer and CDN (Optional)
|
||||||
|
|
||||||
|
For better performance, consider setting up:
|
||||||
|
- Cloud Load Balancer
|
||||||
|
- Cloud CDN for static assets
|
||||||
|
- Cloud Storage for file uploads
|
||||||
|
|
||||||
|
## Environment Variables Reference
|
||||||
|
|
||||||
|
The following environment variables are configured in the Cloud Run service:
|
||||||
|
|
||||||
|
### Application Settings
|
||||||
|
- `APP_ENV=production`
|
||||||
|
- `APP_DEBUG=false`
|
||||||
|
- `APP_KEY` (from Secret Manager)
|
||||||
|
|
||||||
|
### Database Settings
|
||||||
|
- `DB_HOST=127.0.0.1` (Cloud SQL Proxy)
|
||||||
|
- `DB_DATABASE=merchbay`
|
||||||
|
- `DB_USERNAME=laravel_user`
|
||||||
|
- `DB_PASSWORD` (from Secret Manager)
|
||||||
|
|
||||||
|
### Cache & Session
|
||||||
|
- `CACHE_DRIVER=redis` (requires Redis setup)
|
||||||
|
- `SESSION_DRIVER=redis`
|
||||||
|
- `QUEUE_DRIVER=database`
|
||||||
|
|
||||||
|
### PayPal Configuration
|
||||||
|
- `PAYPAL_MODE=live` (or 'sandbox' for testing)
|
||||||
|
- `PAYPAL_LIVE_CLIENT_ID`
|
||||||
|
- `PAYPAL_LIVE_SECRET`
|
||||||
|
- `PAYPAL_SANDBOX_CLIENT_ID`
|
||||||
|
- `PAYPAL_SANDBOX_SECRET`
|
||||||
|
|
||||||
|
### Mail Configuration
|
||||||
|
- `MAIL_DRIVER=smtp`
|
||||||
|
- `MAIL_HOST`
|
||||||
|
- `MAIL_PORT`
|
||||||
|
- `MAIL_USERNAME`
|
||||||
|
- `MAIL_PASSWORD`
|
||||||
|
|
||||||
|
## Monitoring and Logging
|
||||||
|
|
||||||
|
### Enable Application Insights
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Enable Cloud Logging
|
||||||
|
gcloud logging sinks create laravel-logs \
|
||||||
|
bigquery.googleapis.com/projects/$PROJECT_ID/datasets/app_logs
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set up Uptime Monitoring
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create uptime check
|
||||||
|
gcloud alpha monitoring uptime create \
|
||||||
|
--display-name="Merchbay Laravel App" \
|
||||||
|
--http-check-path="/" \
|
||||||
|
--hostname=your-service-url.run.app
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **502 Bad Gateway**: Check logs with `gcloud run services logs read merchbay-laravel`
|
||||||
|
2. **Database Connection Issues**: Verify Cloud SQL instance and VPC configuration
|
||||||
|
3. **Memory Issues**: Increase memory allocation in cloudbuild.yaml
|
||||||
|
4. **Timeout Issues**: Increase timeout and check for long-running operations
|
||||||
|
|
||||||
|
### Debugging Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# View service logs
|
||||||
|
gcloud run services logs read merchbay-laravel --region=us-central1
|
||||||
|
|
||||||
|
# Get service details
|
||||||
|
gcloud run services describe merchbay-laravel --region=us-central1
|
||||||
|
|
||||||
|
# Check revisions
|
||||||
|
gcloud run revisions list --service=merchbay-laravel --region=us-central1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **Use Secret Manager** for all sensitive data
|
||||||
|
2. **Enable VPC** for database connections
|
||||||
|
3. **Configure IAM** with least privilege principle
|
||||||
|
4. **Enable Cloud Armor** for DDoS protection
|
||||||
|
5. **Use HTTPS** with managed SSL certificates
|
||||||
|
6. **Regular Updates** for dependencies and base images
|
||||||
|
|
||||||
|
## Cost Optimization
|
||||||
|
|
||||||
|
1. **Set Min Instances to 0** for cost savings
|
||||||
|
2. **Use Appropriate CPU/Memory** settings
|
||||||
|
3. **Implement Caching** (Redis/Memcached)
|
||||||
|
4. **Optimize Images** and use multi-stage builds
|
||||||
|
5. **Monitor Usage** with Cloud Monitoring
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For issues specific to:
|
||||||
|
- **Cloud Run**: Check [Cloud Run documentation](https://cloud.google.com/run/docs)
|
||||||
|
- **Laravel**: Check [Laravel documentation](https://laravel.com/docs)
|
||||||
|
- **PayPal Integration**: Check [PayPal developer documentation](https://developer.paypal.com/)
|
||||||
12
Dockerfile
12
Dockerfile
@@ -11,29 +11,23 @@ RUN apk --update --no-cache add \
|
|||||||
zip \
|
zip \
|
||||||
unzip \
|
unzip \
|
||||||
libmcrypt-dev \
|
libmcrypt-dev \
|
||||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||||
&& docker-php-ext-install gd pdo pdo_mysql zip mcrypt
|
&& docker-php-ext-install gd pdo pdo_mysql zip mcrypt
|
||||||
|
|
||||||
# Set the working directory in the container
|
# Set the working directory in the container
|
||||||
WORKDIR /var/www
|
WORKDIR /var/www
|
||||||
|
|
||||||
# Clear cache
|
|
||||||
# RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Copy the Laravel application files to the container
|
# Copy the Laravel application files to the container
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Set appropriate permissions for Laravel storage and bootstrap cache
|
# Set appropriate permissions for Laravel storage and bootstrap cache
|
||||||
RUN chown -R www-data:www-data storage bootstrap
|
RUN chown -R www-data:www-data storage bootstrap/cache
|
||||||
|
|
||||||
# Install Composer
|
# Install Composer
|
||||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
# Install Laravel dependencies
|
# Install Laravel dependencies
|
||||||
RUN composer install --no-plugins --no-scripts
|
RUN composer install --no-interaction --no-plugins --no-scripts
|
||||||
|
|
||||||
# Generate Laravel application key
|
|
||||||
RUN php artisan key:generate
|
|
||||||
|
|
||||||
# Create directory for the socket and set permissions
|
# Create directory for the socket and set permissions
|
||||||
RUN mkdir -p /run/php && chown www-data:www-data /run/php
|
RUN mkdir -p /run/php && chown www-data:www-data /run/php
|
||||||
|
|||||||
71
Dockerfile.alpine
Normal file
71
Dockerfile.alpine
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
# Debug Dockerfile - Let's try the original approach that was working
|
||||||
|
FROM php:5.6-fpm-alpine
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /var/www
|
||||||
|
|
||||||
|
# Install system dependencies and PHP extensions
|
||||||
|
RUN apk --update --no-cache add \
|
||||||
|
nginx \
|
||||||
|
libpng-dev \
|
||||||
|
libjpeg-turbo-dev \
|
||||||
|
freetype-dev \
|
||||||
|
libzip-dev \
|
||||||
|
zip \
|
||||||
|
unzip \
|
||||||
|
libmcrypt-dev \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||||
|
&& docker-php-ext-install gd pdo pdo_mysql zip mcrypt mbstring
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
# Copy the Laravel application files to the container
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Set appropriate permissions for Laravel storage and bootstrap cache
|
||||||
|
RUN chown -R www-data:www-data storage bootstrap/cache
|
||||||
|
|
||||||
|
# Install Laravel dependencies
|
||||||
|
RUN composer install --no-interaction --no-plugins --no-scripts --no-dev
|
||||||
|
|
||||||
|
# Create .env file
|
||||||
|
RUN if [ ! -f .env ]; then cp .env.example .env; fi
|
||||||
|
|
||||||
|
# Generate application key
|
||||||
|
RUN php artisan key:generate || true
|
||||||
|
|
||||||
|
# Create directory for the socket and set permissions
|
||||||
|
RUN mkdir -p /run/php && chown www-data:www-data /run/php
|
||||||
|
|
||||||
|
# Configure nginx for Laravel
|
||||||
|
RUN echo 'server {
|
||||||
|
listen 80;
|
||||||
|
server_name localhost;
|
||||||
|
root /var/www/public;
|
||||||
|
index index.php index.html index.htm;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_pass 127.0.0.1:9000;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
include fastcgi_params;
|
||||||
|
}
|
||||||
|
}' > /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
# Create startup script
|
||||||
|
RUN echo '#!/bin/sh
|
||||||
|
php-fpm -D
|
||||||
|
nginx -g "daemon off;"' > /start.sh && chmod +x /start.sh
|
||||||
|
|
||||||
|
# Expose port 80
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Start both PHP-FPM and Nginx
|
||||||
|
CMD ["/start.sh"]
|
||||||
39
Dockerfile.basic
Normal file
39
Dockerfile.basic
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Bare minimum working Dockerfile for Laravel 5.0
|
||||||
|
FROM php:5.6-apache
|
||||||
|
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Install absolute essentials only
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
libmcrypt-dev \
|
||||||
|
&& docker-php-ext-install \
|
||||||
|
pdo \
|
||||||
|
pdo_mysql \
|
||||||
|
mcrypt \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
# Enable Apache rewrite
|
||||||
|
RUN a2enmod rewrite
|
||||||
|
|
||||||
|
# Configure Apache for Laravel
|
||||||
|
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
|
||||||
|
|
||||||
|
# Copy app and set permissions
|
||||||
|
COPY . /var/www/html/
|
||||||
|
RUN chown -R www-data:www-data /var/www/html
|
||||||
|
|
||||||
|
# Basic Laravel setup
|
||||||
|
RUN if [ ! -f .env ]; then cp .env.example .env; fi
|
||||||
|
RUN composer install --no-dev --no-interaction --ignore-platform-reqs
|
||||||
|
RUN php artisan key:generate || true
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
CMD ["apache2-foreground"]
|
||||||
132
Dockerfile.cloudrun
Normal file
132
Dockerfile.cloudrun
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# Dockerfile optimized for Google Cloud Run
|
||||||
|
# Use PHP 5.6 with Apache (matches Laravel 5.0 requirements perfectly)
|
||||||
|
FROM php:5.6-apache
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Install system dependencies and PHP extensions required for Laravel
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
libpng-dev \
|
||||||
|
libjpeg62-turbo-dev \
|
||||||
|
libfreetype6-dev \
|
||||||
|
libmcrypt-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
zip \
|
||||||
|
unzip \
|
||||||
|
git \
|
||||||
|
curl \
|
||||||
|
libxml2-dev \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||||
|
&& docker-php-ext-install \
|
||||||
|
pdo \
|
||||||
|
pdo_mysql \
|
||||||
|
mbstring \
|
||||||
|
zip \
|
||||||
|
gd \
|
||||||
|
xml \
|
||||||
|
mcrypt \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
# Enable Apache modules and configure
|
||||||
|
RUN a2enmod rewrite headers
|
||||||
|
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||||
|
|
||||||
|
# Configure Apache document root for Laravel
|
||||||
|
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
|
||||||
|
|
||||||
|
# Copy Apache virtual host configuration
|
||||||
|
COPY <<EOF /etc/apache2/sites-available/000-default.conf
|
||||||
|
<VirtualHost *:80>
|
||||||
|
ServerAdmin webmaster@localhost
|
||||||
|
DocumentRoot /var/www/html/public
|
||||||
|
|
||||||
|
<Directory /var/www/html/public>
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
ErrorLog \${APACHE_LOG_DIR}/error.log
|
||||||
|
CustomLog \${APACHE_LOG_DIR}/access.log combined
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
Header always set X-Content-Type-Options nosniff
|
||||||
|
Header always set X-Frame-Options DENY
|
||||||
|
Header always set X-XSS-Protection "1; mode=block"
|
||||||
|
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||||
|
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
|
</VirtualHost>
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . /var/www/html/
|
||||||
|
|
||||||
|
# Fix Git ownership issue for the repository
|
||||||
|
RUN git config --global --add safe.directory /var/www/html || true
|
||||||
|
|
||||||
|
# Install PHP dependencies
|
||||||
|
RUN composer install --no-dev --optimize-autoloader --no-interaction
|
||||||
|
|
||||||
|
# Set proper permissions for Laravel
|
||||||
|
RUN chown -R www-data:www-data /var/www/html \
|
||||||
|
&& chmod -R 755 /var/www/html \
|
||||||
|
&& chmod -R 775 /var/www/html/storage \
|
||||||
|
&& chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
|
# Create .env file from .env.example if it doesn't exist
|
||||||
|
RUN if [ ! -f /var/www/html/.env ]; then \
|
||||||
|
cp /var/www/html/.env.example /var/www/html/.env; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Switch to www-data user for Laravel commands to avoid ownership issues
|
||||||
|
USER www-data
|
||||||
|
|
||||||
|
# Generate application key (will be overridden by environment variables in Cloud Run)
|
||||||
|
RUN php artisan key:generate || true
|
||||||
|
|
||||||
|
# Clear and cache configuration for production
|
||||||
|
RUN php artisan config:clear || true \
|
||||||
|
&& php artisan route:clear || true \
|
||||||
|
&& php artisan view:clear || true
|
||||||
|
|
||||||
|
# Switch back to root for the remaining setup
|
||||||
|
USER root
|
||||||
|
|
||||||
|
# Create startup script
|
||||||
|
COPY <<EOF /usr/local/bin/start.sh
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Fix Git ownership issue
|
||||||
|
git config --global --add safe.directory /var/www/html || true
|
||||||
|
|
||||||
|
# Wait for database to be ready (if using Cloud SQL)
|
||||||
|
echo "Starting Laravel application..."
|
||||||
|
|
||||||
|
# Run Laravel optimizations
|
||||||
|
php artisan config:cache || true
|
||||||
|
php artisan route:cache || true
|
||||||
|
php artisan view:cache || true
|
||||||
|
|
||||||
|
# Start Apache in foreground
|
||||||
|
exec apache2-foreground
|
||||||
|
EOF
|
||||||
|
|
||||||
|
RUN chmod +x /usr/local/bin/start.sh
|
||||||
|
|
||||||
|
# Expose port 80 (Cloud Run will map this to 8080)
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Health check for Cloud Run
|
||||||
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||||
|
CMD curl -f http://localhost/ || exit 1
|
||||||
|
|
||||||
|
# Use the startup script
|
||||||
|
CMD ["/usr/local/bin/start.sh"]
|
||||||
86
Dockerfile.minimal
Normal file
86
Dockerfile.minimal
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
# Minimal Dockerfile for Laravel 5.0 with PHP 5.6
|
||||||
|
FROM php:5.6-apache
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Install only essential system dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
libmcrypt-dev \
|
||||||
|
libpng-dev \
|
||||||
|
libjpeg62-turbo-dev \
|
||||||
|
libfreetype6-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
zip \
|
||||||
|
unzip \
|
||||||
|
git \
|
||||||
|
curl \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||||
|
&& docker-php-ext-install \
|
||||||
|
pdo \
|
||||||
|
pdo_mysql \
|
||||||
|
mcrypt \
|
||||||
|
gd \
|
||||||
|
zip \
|
||||||
|
mbstring \
|
||||||
|
&& apt-get clean \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
# Enable Apache modules
|
||||||
|
RUN a2enmod rewrite
|
||||||
|
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||||
|
|
||||||
|
# Configure Apache document root for Laravel
|
||||||
|
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
|
||||||
|
|
||||||
|
# Simple Apache configuration
|
||||||
|
RUN echo '<VirtualHost *:80>\n\
|
||||||
|
DocumentRoot /var/www/html/public\n\
|
||||||
|
<Directory /var/www/html/public>\n\
|
||||||
|
AllowOverride All\n\
|
||||||
|
Require all granted\n\
|
||||||
|
</Directory>\n\
|
||||||
|
</VirtualHost>' > /etc/apache2/sites-available/000-default.conf
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . /var/www/html/
|
||||||
|
|
||||||
|
# Fix Git ownership issue
|
||||||
|
RUN git config --global --add safe.directory /var/www/html || true
|
||||||
|
|
||||||
|
# Install PHP dependencies
|
||||||
|
RUN composer install --no-dev --optimize-autoloader --no-interaction
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
RUN chown -R www-data:www-data /var/www/html \
|
||||||
|
&& chmod -R 755 /var/www/html \
|
||||||
|
&& chmod -R 775 /var/www/html/storage \
|
||||||
|
&& chmod -R 775 /var/www/html/bootstrap/cache
|
||||||
|
|
||||||
|
# Create .env file if it doesn't exist
|
||||||
|
RUN if [ ! -f /var/www/html/.env ]; then \
|
||||||
|
cp /var/www/html/.env.example /var/www/html/.env; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Switch to www-data for Laravel commands
|
||||||
|
USER www-data
|
||||||
|
RUN php artisan key:generate || true
|
||||||
|
USER root
|
||||||
|
|
||||||
|
# Create simple startup script
|
||||||
|
RUN echo '#!/bin/bash\n\
|
||||||
|
set -e\n\
|
||||||
|
echo "Starting Laravel application..."\n\
|
||||||
|
exec apache2-foreground' > /usr/local/bin/start.sh \
|
||||||
|
&& chmod +x /usr/local/bin/start.sh
|
||||||
|
|
||||||
|
# Expose port 80
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Start Apache
|
||||||
|
CMD ["/usr/local/bin/start.sh"]
|
||||||
75
Dockerfile.simple
Normal file
75
Dockerfile.simple
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Ultra-minimal Dockerfile for Laravel 5.0 with PHP 5.6
|
||||||
|
FROM php:5.6-apache
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Install packages one by one to identify issues
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
# Install core development tools first
|
||||||
|
RUN apt-get install -y \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
zip \
|
||||||
|
unzip
|
||||||
|
|
||||||
|
# Install mcrypt (most important for Laravel 5.0)
|
||||||
|
RUN apt-get install -y libmcrypt-dev \
|
||||||
|
&& docker-php-ext-install mcrypt
|
||||||
|
|
||||||
|
# Install basic PHP extensions
|
||||||
|
RUN docker-php-ext-install \
|
||||||
|
pdo \
|
||||||
|
pdo_mysql \
|
||||||
|
mbstring
|
||||||
|
|
||||||
|
# Try to install GD dependencies
|
||||||
|
RUN apt-get install -y \
|
||||||
|
libpng-dev \
|
||||||
|
libjpeg-dev \
|
||||||
|
libfreetype6-dev \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||||
|
&& docker-php-ext-install gd
|
||||||
|
|
||||||
|
# Install zip extension
|
||||||
|
RUN apt-get install -y zlib1g-dev \
|
||||||
|
&& docker-php-ext-install zip
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
# Enable Apache rewrite module
|
||||||
|
RUN a2enmod rewrite
|
||||||
|
|
||||||
|
# Configure Apache
|
||||||
|
RUN echo "ServerName localhost" >> /etc/apache2/apache2.conf
|
||||||
|
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
|
||||||
|
|
||||||
|
# Copy application files
|
||||||
|
COPY . /var/www/html/
|
||||||
|
|
||||||
|
# Set basic permissions
|
||||||
|
RUN chown -R www-data:www-data /var/www/html \
|
||||||
|
&& chmod -R 755 /var/www/html
|
||||||
|
|
||||||
|
# Create .env file if needed
|
||||||
|
RUN if [ ! -f /var/www/html/.env ]; then \
|
||||||
|
cp /var/www/html/.env.example /var/www/html/.env; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install dependencies without dev packages
|
||||||
|
RUN composer install --no-dev --no-interaction || true
|
||||||
|
|
||||||
|
# Generate Laravel key
|
||||||
|
RUN php artisan key:generate || true
|
||||||
|
|
||||||
|
# Expose port 80
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
# Start Apache
|
||||||
|
CMD ["apache2-foreground"]
|
||||||
60
Dockerfile.test
Normal file
60
Dockerfile.test
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
# Test Dockerfile to identify available packages
|
||||||
|
FROM php:5.6-apache
|
||||||
|
|
||||||
|
WORKDIR /var/www/html
|
||||||
|
|
||||||
|
# Update package lists first
|
||||||
|
RUN apt-get update
|
||||||
|
|
||||||
|
# Test each package individually
|
||||||
|
RUN apt-get install -y curl || echo "curl failed"
|
||||||
|
RUN apt-get install -y git || echo "git failed"
|
||||||
|
RUN apt-get install -y zip || echo "zip failed"
|
||||||
|
RUN apt-get install -y unzip || echo "unzip failed"
|
||||||
|
|
||||||
|
# Test mcrypt (most important)
|
||||||
|
RUN apt-get install -y libmcrypt-dev || echo "libmcrypt-dev failed"
|
||||||
|
|
||||||
|
# Test image libraries one by one
|
||||||
|
RUN apt-get install -y libpng-dev || echo "libpng-dev failed"
|
||||||
|
RUN apt-get install -y libjpeg-dev || echo "libjpeg-dev failed"
|
||||||
|
RUN apt-get install -y libfreetype6-dev || echo "libfreetype6-dev failed"
|
||||||
|
|
||||||
|
# Test zip library
|
||||||
|
RUN apt-get install -y zlib1g-dev || echo "zlib1g-dev failed"
|
||||||
|
|
||||||
|
# Try to install PHP extensions
|
||||||
|
RUN docker-php-ext-install mcrypt || echo "mcrypt extension failed"
|
||||||
|
RUN docker-php-ext-install pdo || echo "pdo extension failed"
|
||||||
|
RUN docker-php-ext-install pdo_mysql || echo "pdo_mysql extension failed"
|
||||||
|
RUN docker-php-ext-install mbstring || echo "mbstring extension failed"
|
||||||
|
|
||||||
|
# Test GD configuration
|
||||||
|
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ || echo "gd configure failed"
|
||||||
|
RUN docker-php-ext-install gd || echo "gd extension failed"
|
||||||
|
|
||||||
|
# Test zip extension
|
||||||
|
RUN docker-php-ext-install zip || echo "zip extension failed"
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
# Basic Apache setup
|
||||||
|
RUN a2enmod rewrite
|
||||||
|
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
|
||||||
|
|
||||||
|
# Test copy and basic setup
|
||||||
|
COPY . /var/www/html/
|
||||||
|
RUN chown -R www-data:www-data /var/www/html
|
||||||
|
|
||||||
|
# Test Laravel commands
|
||||||
|
RUN if [ ! -f .env ]; then cp .env.example .env; fi || echo ".env creation failed"
|
||||||
|
RUN composer install --no-dev --no-interaction || echo "composer install failed"
|
||||||
|
RUN php artisan key:generate || echo "key generation failed"
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
CMD ["apache2-foreground"]
|
||||||
100
PHP_COMPATIBILITY.md
Normal file
100
PHP_COMPATIBILITY.md
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# Laravel 5.0 and PHP Compatibility Guide
|
||||||
|
|
||||||
|
## Issue: mcrypt Extension Required
|
||||||
|
|
||||||
|
Laravel 5.0 requires the `mcrypt` PHP extension, which was:
|
||||||
|
|
||||||
|
- **Deprecated** in PHP 7.1
|
||||||
|
- **Removed** in PHP 7.2+
|
||||||
|
|
||||||
|
## Solutions
|
||||||
|
|
||||||
|
### Option 1: Use PHP 5.6 (Current Implementation)
|
||||||
|
|
||||||
|
The `Dockerfile.minimal` has been updated to use PHP 5.6 which is the ideal match for Laravel 5.0.
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
|
||||||
|
- Perfect compatibility with Laravel 5.0
|
||||||
|
- Native mcrypt support
|
||||||
|
- All packages available and tested
|
||||||
|
- Matches original development environment
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
|
||||||
|
- PHP 5.6 reached end-of-life in December 2018
|
||||||
|
- Security concerns for long-term production use
|
||||||
|
|
||||||
|
### Option 2: Upgrade Laravel (Recommended for Production)
|
||||||
|
Upgrade to Laravel 5.5+ which doesn't require mcrypt.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Update composer.json
|
||||||
|
"laravel/framework": "5.8.*"
|
||||||
|
|
||||||
|
# Remove mcrypt dependencies and update encryption
|
||||||
|
php artisan key:generate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Use OpenSSL Instead (Laravel 5.2+)
|
||||||
|
If upgrading Laravel, update encryption configuration:
|
||||||
|
|
||||||
|
```php
|
||||||
|
// config/app.php
|
||||||
|
'cipher' => 'AES-256-CBC',
|
||||||
|
```
|
||||||
|
|
||||||
|
## Current Docker Configuration
|
||||||
|
|
||||||
|
The Dockerfile now uses:
|
||||||
|
|
||||||
|
- **Base Image**: `php:5.6-apache`
|
||||||
|
- **mcrypt Extension**: Native support (no installation issues)
|
||||||
|
- **Other Extensions**: All Laravel 5.0 requirements met
|
||||||
|
- **Package Compatibility**: Perfect match for PHP 5.6
|
||||||
|
|
||||||
|
## Production Recommendations
|
||||||
|
|
||||||
|
For a production deployment, consider:
|
||||||
|
|
||||||
|
1. **Upgrade Laravel** to 5.8 or later (LTS)
|
||||||
|
2. **Use PHP 7.4+** for better performance and security
|
||||||
|
3. **Replace mcrypt** with OpenSSL encryption
|
||||||
|
|
||||||
|
## Quick Upgrade Path (Optional)
|
||||||
|
|
||||||
|
If you want to modernize the application:
|
||||||
|
|
||||||
|
### Step 1: Update composer.json
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"laravel/framework": "5.8.*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Update Dockerfile to use PHP 7.4
|
||||||
|
```dockerfile
|
||||||
|
FROM php:7.4-apache
|
||||||
|
# Remove mcrypt installation
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Update configuration
|
||||||
|
```bash
|
||||||
|
php artisan key:generate
|
||||||
|
php artisan config:cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## Security Note
|
||||||
|
|
||||||
|
Since PHP 7.1 is end-of-life, monitor for security updates and consider upgrading the Laravel version for long-term production use.
|
||||||
|
|
||||||
|
## Testing the Current Setup
|
||||||
|
|
||||||
|
The current configuration should work with:
|
||||||
|
```bash
|
||||||
|
./start-local.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
This will use PHP 7.1 with mcrypt support for Laravel 5.0 compatibility.
|
||||||
156
cloudbuild.yaml
Normal file
156
cloudbuild.yaml
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
# Google Cloud Build configuration for Laravel 5 application deployment to Cloud Run
|
||||||
|
steps:
|
||||||
|
# Step 1: Build the Docker image
|
||||||
|
- name: 'gcr.io/cloud-builders/docker'
|
||||||
|
args:
|
||||||
|
- 'build'
|
||||||
|
- '-t'
|
||||||
|
- 'gcr.io/$PROJECT_ID/merchbay-laravel:$COMMIT_SHA'
|
||||||
|
- '-t'
|
||||||
|
- 'gcr.io/$PROJECT_ID/merchbay-laravel:latest'
|
||||||
|
- '-f'
|
||||||
|
- 'Dockerfile.simple'
|
||||||
|
- '.'
|
||||||
|
id: 'build-image'
|
||||||
|
|
||||||
|
# Step 2: Push the Docker image to Google Container Registry
|
||||||
|
- name: 'gcr.io/cloud-builders/docker'
|
||||||
|
args:
|
||||||
|
- 'push'
|
||||||
|
- 'gcr.io/$PROJECT_ID/merchbay-laravel:$COMMIT_SHA'
|
||||||
|
id: 'push-image'
|
||||||
|
waitFor: ['build-image']
|
||||||
|
|
||||||
|
# Step 3: Push the latest tag as well
|
||||||
|
- name: 'gcr.io/cloud-builders/docker'
|
||||||
|
args:
|
||||||
|
- 'push'
|
||||||
|
- 'gcr.io/$PROJECT_ID/merchbay-laravel:latest'
|
||||||
|
id: 'push-latest'
|
||||||
|
waitFor: ['build-image']
|
||||||
|
|
||||||
|
# Step 4: Run database migrations (optional - only if you have Cloud SQL configured)
|
||||||
|
# Uncomment and configure if you need to run migrations
|
||||||
|
# - name: 'gcr.io/cloud-builders/gcloud'
|
||||||
|
# entrypoint: 'bash'
|
||||||
|
# args:
|
||||||
|
# - '-c'
|
||||||
|
# - |
|
||||||
|
# gcloud run jobs create laravel-migrate \
|
||||||
|
# --image=gcr.io/$PROJECT_ID/merchbay-laravel:$COMMIT_SHA \
|
||||||
|
# --region=$_REGION \
|
||||||
|
# --set-env-vars="APP_ENV=production,APP_KEY=$_APP_KEY,DB_HOST=$_DB_HOST,DB_DATABASE=$_DB_DATABASE,DB_USERNAME=$_DB_USERNAME,DB_PASSWORD=$_DB_PASSWORD" \
|
||||||
|
# --set-cloudsql-instances=$_CLOUDSQL_INSTANCE \
|
||||||
|
# --command="php" \
|
||||||
|
# --args="artisan,migrate,--force" \
|
||||||
|
# --max-retries=1 \
|
||||||
|
# --replace || true
|
||||||
|
# gcloud run jobs execute laravel-migrate --region=$_REGION --wait
|
||||||
|
# id: 'run-migrations'
|
||||||
|
# waitFor: ['push-image']
|
||||||
|
|
||||||
|
# Step 5: Deploy to Cloud Run
|
||||||
|
- name: 'gcr.io/cloud-builders/gcloud'
|
||||||
|
args:
|
||||||
|
- 'run'
|
||||||
|
- 'deploy'
|
||||||
|
- '$_SERVICE_NAME'
|
||||||
|
- '--image'
|
||||||
|
- 'gcr.io/$PROJECT_ID/merchbay-laravel:$COMMIT_SHA'
|
||||||
|
- '--region'
|
||||||
|
- '$_REGION'
|
||||||
|
- '--platform'
|
||||||
|
- 'managed'
|
||||||
|
- '--allow-unauthenticated'
|
||||||
|
- '--port'
|
||||||
|
- '8080'
|
||||||
|
- '--memory'
|
||||||
|
- '$_MEMORY'
|
||||||
|
- '--cpu'
|
||||||
|
- '$_CPU'
|
||||||
|
- '--timeout'
|
||||||
|
- '$_TIMEOUT'
|
||||||
|
- '--concurrency'
|
||||||
|
- '$_CONCURRENCY'
|
||||||
|
- '--min-instances'
|
||||||
|
- '$_MIN_INSTANCES'
|
||||||
|
- '--max-instances'
|
||||||
|
- '$_MAX_INSTANCES'
|
||||||
|
- '--set-env-vars'
|
||||||
|
- 'APP_ENV=production,APP_DEBUG=false,APP_KEY=$_APP_KEY,DB_HOST=$_DB_HOST,DB_DATABASE=$_DB_DATABASE,DB_USERNAME=$_DB_USERNAME,DB_PASSWORD=$_DB_PASSWORD,CACHE_DRIVER=redis,SESSION_DRIVER=redis,QUEUE_DRIVER=database,PAYPAL_MODE=$_PAYPAL_MODE,PAYPAL_LIVE_CLIENT_ID=$_PAYPAL_LIVE_CLIENT_ID,PAYPAL_LIVE_SECRET=$_PAYPAL_LIVE_SECRET,PAYPAL_SANDBOX_CLIENT_ID=$_PAYPAL_SANDBOX_CLIENT_ID,PAYPAL_SANDBOX_SECRET=$_PAYPAL_SANDBOX_SECRET,MAIL_DRIVER=$_MAIL_DRIVER,MAIL_HOST=$_MAIL_HOST,MAIL_PORT=$_MAIL_PORT,MAIL_USERNAME=$_MAIL_USERNAME,MAIL_PASSWORD=$_MAIL_PASSWORD,GOOGLE_ANALYTICS_VIEW_ID=$_GOOGLE_ANALYTICS_VIEW_ID'
|
||||||
|
- '--set-cloudsql-instances'
|
||||||
|
- '$_CLOUDSQL_INSTANCE'
|
||||||
|
- '--vpc-connector'
|
||||||
|
- '$_VPC_CONNECTOR'
|
||||||
|
- '--add-cloudsql-instances'
|
||||||
|
- '$_CLOUDSQL_INSTANCE'
|
||||||
|
id: 'deploy-service'
|
||||||
|
waitFor: ['push-image']
|
||||||
|
|
||||||
|
# Substitution variables - you can override these in your Cloud Build trigger
|
||||||
|
substitutions:
|
||||||
|
# Service configuration
|
||||||
|
_SERVICE_NAME: 'merchbay-laravel'
|
||||||
|
_REGION: 'us-central1'
|
||||||
|
|
||||||
|
# Resource limits
|
||||||
|
_MEMORY: '1Gi'
|
||||||
|
_CPU: '1000m'
|
||||||
|
_TIMEOUT: '300s'
|
||||||
|
_CONCURRENCY: '80'
|
||||||
|
_MIN_INSTANCES: '0'
|
||||||
|
_MAX_INSTANCES: '10'
|
||||||
|
|
||||||
|
# Database configuration (Cloud SQL)
|
||||||
|
_CLOUDSQL_INSTANCE: 'YOUR_PROJECT_ID:REGION:INSTANCE_NAME'
|
||||||
|
_DB_HOST: '127.0.0.1'
|
||||||
|
_DB_DATABASE: 'merchbay'
|
||||||
|
_DB_USERNAME: 'laravel_user'
|
||||||
|
_DB_PASSWORD: 'YOUR_DB_PASSWORD'
|
||||||
|
|
||||||
|
# VPC configuration (if needed)
|
||||||
|
_VPC_CONNECTOR: 'projects/YOUR_PROJECT_ID/locations/REGION/connectors/CONNECTOR_NAME'
|
||||||
|
|
||||||
|
# Application configuration
|
||||||
|
_APP_KEY: 'base64:YOUR_APP_KEY_HERE'
|
||||||
|
|
||||||
|
# PayPal configuration
|
||||||
|
_PAYPAL_MODE: 'live'
|
||||||
|
_PAYPAL_LIVE_CLIENT_ID: 'YOUR_PAYPAL_LIVE_CLIENT_ID'
|
||||||
|
_PAYPAL_LIVE_SECRET: 'YOUR_PAYPAL_LIVE_SECRET'
|
||||||
|
_PAYPAL_SANDBOX_CLIENT_ID: 'YOUR_PAYPAL_SANDBOX_CLIENT_ID'
|
||||||
|
_PAYPAL_SANDBOX_SECRET: 'YOUR_PAYPAL_SANDBOX_SECRET'
|
||||||
|
|
||||||
|
# Mail configuration
|
||||||
|
_MAIL_DRIVER: 'smtp'
|
||||||
|
_MAIL_HOST: 'smtp.gmail.com'
|
||||||
|
_MAIL_PORT: '587'
|
||||||
|
_MAIL_USERNAME: 'your-email@domain.com'
|
||||||
|
_MAIL_PASSWORD: 'your-app-password'
|
||||||
|
|
||||||
|
# Google Analytics
|
||||||
|
_GOOGLE_ANALYTICS_VIEW_ID: 'YOUR_GA_VIEW_ID'
|
||||||
|
|
||||||
|
# Build options
|
||||||
|
options:
|
||||||
|
# Use a more powerful machine for faster builds
|
||||||
|
machineType: 'E2_HIGHCPU_8'
|
||||||
|
|
||||||
|
# Enable detailed logging
|
||||||
|
logging: CLOUD_LOGGING_ONLY
|
||||||
|
|
||||||
|
# Build timeout
|
||||||
|
timeout: '1200s'
|
||||||
|
|
||||||
|
# Store build logs in Cloud Logging
|
||||||
|
logsBucket: 'gs://YOUR_PROJECT_ID_cloudbuild-logs'
|
||||||
|
|
||||||
|
# Available logs for debugging
|
||||||
|
availableSecrets:
|
||||||
|
secretManager:
|
||||||
|
- versionName: 'projects/YOUR_PROJECT_ID/secrets/APP_KEY/versions/latest'
|
||||||
|
env: 'APP_KEY'
|
||||||
|
- versionName: 'projects/YOUR_PROJECT_ID/secrets/DB_PASSWORD/versions/latest'
|
||||||
|
env: 'DB_PASSWORD'
|
||||||
|
- versionName: 'projects/YOUR_PROJECT_ID/secrets/PAYPAL_LIVE_SECRET/versions/latest'
|
||||||
|
env: 'PAYPAL_LIVE_SECRET'
|
||||||
@@ -46,6 +46,9 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"preferred-install": "dist"
|
"preferred-install": "dist",
|
||||||
|
"allow-plugins": {
|
||||||
|
"kylekatarnls/update-helper": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
75
docker-compose.local.yml
Normal file
75
docker-compose.local.yml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Docker Compose for local development and testing
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile.basic
|
||||||
|
ports:
|
||||||
|
- "8080:80"
|
||||||
|
environment:
|
||||||
|
- APP_ENV=local
|
||||||
|
- APP_DEBUG=true
|
||||||
|
- APP_KEY=base64:your-app-key-here
|
||||||
|
- DB_HOST=mysql
|
||||||
|
- DB_DATABASE=merchbay
|
||||||
|
- DB_USERNAME=laravel_user
|
||||||
|
- DB_PASSWORD=secret
|
||||||
|
- CACHE_DRIVER=file
|
||||||
|
- SESSION_DRIVER=file
|
||||||
|
- REDIS_HOST=redis
|
||||||
|
- QUEUE_DRIVER=sync
|
||||||
|
- PAYPAL_MODE=sandbox
|
||||||
|
- PAYPAL_SANDBOX_CLIENT_ID=your-sandbox-client-id
|
||||||
|
- PAYPAL_SANDBOX_SECRET=your-sandbox-secret
|
||||||
|
- MAIL_DRIVER=log
|
||||||
|
volumes:
|
||||||
|
- ./storage:/var/www/html/storage
|
||||||
|
- ./bootstrap/cache:/var/www/html/bootstrap/cache
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
- redis
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=root
|
||||||
|
- MYSQL_DATABASE=merchbay
|
||||||
|
- MYSQL_USER=laravel_user
|
||||||
|
- MYSQL_PASSWORD=secret
|
||||||
|
ports:
|
||||||
|
- "3306:3306"
|
||||||
|
volumes:
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
ports:
|
||||||
|
- "6379:6379"
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
phpmyadmin:
|
||||||
|
image: phpmyadmin/phpmyadmin
|
||||||
|
environment:
|
||||||
|
- PMA_HOST=mysql
|
||||||
|
- PMA_USER=root
|
||||||
|
- PMA_PASSWORD=root
|
||||||
|
ports:
|
||||||
|
- "8081:80"
|
||||||
|
depends_on:
|
||||||
|
- mysql
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app-network:
|
||||||
|
driver: bridge
|
||||||
@@ -3,37 +3,29 @@ server {
|
|||||||
index index.php index.html;
|
index index.php index.html;
|
||||||
error_log /var/log/nginx/error.log;
|
error_log /var/log/nginx/error.log;
|
||||||
access_log /var/log/nginx/access.log;
|
access_log /var/log/nginx/access.log;
|
||||||
root /var/www;
|
root /var/www/public;
|
||||||
index index.php index.html;
|
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
if ($request_method = 'OPTIONS') {
|
|
||||||
add_header 'Access-Control-Allow-Origin' '*';
|
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, HEAD';
|
|
||||||
add_header 'Access-Control-Max-Age' '1728000';
|
|
||||||
add_header 'Access-Control-Allow-Headers' '*';
|
|
||||||
#add_header 'Content-Type: text/plain; charset=UTF-8';
|
|
||||||
#add_header 'Content-Length: 0';
|
|
||||||
return 204;
|
|
||||||
}
|
|
||||||
try_files $uri $uri/ /index.php?$query_string;
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ \.php$ {
|
location ~ \.php$ {
|
||||||
fastcgi_index index.php;
|
try_files $uri =404;
|
||||||
fastcgi_pass app:9000;
|
|
||||||
|
|
||||||
include fastcgi_params;
|
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
fastcgi_pass app:9000;
|
||||||
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
|
fastcgi_index index.php;
|
||||||
|
include fastcgi_params;
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
location ~* \.(css|less|js|jpg|png|gif)$ {
|
location ~* \.(css|less|js|jpg|png|gif)$ {
|
||||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
expires 0;
|
||||||
add_header Pragma "no-cache";
|
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||||
expires 0;
|
add_header Pragma "no-cache";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
106
rebuild.sh
Executable file
106
rebuild.sh
Executable file
@@ -0,0 +1,106 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Check if docker compose (new) or docker-compose (old) is available
|
||||||
|
if command -v docker &>/dev/null; then
|
||||||
|
if docker compose version &>/dev/null; then
|
||||||
|
DOCKER_COMPOSE="docker compose"
|
||||||
|
elif command -v docker-compose &>/dev/null; then
|
||||||
|
DOCKER_COMPOSE="docker-compose"
|
||||||
|
else
|
||||||
|
echo "❌ Error: Neither 'docker compose' nor 'docker-compose' found."
|
||||||
|
echo "Please install Docker Desktop from https://www.docker.com/products/docker-desktop/"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "❌ Error: Docker is not installed."
|
||||||
|
echo "Please install Docker Desktop from https://www.docker.com/products/docker-desktop/"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🚀 Starting rebuild process..."
|
||||||
|
|
||||||
|
# Function to display usage
|
||||||
|
show_usage() {
|
||||||
|
echo "Usage: ./rebuild.sh [OPTIONS]"
|
||||||
|
echo "Options:"
|
||||||
|
echo " -h, --help Show this help message"
|
||||||
|
echo " -c, --clean Perform a clean rebuild (no cache)"
|
||||||
|
echo " -f, --fresh Perform a fresh migration"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Default values
|
||||||
|
CLEAN_BUILD=false
|
||||||
|
FRESH_MIGRATION=false
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [[ "$#" -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help) show_usage; exit 0 ;;
|
||||||
|
-c|--clean) CLEAN_BUILD=true ;;
|
||||||
|
-f|--fresh) FRESH_MIGRATION=true ;;
|
||||||
|
*) echo "Unknown parameter: $1"; show_usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# Pull latest changes from git
|
||||||
|
echo "📥 Pulling latest changes from git..."
|
||||||
|
if ! git pull; then
|
||||||
|
echo "❌ Git pull failed. Please resolve any conflicts and try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stop running containers
|
||||||
|
echo "📥 Stopping running containers..."
|
||||||
|
$DOCKER_COMPOSE down
|
||||||
|
|
||||||
|
# Remove old images if clean build
|
||||||
|
if [ "$CLEAN_BUILD" = true ] ; then
|
||||||
|
echo "🧹 Cleaning Docker cache..."
|
||||||
|
$DOCKER_COMPOSE rm -f
|
||||||
|
docker system prune -f
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build and start containers
|
||||||
|
echo "🏗️ Building containers..."
|
||||||
|
if [ "$CLEAN_BUILD" = true ] ; then
|
||||||
|
$DOCKER_COMPOSE build --no-cache
|
||||||
|
else
|
||||||
|
$DOCKER_COMPOSE build
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start containers
|
||||||
|
echo "🚀 Starting containers..."
|
||||||
|
$DOCKER_COMPOSE up -d
|
||||||
|
|
||||||
|
# Wait for the containers to be ready
|
||||||
|
echo "⏳ Waiting for containers to be ready..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Clear Laravel cache
|
||||||
|
echo "🧹 Clearing Laravel cache..."
|
||||||
|
$DOCKER_COMPOSE exec app php artisan cache:clear
|
||||||
|
$DOCKER_COMPOSE exec app php artisan config:clear
|
||||||
|
$DOCKER_COMPOSE exec app php artisan view:clear
|
||||||
|
|
||||||
|
# Run composer install
|
||||||
|
echo "📦 Installing dependencies..."
|
||||||
|
$DOCKER_COMPOSE exec app composer install
|
||||||
|
|
||||||
|
# Generate application key if .env exists and APP_KEY is empty
|
||||||
|
if [ -f .env ] && ! grep -q "^APP_KEY=[A-Za-z0-9+/]\{40\}$" .env; then
|
||||||
|
echo "🔑 Generating application key..."
|
||||||
|
$DOCKER_COMPOSE exec app php artisan key:generate
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run migrations if requested
|
||||||
|
if [ "$FRESH_MIGRATION" = true ] ; then
|
||||||
|
echo "🔄 Running fresh migrations..."
|
||||||
|
$DOCKER_COMPOSE exec app php artisan migrate:fresh
|
||||||
|
else
|
||||||
|
echo "🔄 Running migrations..."
|
||||||
|
$DOCKER_COMPOSE exec app php artisan migrate
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✨ Rebuild completed!"
|
||||||
|
echo "🌐 Your application should be available at http://localhost:8080"
|
||||||
@@ -10,11 +10,11 @@
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
<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>
|
<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://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="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('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/style.css') }}" rel="stylesheet">
|
||||||
<link href="{{ asset('public/assets/login/css/form-elements.css') }}" rel="stylesheet"> -->
|
<link href="{{ asset('public/assets/login/css/form-elements.css') }}" rel="stylesheet"> -->
|
||||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||||
@@ -258,7 +258,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fetchCanada() {
|
function fetchCanada() {
|
||||||
$.getJSON("{{ asset('/public/api/canada.json') }}", function(items) {
|
$.getJSON("{{ asset('/api/canada.json') }}", function(items) {
|
||||||
var states = [];
|
var states = [];
|
||||||
|
|
||||||
Object.keys(items).forEach(function(state) {
|
Object.keys(items).forEach(function(state) {
|
||||||
@@ -307,7 +307,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fetchUSA() {
|
function fetchUSA() {
|
||||||
$.getJSON("{{ asset('/public/api/usaCities.json') }}", function(data) {
|
$.getJSON("{{ asset('/api/usaCities.json') }}", function(data) {
|
||||||
var states = [];
|
var states = [];
|
||||||
|
|
||||||
for (i = 0; i < data.length; i++) {
|
for (i = 0; i < data.length; i++) {
|
||||||
|
|||||||
66
start-local.sh
Executable file
66
start-local.sh
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Quick start script for local development and testing before Cloud Run deployment
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🚀 Starting Merchbay Laravel Application Setup..."
|
||||||
|
|
||||||
|
# Check if Docker is running
|
||||||
|
if ! docker info > /dev/null 2>&1; then
|
||||||
|
echo "❌ Docker is not running. Please start Docker and try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine which docker compose command to use
|
||||||
|
if command -v docker-compose > /dev/null 2>&1; then
|
||||||
|
DOCKER_COMPOSE="docker-compose"
|
||||||
|
elif docker compose version > /dev/null 2>&1; then
|
||||||
|
DOCKER_COMPOSE="docker compose"
|
||||||
|
else
|
||||||
|
echo "❌ Neither 'docker-compose' nor 'docker compose' is available."
|
||||||
|
echo "Please install Docker Compose and try again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "ℹ️ Using: $DOCKER_COMPOSE"
|
||||||
|
|
||||||
|
# Check if .env file exists
|
||||||
|
if [ ! -f .env ]; then
|
||||||
|
echo "📄 Creating .env file from .env.example..."
|
||||||
|
cp .env.example .env
|
||||||
|
echo "✅ .env file created. Please update it with your configuration."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build and start services
|
||||||
|
echo "🔨 Building Docker images..."
|
||||||
|
$DOCKER_COMPOSE -f docker-compose.local.yml build
|
||||||
|
|
||||||
|
echo "🚀 Starting services..."
|
||||||
|
$DOCKER_COMPOSE -f docker-compose.local.yml up -d
|
||||||
|
|
||||||
|
echo "⏳ Waiting for services to be ready..."
|
||||||
|
sleep 30
|
||||||
|
|
||||||
|
# Run Laravel setup commands
|
||||||
|
echo "🔧 Setting up Laravel..."
|
||||||
|
$DOCKER_COMPOSE -f docker-compose.local.yml exec app php artisan key:generate
|
||||||
|
#$DOCKER_COMPOSE -f docker-compose.local.yml exec app php artisan migrate --force
|
||||||
|
$DOCKER_COMPOSE -f docker-compose.local.yml exec app php artisan config:cache
|
||||||
|
$DOCKER_COMPOSE -f docker-compose.local.yml exec app php artisan route:cache
|
||||||
|
$DOCKER_COMPOSE -f docker-compose.local.yml exec app php artisan view:cache
|
||||||
|
|
||||||
|
echo "✅ Setup complete!"
|
||||||
|
echo ""
|
||||||
|
echo "🌐 Your application is now running at:"
|
||||||
|
echo " Application: http://localhost:8080"
|
||||||
|
echo " phpMyAdmin: http://localhost:8081"
|
||||||
|
echo ""
|
||||||
|
echo "📊 Check logs with:"
|
||||||
|
echo " $DOCKER_COMPOSE -f docker-compose.local.yml logs -f app"
|
||||||
|
echo ""
|
||||||
|
echo "🛑 Stop the application with:"
|
||||||
|
echo " $DOCKER_COMPOSE -f docker-compose.local.yml down"
|
||||||
|
echo ""
|
||||||
|
echo "🚀 When ready to deploy to Cloud Run, use:"
|
||||||
|
echo " gcloud builds submit --config=cloudbuild.yaml"
|
||||||
Reference in New Issue
Block a user