Skip to content

Commit 7c57579

Browse files
committed
Render deploy
1 parent 1775e87 commit 7c57579

File tree

9 files changed

+979
-3
lines changed

9 files changed

+979
-3
lines changed

.dockerignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Git
2+
.git
3+
.gitignore
4+
.gitattributes
5+
6+
# Node
7+
node_modules
8+
npm-debug.log
9+
yarn-error.log
10+
11+
# Laravel
12+
.env
13+
storage/logs/*
14+
storage/framework/sessions/*
15+
storage/framework/cache/data/*
16+
storage/framework/testing/*
17+
public/hot
18+
public/storage
19+
vendor/
20+
21+
# IDE / OS files
22+
.idea
23+
.vscode
24+
*.DS_Store

Dockerfile

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Stage 1: Compile Frontend Assets
2+
FROM node:20-alpine AS node_builder
3+
4+
WORKDIR /app/frontend
5+
6+
# Copy package files and install dependencies
7+
COPY package.json package-lock.json* ./
8+
# Copy build configuration files
9+
COPY webpack.mix.js tailwind.config.js postcss.config.js* .babelrc* ./
10+
# Ensure postcss.config.js and .babelrc are optional by using *
11+
12+
# Install dependencies for building assets
13+
# Using npm ci for cleaner installs if package-lock.json is present and up-to-date
14+
RUN npm ci --production
15+
16+
# Copy frontend source code
17+
COPY resources/js ./resources/js
18+
COPY resources/css ./resources/css
19+
COPY resources/img ./resources/img
20+
# Add other resource directories if you have them (e.g., resources/fonts)
21+
22+
# Compile assets
23+
RUN npm run production
24+
25+
# Stage 2: Setup PHP Application Environment
26+
FROM ric_harvey/nginx-php-fpm:php82 AS app
27+
28+
# Set working directory
29+
WORKDIR /var/www/html
30+
31+
# Install system dependencies and PHP extensions
32+
# The ric_harvey/nginx-php-fpm image should have most common extensions.
33+
# We'll add pdo_mysql, gd, zip, bcmath, exif, opcache, intl if they are not present.
34+
# This often requires root access, then dropping back to www-data.
35+
# The exact commands depend on the base image's package manager (apk for Alpine).
36+
USER root
37+
RUN apk add --no-cache \
38+
libzip-dev \
39+
libpng-dev \
40+
libjpeg-turbo-dev \
41+
freetype-dev \
42+
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
43+
&& docker-php-ext-install -j$(nproc) gd pdo_mysql zip bcmath exif opcache intl \
44+
&& apk del libzip-dev libpng-dev libjpeg-turbo-dev freetype-dev \
45+
&& rm -rf /var/cache/apk/*
46+
47+
# Install Composer globally
48+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
49+
50+
# Copy application files (respecting .dockerignore)
51+
COPY . .
52+
53+
# Copy compiled assets from the node_builder stage
54+
COPY --chown=www-data:www-data --from=node_builder /app/frontend/public ./public
55+
56+
# Set permissions for Laravel storage and bootstrap cache
57+
# Ensure these directories exist before chown/chmod if copying doesn't create them fully.
58+
RUN mkdir -p storage/framework/sessions storage/framework/cache/data storage/framework/views storage/logs \
59+
&& chown -R www-data:www-data storage bootstrap/cache \
60+
&& chmod -R 775 storage bootstrap/cache
61+
62+
# Copy Nginx site configuration
63+
# The ric_harvey image might use /etc/nginx/conf.d/default.conf or similar.
64+
# We'll assume /etc/nginx/sites-available/default and ensure it's linked or directly used.
65+
COPY nginx-site.conf /etc/nginx/sites-available/default
66+
# If sites-enabled is used: RUN ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
67+
68+
# Copy and set permissions for the deploy script
69+
COPY deploy.sh /usr/local/bin/deploy.sh
70+
RUN chmod +x /usr/local/bin/deploy.sh
71+
72+
# Expose port 80
73+
EXPOSE 80

app/Http/Middleware/TrustProxies.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class TrustProxies extends Middleware
1212
*
1313
* @var array<int, string>|string|null
1414
*/
15-
protected $proxies;
15+
protected $proxies = '*'; // Trust all upstream proxies (Render's load balancer)
1616

