Fix/docker production #4
+32
-1
@@ -1,6 +1,37 @@
|
||||
# Build descriptors (not application code)
|
||||
Dockerfile*
|
||||
|
||||
# Version control
|
||||
.git
|
||||
.gitea
|
||||
|
||||
# AI / IDE tooling
|
||||
.claude
|
||||
|
||||
# Dev tooling
|
||||
.gitignore
|
||||
/.phpunit.cache
|
||||
phpunit.xml.dist
|
||||
tests/
|
||||
|
||||
# Documentation
|
||||
CHANGELOG.md
|
||||
CLAUDE.md
|
||||
README.md
|
||||
|
||||
# Compose / deployment descriptors (not app code)
|
||||
docker-compose.yml
|
||||
docker-compose.override.yml
|
||||
docker-compose.prod.yml
|
||||
|
||||
# Dependencies — re-installed from lockfile in the build stage;
|
||||
# a local vendor/ in the build context would silently override the clean install
|
||||
vendor/
|
||||
|
||||
# Runtime dirs (generated at build or run time, not from source)
|
||||
var/
|
||||
|
||||
# Env files — .env contains only placeholder defaults and is needed by composer dump-env;
|
||||
# local overrides with real secrets stay excluded
|
||||
.env.local
|
||||
.env.*.local
|
||||
docker-compose.override.yml
|
||||
|
||||
@@ -15,7 +15,7 @@ on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: 'Release tag (semver, e.g. 1.2.3)'
|
||||
description: "Release tag (semver, e.g. 1.2.3)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
@@ -55,8 +55,6 @@ jobs:
|
||||
images: ${{ env.REGISTRY }}/${{ gitea.repository }}
|
||||
tags: |
|
||||
type=semver,pattern={{version}},value=${{ inputs.tag }}
|
||||
type=semver,pattern={{major}}.{{minor}},value=${{ inputs.tag }}
|
||||
type=semver,pattern={{major}},value=${{ inputs.tag }}
|
||||
labels: |
|
||||
org.opencontainers.image.source=${{ gitea.server_url }}/${{ gitea.repository }}
|
||||
|
||||
@@ -75,10 +73,22 @@ jobs:
|
||||
username: ${{ gitea.actor }}
|
||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||
|
||||
# Build a single-arch image locally so Trivy can inspect it before the real push.
|
||||
- name: Build local image for scanning
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
target: final
|
||||
platforms: linux/amd64
|
||||
load: true
|
||||
tags: scan-target:${{ inputs.tag }}
|
||||
cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ gitea.repository }}:buildcache
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
target: final
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
|
||||
@@ -3,5 +3,4 @@
|
||||
/vendor/
|
||||
/var/
|
||||
/public/bundles/
|
||||
composer.lock
|
||||
/.phpunit.cache
|
||||
|
||||
+27
-25
@@ -1,9 +1,16 @@
|
||||
#syntax=docker/dockerfile:1
|
||||
|
||||
FROM dunglas/frankenphp:1-php8.4-alpine AS base
|
||||
|
||||
RUN apk add --no-cache \
|
||||
curl \
|
||||
icu-libs \
|
||||
libzip
|
||||
RUN apk add --no-cache icu-dev libzip-dev \
|
||||
&& docker-php-ext-install -j$(nproc) intl opcache zip \
|
||||
&& apk del icu-dev libzip-dev \
|
||||
&& apk add --no-cache curl icu-libs libzip \
|
||||
&& cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
|
||||
&& mkdir -p $PHP_INI_DIR/app.conf.d
|
||||
|
||||
ENV PHP_INI_SCAN_DIR=":$PHP_INI_DIR/app.conf.d"
|
||||
ENV COMPOSER_ALLOW_SUPERUSER=1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -21,34 +28,29 @@ RUN composer install \
|
||||
# ── build stage (generate optimised classmap with source present) ──────────────
|
||||
FROM deps AS build
|
||||
COPY . .
|
||||
RUN composer dump-autoload --optimize --no-dev --no-interaction
|
||||
|
||||
# ── dev stage (all deps + Xdebug, source is mounted at runtime) ───────────────
|
||||
FROM base AS dev
|
||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||
RUN apk add --no-cache ${PHPIZE_DEPS} linux-headers \
|
||||
&& pecl install xdebug \
|
||||
&& docker-php-ext-enable xdebug \
|
||||
&& apk del ${PHPIZE_DEPS}
|
||||
COPY docker/php/xdebug.ini /usr/local/etc/php/conf.d/docker-xdebug.ini
|
||||
COPY docker/frankenphp/Caddyfile.dev /etc/caddy/Caddyfile
|
||||
COPY composer.json composer.lock* ./
|
||||
RUN composer install --no-scripts --no-interaction --prefer-dist
|
||||
EXPOSE 8080
|
||||
ENV APP_ENV=dev APP_DEBUG=1
|
||||
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
|
||||
RUN composer dump-autoload --classmap-authoritative --no-dev --no-interaction && \
|
||||
mkdir -p var/cache var/log && \
|
||||
APP_ENV=prod APP_SECRET=placeholder php bin/console cache:warmup --no-debug && \
|
||||
composer dump-env prod
|
||||
|
||||
# ── final (prod) stage — no composer binary ────────────────────────────────────
|
||||
FROM base AS final
|
||||
|
||||
RUN addgroup -S app && adduser -S -G app app
|
||||
|
||||
COPY --from=build /app/vendor /app/vendor
|
||||
COPY . .
|
||||
COPY docker/frankenphp/Caddyfile /etc/caddy/Caddyfile
|
||||
COPY --link --from=build /app/vendor /app/vendor
|
||||
COPY --link --from=build /app/var/cache/prod /app/var/cache/prod
|
||||
COPY --link bin/ ./bin/
|
||||
COPY --link config/ ./config/
|
||||
COPY --link public/ ./public/
|
||||
COPY --link src/ ./src/
|
||||
COPY --link composer.json composer.lock ./
|
||||
COPY --link docker/frankenphp/Caddyfile /etc/caddy/Caddyfile
|
||||
COPY --link docker/php/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/
|
||||
|
||||
RUN mkdir -p var/cache var/log \
|
||||
&& chown -R app:app /app
|
||||
RUN chmod +x bin/console && \
|
||||
mkdir -p var/cache/prod/pools var/log /config/caddy /data/caddy && \
|
||||
chown -R app:app /app /config /data
|
||||
|
||||
USER app
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
FROM dunglas/frankenphp:1-php8.4-alpine
|
||||
|
||||
RUN apk add --no-cache icu-dev libzip-dev \
|
||||
&& docker-php-ext-install -j$(nproc) intl opcache zip \
|
||||
&& apk del icu-dev libzip-dev \
|
||||
&& apk add --no-cache curl icu-libs libzip \
|
||||
&& cp "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" \
|
||||
&& mkdir -p $PHP_INI_DIR/app.conf.d
|
||||
|
||||
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||
|
||||
RUN apk add --no-cache ${PHPIZE_DEPS} linux-headers \
|
||||
&& pecl install xdebug \
|
||||
&& docker-php-ext-enable xdebug \
|
||||
&& apk del ${PHPIZE_DEPS}
|
||||
|
||||
ENV PHP_INI_SCAN_DIR=":$PHP_INI_DIR/app.conf.d"
|
||||
ENV COMPOSER_ALLOW_SUPERUSER=1
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY docker/php/xdebug.ini /usr/local/etc/php/conf.d/docker-xdebug.ini
|
||||
COPY docker/php/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/
|
||||
COPY docker/frankenphp/Caddyfile.dev /etc/caddy/Caddyfile
|
||||
COPY composer.json composer.lock* ./
|
||||
RUN composer install --no-scripts --no-interaction --prefer-dist
|
||||
|
||||
EXPOSE 8080
|
||||
ENV APP_ENV=dev APP_DEBUG=1
|
||||
CMD ["frankenphp", "run", "--config", "/etc/caddy/Caddyfile"]
|
||||
Generated
+6053
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
services:
|
||||
graph:
|
||||
build:
|
||||
target: dev
|
||||
dockerfile: Dockerfile.dev
|
||||
volumes:
|
||||
- .:/app
|
||||
- /app/vendor # keeps vendor from the dev image, not your local dir
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
services:
|
||||
graph:
|
||||
image: git.arthurerlich.de/haylan/git-contribution-graph:latest
|
||||
container_name: git-contribution-graph
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
APP_ENV: prod
|
||||
APP_DEBUG: "0"
|
||||
APP_SECRET: "${APP_SECRET}"
|
||||
ALLOWED_HOSTS: "${ALLOWED_HOSTS:-}"
|
||||
GITHUB_USER: "${GITHUB_USER:-}"
|
||||
GITHUB_TOKEN: "${GITHUB_TOKEN:-}"
|
||||
GITLAB_USER: "${GITLAB_USER:-}"
|
||||
GITLAB_TOKEN: "${GITLAB_TOKEN:-}"
|
||||
GITLAB_URL: "${GITLAB_URL:-}"
|
||||
GITEA_USER: "${GITEA_USER:-}"
|
||||
GITEA_TOKEN: "${GITEA_TOKEN:-}"
|
||||
GITEA_URL: "${GITEA_URL:-}"
|
||||
volumes:
|
||||
- cache:/app/var/cache/prod/pools
|
||||
- logs:/app/var/log
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
cache:
|
||||
logs:
|
||||
+2
-1
@@ -21,13 +21,14 @@ services:
|
||||
GITEA_TOKEN: "${GITEA_TOKEN:-}"
|
||||
GITEA_URL: "${GITEA_URL:-}"
|
||||
volumes:
|
||||
- cache:/app/var/cache
|
||||
- cache:/app/var/cache/prod/pools
|
||||
- logs:/app/var/log
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
volumes:
|
||||
cache:
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
opcache.validate_timestamps=1
|
||||
opcache.revalidate_freq=0
|
||||
@@ -0,0 +1,6 @@
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=0
|
||||
opcache.memory_consumption=128
|
||||
opcache.max_accelerated_files=20000
|
||||
opcache.validate_timestamps=0
|
||||
expose_php=0
|
||||
Reference in New Issue
Block a user