Skip to content

Feature - Docker overhaul #369

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .devcontainer/.bashrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Get current Git branch
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}

# Custom PS1 prompt: green user@host, blue directory, yellow git branch
export PS1='\[\e[32m\]\u@\h\[\e[m\]:\[\e[34m\]\w\[\e[33m\]$(parse_git_branch)\[\e[m\]\$ '
7 changes: 4 additions & 3 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
{
"name": "PrimeVue Inertia",
"dockerComposeFile": [
"../docker-compose.local.yml"
"../docker-compose.dev.yml"
],
"service": "laravel",
"workspaceFolder": "/var/www/html",
"mounts": [
"type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/sail/.ssh,readonly"
"type=bind,source=/home/${localEnv:USER}/.ssh,target=/home/www-data/.ssh,readonly"
],
"customizations": {
"vscode": {
"extensions": [
"DEVSENSE.phptools-vscode",
"MehediDracula.php-namespace-resolver",
"xdebug.php-debug",
"laravel.vscode-laravel",
"Vue.volar",
"hollowtree.vue-snippets",
Expand All @@ -35,7 +36,7 @@
}
}
},
"remoteUser": "sail",
"remoteUser": "www-data",
"postCreateCommand": "chown -R 1000:1000 /var/www/html 2>/dev/null || true"
// "forwardPorts": [],
// "runServices": [],
Expand Down
6 changes: 6 additions & 0 deletions .devcontainer/xdebug.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[xdebug]
zend_extension=xdebug.so
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9003
xdebug.log=/tmp/xdebug.log
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.git
tests
.env*
Dockerfile*
docker-*.yml
*.md
8 changes: 4 additions & 4 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ DB_CONNECTION=sqlite
#DB_USERNAME=
#DB_PASSWORD=

SESSION_DRIVER=file
SESSION_DRIVER=database
SESSION_LIFETIME=120
SESSION_ENCRYPT=false
SESSION_PATH=/
Expand Down Expand Up @@ -63,9 +63,9 @@ AWS_USE_PATH_STYLE_ENDPOINT=false

VITE_APP_NAME="${APP_NAME}"

WWWGROUP=1000
WWWUSER=1000
USER_ID=1000
GROUP_ID=1000
#XDEBUG_MODE=debug

APP_PORT=8000
VITE_PORT=5173
FORWARD_DB_PORT=
1 change: 1 addition & 0 deletions .infrastructure/s6-overlay/inertia-ssr/dependencies
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
php-fpm
2 changes: 2 additions & 0 deletions .infrastructure/s6-overlay/inertia-ssr/run
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/sh
exec php /var/www/html/artisan inertia:start-ssr
1 change: 1 addition & 0 deletions .infrastructure/s6-overlay/inertia-ssr/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
longrun
77 changes: 77 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
ARG NODE_VERSION=22

# Base Image
# https://serversideup.net/open-source/docker-php/docs
FROM serversideup/php:8.4-fpm-nginx-alpine AS base
USER root
RUN install-php-extensions bcmath gd pgsql

# Node Image
FROM node:${NODE_VERSION}-alpine AS node

# Install Composer packages
FROM base AS composer
WORKDIR /var/www/html
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-scripts --no-interaction

# Install and bundle NPM packages
FROM node:${NODE_VERSION}-alpine AS build-assets
WORKDIR /var/www/html
COPY package*.json ./
RUN npm ci
COPY --from=composer /var/www/html/vendor/tightenco/ziggy ./vendor/tightenco/ziggy
COPY vite.config.js ./
COPY resources ./resources
RUN npm run build

# Development Image
FROM base AS development
ARG USER_ID
ARG GROUP_ID
USER root
RUN apk add --no-cache curl git bash gnupg postgresql-client openssh-client \
&& apk add --no-cache --virtual .build-deps build-base autoconf \
&& install-php-extensions xdebug \
&& rm -rf /var/cache/apk/* \
&& apk del .build-deps
COPY --from=node /usr/lib /usr/lib
COPY --from=node /usr/local/lib /usr/local/lib
COPY --from=node /usr/local/include /usr/local/include
COPY --from=node /usr/local/bin /usr/local/bin
COPY .devcontainer/.bashrc /home/www-data/.bashrc
COPY .devcontainer/xdebug.ini /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN usermod -s /bin/bash www-data \
&& git config --global --add safe.directory /var/www/html \
&& mkdir -p /home/www-data/.ssh \
&& chown www-data:www-data /home/www-data/.ssh \
&& chown www-data:www-data /home/www-data/.bashrc \
&& docker-php-serversideup-set-id www-data $USER_ID:$GROUP_ID \
&& docker-php-serversideup-set-file-permissions --owner $USER_ID:$GROUP_ID --service nginx
WORKDIR /var/www/html
USER www-data

# Production Image
FROM base AS release
WORKDIR /var/www/html
COPY --chown=www-data:www-data --from=composer /var/www/html/vendor ./vendor
COPY --chown=www-data:www-data --from=build-assets /var/www/html/public/build ./public/build
COPY --chown=www-data:www-data . .
USER www-data

# SSR Production Image
FROM base AS ssr-release
COPY --from=node /usr/lib /usr/lib
COPY --from=node /usr/local/lib /usr/local/lib
COPY --from=node /usr/local/include /usr/local/include
COPY --from=node /usr/local/bin /usr/local/bin
COPY --chown=www-data:www-data --chmod=755 .infrastructure/s6-overlay/inertia-ssr /etc/s6-overlay/s6-rc.d/inertia-ssr
RUN touch /etc/s6-overlay/s6-rc.d/user/contents.d/inertia-ssr \
&& chown www-data:www-data /etc/s6-overlay/s6-rc.d/user/contents.d/inertia-ssr \
&& chmod 755 /etc/s6-overlay/s6-rc.d/user/contents.d/inertia-ssr
WORKDIR /var/www/html
COPY --chown=www-data:www-data --from=composer /var/www/html/vendor ./vendor
COPY --chown=www-data:www-data --from=build-assets /var/www/html/public/build ./public/build
COPY --chown=www-data:www-data --from=build-assets /var/www/html/bootstrap/ssr ./bootstrap/ssr
COPY --chown=www-data:www-data . .
USER www-data
5 changes: 4 additions & 1 deletion app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Providers;

use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
Expand All @@ -19,6 +20,8 @@ public function register(): void
*/
public function boot(): void
{
//
if ($this->app->environment('production')) {
URL::forceScheme('https');
}
}
}
8 changes: 8 additions & 0 deletions bootstrap/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
BaseEncryptCookies::class => EncryptCookies::class
],
);
// TrustProxies middleware for Traefik handling assets over https
$middleware->trustProxies(
at: '*',
headers: Request::HEADER_X_FORWARDED_FOR
| Request::HEADER_X_FORWARDED_HOST
| Request::HEADER_X_FORWARDED_PORT
| Request::HEADER_X_FORWARDED_PROTO
);
})
->withExceptions(function (Exceptions $exceptions) {
$exceptions->respond(function (Response $response, Throwable $exception, Request $request) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
-- create a PostgreSQL testing db for PHPUnit test suite
SELECT 'CREATE DATABASE testing'
WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = 'testing')\gexec
56 changes: 56 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
services:
laravel:
build:
context: .
dockerfile: Dockerfile
target: development
args:
USER_ID: '${USER_ID:-1000}'
GROUP_ID: '${GROUP_ID:-1000}'
extra_hosts:
- 'host.docker.internal:host-gateway'
#ports:
#- '${VITE_PORT:-5173}:${VITE_PORT:-5173}' # Not necessarily required for dev containers (auto port forwarding)
environment:
PHP_OPCACHE_ENABLE: '1'
PHP_OPCACHE_REVALIDATE_FREQ: '0'
XDEBUG_MODE: '${XDEBUG_MODE:-off}'
volumes:
- '.:/var/www/html'
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.laravel-primevue.rule=Host(`laravel-primevue.localhost`)'
- 'traefik.http.services.laravel-primevue.loadbalancer.server.port=8080' # exposed http port from serversideup image
networks:
- proxy
- laravel
depends_on:
- pgsql

pgsql:
image: 'postgres:17'
ports:
- '${FORWARD_DB_PORT:-5432}:5432'
environment:
PGPASSWORD: '${DB_PASSWORD:-secret}'
POSTGRES_DB: '${DB_DATABASE}'
POSTGRES_USER: '${DB_USERNAME}'
POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}'
volumes:
- 'postgres-data:/var/lib/postgresql/data'
- './database/create-pg-testing-database.sql:/docker-entrypoint-initdb.d/10-create-testing-database.sql'
networks:
- laravel
healthcheck:
test: [ "CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}" ]
retries: 3
timeout: 5s

volumes:
postgres-data:

networks:
laravel:
proxy:
name: traefik_network
external: true
60 changes: 0 additions & 60 deletions docker-compose.local.yml

This file was deleted.

60 changes: 60 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
services:
laravel:
build:
context: .
dockerfile: Dockerfile
target: release
restart: always
env_file: '.env'
environment:
PHP_OPCACHE_ENABLE: '1'
SSL_MODE: 'mixed'
volumes:
- 'storage-public:/var/www/html/storage/app/public/'
- 'storage-sessions:/var/www/html/storage/framework/sessions'
- 'storage-logs:/var/www/html/storage/logs'
labels:
- 'traefik.enable=true'
- 'traefik.http.routers.your-app-name.rule=Host(`your-domain.com`)'
- 'traefik.http.routers.your-app-name.entrypoints=websecure'
- 'traefik.http.routers.your-app-name.tls=true'
- 'traefik.http.routers.your-app-name.tls.certresolver=letsencrypt'
- 'traefik.http.services.your-app-name.loadbalancer.server.port=8080' # exposed http port from serversideup image
# Health check
- 'traefik.http.services.your-app-name.loadbalancer.healthcheck.path=/healthcheck'
- 'traefik.http.services.your-app-name.loadbalancer.healthcheck.interval=30s'
- 'traefik.http.services.your-app-name.loadbalancer.healthcheck.timeout=5s'
- 'traefik.http.services.your-app-name.loadbalancer.healthcheck.scheme=http'
networks:
- proxy
depends_on:
- pgsql

pgsql:
image: postgres:17
restart: always
ports:
- '${FORWARD_DB_PORT:-5432}:5432'
environment:
POSTGRES_DB: '${DB_DATABASE}'
POSTGRES_USER: '${DB_USERNAME}'
POSTGRES_PASSWORD: '${DB_PASSWORD}'
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- proxy
healthcheck:
test: ['CMD', 'pg_isready', '-q', '-d', '${DB_DATABASE}', '-U', '${DB_USERNAME}']
retries: 3
timeout: 5s

volumes:
postgres-data:
storage-public:
storage-sessions:
storage-logs:

networks:
proxy:
name: traefik_network
external: true
6 changes: 0 additions & 6 deletions docker/local/database/mysql/create-testing-database.sh

This file was deleted.

Loading