1717
/**
1818
* The headers that should be used to detect proxies.

app/Providers/AppServiceProvider.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Providers;
44

5+
use Illuminate\Routing\UrlGenerator;
56
use Illuminate\Support\ServiceProvider;
67

78
class AppServiceProvider extends ServiceProvider
@@ -21,8 +22,10 @@ public function register()
2122
*
2223
* @return void
2324
*/
24-
public function boot()
25+
public function boot(UrlGenerator $url)
2526
{
26-
//
27+
if (config('app.env') === 'production') {
28+
$url->forceScheme('https');
29+
}
2730
}
2831
}

deploy.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env bash
2+
echo "Running composer"
3+
composer install --no-dev --working-dir=/var/www/html
4+
5+
echo "Caching config..."
6+
php artisan config:cache
7+
8+
echo "Caching routes..."
9+
php artisan route:cache
10+
11+
echo "Running migrations..."
12+
php artisan migrate --force

nginx-site.conf

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
server {
2+
listen 80 default_server;
3+
listen [::]:80 default_server;
4+
5+
server_name _; # Catch all hostnames
6+
7+
root /var/www/html/public;
8+
index index.php index.html index.htm;
9+
10+
#charset utf-8;
11+
12+
location / {
13+
try_files $uri $uri/ /index.php?$query_string;
14+
}
15+
16+
location = /favicon.ico { access_log off; log_not_found off; }
17+
location = /robots.txt { access_log off; log_not_found off; }
18+
19+
# Prevent access to hidden files
20+
location ~ /\.ht {
21+
deny all;
22+
}
23+
24+
# Handle PHP files
25+
location ~ \.php$ {
26+
try_files $uri =404;
27+
fastcgi_split_path_info ^(.+\.php)(/.+)$;
28+
# fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; # Adjust socket based on PHP version and FPM config
29+
# The ric_harvey/nginx-php-fpm image might use a TCP port, e.g., 127.0.0.1:9000 or php:9000
30+
# Common setup for ric_harvey images or similar:
31+
fastcgi_pass 127.0.0.1:9000; # Or php:9000 if php-fpm is exposed on a 'php' hostname in the container network
32+
fastcgi_index index.php;
33+
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
34+
fastcgi_param PATH_INFO $fastcgi_path_info;
35+
include fastcgi_params;
36+
fastcgi_read_timeout 300; # Optional: Increase timeout for long-running scripts
37+
}
38+
39+
# Security headers (optional but recommended)
40+
# add_header X-Frame-Options "SAMEORIGIN";
41+
# add_header X-XSS-Protection "1; mode=block";
42+
# add_header X-Content-Type-Options "nosniff";
43+
44+
# Enable gzip compression (optional)
45+
# gzip on;
46+
# gzip_vary on;
47+
# gzip_proxied any;
48+
# gzip_comp_level 6;
49+
# gzip_buffers 16 8k;
50+
# gzip_http_version 1.1;
51+
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
52+
}

render.yaml

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# render.yaml
2+
# Defines the infrastructure for deploying the Laravel application on Render
3+
# based on the provided schema.json.
4+
# Assumes CircleCI builds the Docker image, pushes it to a registry,
5+
# and then triggers a deploy on Render using a deploy hook.
6+
7+
databases:
8+
- name: ecommerce-db # Name for your managed MySQL database
9+
plan: free # Example: "free", "starter", etc.
10+
# databaseName: laravel_ecommerce_db # Optional: specify the actual database name
11+
# user: db_user # Optional: specify the username
12+
# The schema provided lists postgresMajorVersion, not mysqlMajorVersion.
13+
# For MySQL, version is typically tied to the plan or a default.
14+
15+
services:
16+
- type: web # Must be one of "web", "worker", "pserv", "cron" for serverService
17+
name: laravel-vue-ecommerce
18+
runtime: docker # Valid runtime for serverService
19+
autoDeploy: false # Boolean value
20+
healthCheckPath: /api/health # For web services
21+
# image: # Define if image is pre-built and pushed to a registry
22+
# url: registry.render.com/YOUR_RENDER_ORG_OR_USER/laravel-vue-ecommerce:latest
23+
envVars:
24+
- key: APP_NAME
25+
value: "Laravel Vue Ecommerce"
26+
- key: APP_ENV
27+
value: "production"
28+
- key: APP_DEBUG
29+
value: "false" # Env vars are strings
30+
- key: APP_URL
31+
value: "${RENDER_EXTERNAL_URL}" # Render injects this
32+
- key: ASSET_URL
33+
value: "${RENDER_EXTERNAL_URL}" # Render injects this
34+
- key: APP_KEY
35+
generateValue: true # Valid per envVarFromKeyValue schema
36+
- key: LOG_CHANNEL
37+
value: "stderr"
38+
# Database Connection
39+
- key: DB_CONNECTION # Tells Laravel to use the mysql driver
40+
value: "mysql"
41+
- key: DATABASE_URL # Laravel will parse this if DB_CONNECTION is set
42+
fromDatabase: # Valid per envVarFromDatabase schema
43+
name: ecommerce-db # Must match the name in the top-level 'databases' section
44+
property: connectionString # Provides the full database connection URL
45+
# Cache and Session
46+
- key: CACHE_DRIVER
47+
value: "file"
48+
- key: SESSION_DRIVER
49+
value: "file"
50+
# Stripe Keys (Set these as secrets in Render dashboard)
51+
- key: STRIPE_KEY
52+
sync: false # Valid per envVarFromKeyValue schema
53+
- key: STRIPE_SECRET
54+
sync: false
55+
- key: STRIPE_WEBHOOK_SECRET
56+
sync: false
57+
# Cashier Settings
58+
- key: CASHIER_CURRENCY
59+
value: "NOK"
60+
- key: CASHIER_CURRENCY_LOCALE
61+
value: "nb-NO"
62+
# Mailer Configuration (example, adjust as needed)
63+
- key: MAIL_MAILER
64+
value: "smtp"
65+
- key: MAIL_HOST
66+
value: "your_mail_host" # Set as secret or actual value
67+
- key: MAIL_PORT
68+
value: "587"
69+
- key: MAIL_USERNAME
70+
sync: false
71+
- key: MAIL_PASSWORD
72+
sync: false
73+
- key: MAIL_ENCRYPTION
74+
value: "tls"
75+
- key: MAIL_FROM_ADDRESS
76+
value: "hello@example.com"
77+
- key: MAIL_FROM_NAME
78+
value: "${APP_NAME}"
79+
80+
# Start command: runs our deploy script, then starts the main services.
81+
# Assumes the base Docker image (ric_harvey/nginx-php-fpm) has /start.sh as its CMD,
82+
# which typically runs supervisord to manage Nginx and PHP-FPM.
83+
startCommand: "/usr/local/bin/deploy.sh && /start.sh"
84+
85+
# Persistent disk for Laravel storage
86+
disk: # Valid per serverService schema, referencing "disk" definition
87+
name: laravel-storage # Name for the persistent disk
88+
mountPath: /var/www/html/storage # Mount path inside the container
89+
sizeGB: 1 # Size of the disk in GB, integer

routes/api.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,7 @@
2828
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
2929
return $request->user();
3030
});
31+
32+
Route::get('/health', function () {
33+
return response()->json(['status' => 'ok']);
34+
});

0 commit comments

Comments
 (0)