From 85a90e14e8a05f5533b4fc6fd226a2d84cbcb86a Mon Sep 17 00:00:00 2001 From: everythings-gonna-be-alright Date: Tue, 19 May 2026 03:51:28 +0300 Subject: [PATCH 1/5] Dockerfile refactoring --- Dockerfile | 89 ------------------- README.md | 10 ++- docker-compose.yml | 38 ++++---- docker/Dockerfile | 79 ++++++++++++++++ docker/{entrypoint.sh => aio-entrypoint.sh} | 8 +- .../nginx-chadmin.conf} | 11 ++- docker/configs/nginx.conf | 36 ++++++++ docker/configs/php-fpm.conf | 27 ++++++ docker/{prod => configs}/supervisord.conf | 8 +- docker/dev/nginx/Dockerfile | 42 --------- docker/dev/php/Dockerfile | 30 ------- docker/prod/nginx.conf | 68 -------------- docker/prod/php-fpm.conf | 18 ---- docker/prod/php.ini | 16 ---- package-lock.json | 8 +- 15 files changed, 184 insertions(+), 304 deletions(-) delete mode 100644 Dockerfile create mode 100644 docker/Dockerfile rename docker/{entrypoint.sh => aio-entrypoint.sh} (71%) mode change 100755 => 100644 rename docker/{dev/nginx/nginx/conf.d/default.conf => configs/nginx-chadmin.conf} (71%) create mode 100644 docker/configs/nginx.conf create mode 100644 docker/configs/php-fpm.conf rename docker/{prod => configs}/supervisord.conf (82%) delete mode 100644 docker/dev/nginx/Dockerfile delete mode 100644 docker/dev/php/Dockerfile delete mode 100644 docker/prod/nginx.conf delete mode 100644 docker/prod/php-fpm.conf delete mode 100644 docker/prod/php.ini diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 16adb9e..0000000 --- a/Dockerfile +++ /dev/null @@ -1,89 +0,0 @@ -# ----------------------------------------------------------------------------- -# Stage 1 — composer vendor (no dev deps) -# ----------------------------------------------------------------------------- -FROM composer:2.9.7 AS vendor - -WORKDIR /app - -COPY composer.json composer.lock ./ -COPY bin/console bin/console - -# Composer image ships its own PHP, which may lag behind the runtime version below. -# Skip the platform PHP check at install time — the runtime PHP is what executes the code. -RUN composer install \ - --no-scripts \ - --no-dev \ - --optimize-autoloader \ - --no-progress \ - --no-interaction \ - --ignore-platform-req=php - -# ----------------------------------------------------------------------------- -# Stage 2 — frontend build (Vite → public/build/) -# ----------------------------------------------------------------------------- -FROM node:24.15.0-alpine3.23 AS frontend - -RUN apk add --no-cache python3 make g++ - -WORKDIR /app - -COPY package.json package-lock.json ./ -# npm install (not `npm ci`) — the committed lock file has stale peer-dep entries -# from earlier upstream packages; npm install reconciles silently, npm ci fails strict. -RUN npm install --no-audit --no-fund --no-progress --legacy-peer-deps - -COPY frontend/ ./frontend/ -COPY assets/ ./assets/ -COPY public/ ./public/ - -RUN npm run build - -# ----------------------------------------------------------------------------- -# Stage 3 — runtime: php-fpm + nginx + supervisord, single container -# ----------------------------------------------------------------------------- -FROM php:8.5.5-fpm-alpine3.22 - -RUN apk add --no-cache \ - nginx \ - supervisor \ - tzdata \ - libzip-dev \ - icu-dev \ - libxml2-dev \ - linux-headers \ - && docker-php-ext-install -j"$(nproc)" \ - intl \ - bcmath \ - zip \ - pcntl \ - pdo_mysql \ - mysqli \ - soap \ - && (docker-php-ext-enable opcache || true) \ - && rm -rf /var/cache/apk/* /tmp/* - -WORKDIR /var/www/html - -# Application source + built artifacts -COPY . /var/www/html -COPY --from=vendor /app/vendor/ /var/www/html/vendor/ -COPY --from=frontend /app/public/build /var/www/html/public/build - -# Runtime configs -COPY docker/prod/nginx.conf /etc/nginx/nginx.conf -COPY docker/prod/php-fpm.conf /usr/local/etc/php-fpm.d/zz-chadmin.conf -COPY docker/prod/php.ini /usr/local/etc/php/conf.d/zz-chadmin.ini -COPY docker/prod/supervisord.conf /etc/supervisord.conf -COPY docker/entrypoint.sh /usr/local/bin/entrypoint.sh - -RUN chmod +x /usr/local/bin/entrypoint.sh \ - && mkdir -p /var/www/html/var /run/nginx \ - && chown -R www-data:www-data /var/www/html/var /var/www/html/public \ - # Symfony Dotenv::bootEnv() вимагає реальний .env; справжні значення приходять через - # `docker run -e ...` і мають пріоритет над файлом, тому .env.example тут — лише плейсхолдер. - && cp /var/www/html/.env.example /var/www/html/.env - -EXPOSE 80 - -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -CMD ["supervisord", "-c", "/etc/supervisord.conf"] diff --git a/README.md b/README.md index 6ccc753..d534298 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ Chadmin is an administration panel for ClickHouse — a real-time dashboard for monitoring running queries, managing users and access, and operating ClickHouse Cloud services. It auto-detects whether you're running a **single node**, a **self-hosted cluster**, or **ClickHouse Cloud**, and adapts the UI and SQL accordingly. - ![Chadmin Dashboard](https://github.com/user-attachments/assets/a2541685-0b4b-433f-8cb0-3f72d6c7204f) ## Installation and Setup @@ -54,24 +53,29 @@ docker run -d --name chadmin -p 8080:80 --env-file .env bun4uk/chadmin:latest ### Run via Docker Compose (development) #### Requirements + - Docker and Docker Compose - Git #### Quick Start 1. Clone the repository: + ```bash git clone https://github.com/bun4uk/chadmin.git cd chadmin ``` 2. Create and configure the `.env` file: + ```bash cp .env.example .env ``` + Edit `.env` and add your ClickHouse credentials. For ClickHouse Cloud, set `CLICKHOUSE_CLOUD_KEY_ID` and `CLICKHOUSE_CLOUD_KEY_SECRET` — Cloud mode turns on automatically when these are present. See `.env.example` for the full list. 3. Launch the project: + ```bash docker-compose up -d ``` @@ -102,11 +106,13 @@ docker-compose exec frontend npm run build # one-shot production build ### Useful Commands #### Complete shutdown of the project + ```bash docker-compose down ``` #### Viewing logs + ```bash docker-compose logs -f app docker-compose logs -f nginx @@ -114,6 +120,7 @@ docker-compose logs -f frontend ``` #### Full restart with cache clearing + ```bash docker-compose down rm -rf var/cache/* var/log/* public/build/* @@ -141,4 +148,3 @@ docker-compose exec app bin/console cache:clear - Cloud-only: wake idle/stopped services from the UI; deep-link to a specific warehouse/service via URL params (`?warehouse=…&service=…`) - Light/dark theme toggle, persisted per browser - Polling pauses when the tab is hidden, so idle Cloud services aren't kept warm by a background tab - diff --git a/docker-compose.yml b/docker-compose.yml index efc413b..96a70db 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,54 +1,56 @@ services: nginx: - build: - context: . - dockerfile: docker/dev/nginx/Dockerfile + image: nginxinc/nginx-unprivileged:1.31.0-alpine3.23-slim + user: "1984:1984" volumes: - - ./docker/dev/nginx/nginx/conf.d/default.conf:/etc/nginx/conf.d/default.conf + - ./docker/configs/nginx.conf:/etc/nginx/nginx.conf + - ./docker/configs/nginx-chadmin.conf:/etc/nginx/conf.d/default.conf - .:/var/www/html + - php-sock:/sock ports: - "80:80" depends_on: - - app + - php-fpm - frontend env_file: - .env networks: - - sp-net + - docker-net - app: + php-fpm: build: context: . - dockerfile: docker/dev/php/Dockerfile + dockerfile: docker/Dockerfile + target: dev volumes: - .:/var/www/html + - php-sock:/sock env_file: - .env networks: - - sp-net + - docker-net composer: image: composer:latest volumes: - .:/app working_dir: /app - command: ["composer"] + command: ["composer", "install", "--no-interaction", "--prefer-dist"] networks: - - sp-net + - docker-net frontend: image: node:24.15.0-alpine3.23 volumes: - .:/app working_dir: /app - command: sh -c "npm install && npm run watch" + command: sh -c "npm install" networks: - - sp-net - deploy: - resources: - limits: - memory: 8G + - docker-net + +volumes: + php-sock: networks: - sp-net: + docker-net: driver: "bridge" diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..0873d53 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,79 @@ +FROM composer:2.9.8 AS vendor + +WORKDIR /app + +COPY composer.json composer.lock ./ +COPY bin/console bin/console + +# Composer image ships its own PHP, which may lag behind the runtime version below. +# Skip the platform PHP check at install time — the runtime PHP is what executes the code. +RUN composer install \ + --no-scripts \ + --no-dev \ + --optimize-autoloader \ + --no-progress \ + --no-interaction \ + --ignore-platform-req=php + +FROM node:24.15.0-alpine3.23 AS frontend + +RUN apk add --no-cache python3 make g++ + +WORKDIR /app + +COPY package.json package-lock.json ./ +# npm install (not `npm ci`) — the committed lock file has stale peer-dep entries +# from earlier upstream packages; npm install reconciles silently, npm ci fails strict. +RUN npm install --no-audit --no-fund --no-progress --legacy-peer-deps + +COPY frontend/ ./frontend/ +COPY assets/ ./assets/ +COPY public/ ./public/ + +RUN npm run build + +FROM php:8.5.5-fpm-alpine3.23 AS base + +RUN (docker-php-ext-enable opcache || true) + +WORKDIR /var/www/html + +RUN addgroup -S chadmin && adduser --uid 1984 -S chadmin -G chadmin && \ + mkdir -p /sock && chown chadmin:chadmin /sock && chmod 750 /sock + +# Application source + built artifacts +COPY --chown=chadmin:chadmin . /var/www/html +COPY --from=vendor --chown=chadmin:chadmin /app/vendor/ /var/www/html/vendor/ +COPY --from=frontend --chown=chadmin:chadmin /app/public/build /var/www/html/public/build + +# Target for php fpm mode +FROM base AS dev + +COPY docker/configs/php-fpm.conf /usr/local/etc/php-fpm.d/www.conf +USER chadmin +CMD ["php-fpm", "-F"] + +# Target for all in one image mode +FROM base AS aio + +RUN apk add --no-cache \ + nginx \ + supervisor \ + && rm -rf /var/cache/apk/* /tmp/* + +# Runtime configs +COPY docker/configs/nginx.conf /etc/nginx/nginx.conf +COPY docker/configs/nginx-chadmin.conf /etc/nginx/conf.d/default.conf +COPY docker/configs/php-fpm.conf /usr/local/etc/php-fpm.d/www.conf +COPY docker/configs/supervisord.conf /etc/supervisord.conf +COPY docker/aio-entrypoint.sh /usr/local/bin/entrypoint.sh + +RUN chmod +x /usr/local/bin/entrypoint.sh \ + && cp /var/www/html/.env.example /var/www/html/.env + +USER chadmin + +EXPOSE 80 + +ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] +CMD ["supervisord", "-c", "/etc/supervisord.conf"] diff --git a/docker/entrypoint.sh b/docker/aio-entrypoint.sh old mode 100755 new mode 100644 similarity index 71% rename from docker/entrypoint.sh rename to docker/aio-entrypoint.sh index 88258d4..5843320 --- a/docker/entrypoint.sh +++ b/docker/aio-entrypoint.sh @@ -1,12 +1,6 @@ #!/bin/sh set -e -# Symfony writes cache і логи в /var/www/html/var — мусить існувати і бути writable -# власником php-fpm worker'а (www-data). -mkdir -p /var/www/html/var/cache /var/www/html/var/log -chown -R www-data:www-data /var/www/html/var -chmod -R u+rwX,g+rwX /var/www/html/var - # Symfony вимагає непорожнє APP_SECRET. У проді користувач має передати своє через -e, # але щоб контейнер не падав без явно заданого значення, генеруємо випадкове fallback. if [ -z "${APP_SECRET:-}" ]; then @@ -18,4 +12,4 @@ fi # Кеш Symfony білдиться лінivo на першому запиті — warmup тут навмисно не робимо, # щоб уникнути chown-перегонів між root-entrypoint'ом і www-data-php-fpm. -exec "$@" +exec "$@" \ No newline at end of file diff --git a/docker/dev/nginx/nginx/conf.d/default.conf b/docker/configs/nginx-chadmin.conf similarity index 71% rename from docker/dev/nginx/nginx/conf.d/default.conf rename to docker/configs/nginx-chadmin.conf index 0c225b3..6812ad3 100644 --- a/docker/dev/nginx/nginx/conf.d/default.conf +++ b/docker/configs/nginx-chadmin.conf @@ -1,14 +1,13 @@ +upstream php_fpm { + server unix:/sock/fpm.sock; +} + server { listen 80; server_name _; root /var/www/html/public; index index.php index.html; - # Дозволяємо Nginx щоразу оновлювати DNS-запис сервісу `app` - resolver 127.0.0.11 ipv6=off; - # Змінна, щоб примусити повторну резолюцію при кожному запиті - set $php_backend "app:9000"; - # For serving embedded Symfony Encore resources location /build/ { try_files $uri =404; @@ -25,7 +24,7 @@ server { } location ~ ^/index\.php(/|$) { - fastcgi_pass $php_backend; + fastcgi_pass php_fpm; fastcgi_split_path_info ^(.+\.php)(/.*)$; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; diff --git a/docker/configs/nginx.conf b/docker/configs/nginx.conf new file mode 100644 index 0000000..335851d --- /dev/null +++ b/docker/configs/nginx.conf @@ -0,0 +1,36 @@ +worker_processes auto; + +error_log /dev/stderr notice; +pid /tmp/nginx.pid; + + +events { + worker_connections 1024; +} + + +http { + proxy_temp_path /tmp/proxy_temp; + client_body_temp_path /tmp/client_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + scgi_temp_path /tmp/scgi_temp; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + + access_log /dev/stdout main; + + sendfile on; + #tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + include /etc/nginx/conf.d/*.conf; +} \ No newline at end of file diff --git a/docker/configs/php-fpm.conf b/docker/configs/php-fpm.conf new file mode 100644 index 0000000..317e405 --- /dev/null +++ b/docker/configs/php-fpm.conf @@ -0,0 +1,27 @@ +[global] +daemonize = no +error_log = /proc/self/fd/2 +log_level = warning +log_limit = 41943040 +log_buffering = no +process_control_timeout = 3 + +[www] +listen = /sock/fpm.sock +listen.mode = 0660 +listen.backlog = -1 +clear_env = no + +pm = static +pm.max_children = 50 +pm.max_requests = 0 +pm.status_path = /status + +rlimit_core = unlimited +catch_workers_output = yes +request_terminate_timeout = 60 +decorate_workers_output = no + +env[HOSTNAME] = docker +php_admin_flag[log_errors] = on +php_admin_value[error_log] = /proc/self/fd/2 diff --git a/docker/prod/supervisord.conf b/docker/configs/supervisord.conf similarity index 82% rename from docker/prod/supervisord.conf rename to docker/configs/supervisord.conf index 1de52da..408a35c 100644 --- a/docker/prod/supervisord.conf +++ b/docker/configs/supervisord.conf @@ -1,9 +1,9 @@ [supervisord] nodaemon=true -user=root -logfile=/dev/stdout +logfile=/dev/stderr logfile_maxbytes=0 -pidfile=/var/run/supervisord.pid +loglevel=warn +pidfile=/tmp/supervisord.pid [program:php-fpm] command=php-fpm -F @@ -23,4 +23,4 @@ priority=20 stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr -stderr_logfile_maxbytes=0 +stderr_logfile_maxbytes=0 \ No newline at end of file diff --git a/docker/dev/nginx/Dockerfile b/docker/dev/nginx/Dockerfile deleted file mode 100644 index 5b0a27e..0000000 --- a/docker/dev/nginx/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -FROM nginx:1.28.3-alpine3.23 AS builder - -ENV VTS_VERSION=0.2.1 - -# Download sources -RUN wget "http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz" -O nginx.tar.gz && \ - wget "https://github.com/vozlt/nginx-module-vts/archive/v${VTS_VERSION}.tar.gz" -O vts.tar.gz - -# For latest build deps, see https://github.com/nginxinc/docker-nginx/blob/master/mainline/alpine/Dockerfile -RUN apk add --no-cache --virtual .build-deps \ - gcc \ - libc-dev \ - make \ - openssl-dev \ - zlib-dev \ - gnupg \ - libxslt-dev \ - pcre-dev \ - g++ - -# Reuse same cli arguments as the nginx:alpine image used to build -RUN CONFARGS=$(nginx -V 2>&1 | sed -n -e 's/^.*arguments: //p') \ - mkdir -p /usr/src && \ - tar -zxC /usr/src -f nginx.tar.gz && \ - tar -xzvf "vts.tar.gz" && \ - VTSDIR="$(pwd)/nginx-module-vts-${VTS_VERSION}" && \ - cd /usr/src/nginx-$NGINX_VERSION && \ - ./configure --with-compat --with-stream $CONFARGS --add-dynamic-module=$VTSDIR && \ - make modules - -FROM nginx:1.28.3-alpine3.23 - -# Copy all modules -COPY --from=builder /usr/src/nginx-$NGINX_VERSION/objs/*.so /usr/lib/nginx/modules/ -RUN apk add --no-cache --virtual .build-deps \ - vim \ - libmaxminddb-dev \ - libstdc++ - -WORKDIR /var/www/html/ - -STOPSIGNAL SIGQUIT diff --git a/docker/dev/php/Dockerfile b/docker/dev/php/Dockerfile deleted file mode 100644 index fe544f7..0000000 --- a/docker/dev/php/Dockerfile +++ /dev/null @@ -1,30 +0,0 @@ -FROM php:8.5.5-fpm-alpine3.22 - -RUN apk add --no-cache \ - libzip-dev \ - icu-dev \ - libxml2-dev \ - tzdata \ - linux-headers - -RUN docker-php-ext-install intl \ - && docker-php-ext-install bcmath \ - && docker-php-ext-install zip \ - && docker-php-ext-install pcntl \ - && docker-php-ext-install pdo_mysql \ - && docker-php-ext-install mysqli \ - && docker-php-ext-install soap - -# Opcache: in PHP 8.5 the extension may ship compiled-in or as shared — try to enable, -# ignore failure (some base images don't expose a separate opcache.so). -RUN docker-php-ext-enable opcache || true - -RUN php -r "readfile('https://getcomposer.org/installer');" | php -- --install-dir=/usr/bin/ --filename=composer --version=2.9.7 - -WORKDIR /var/www/html - -STOPSIGNAL SIGQUIT - -EXPOSE 9000 - -CMD ["php-fpm", "-R", "-F"] diff --git a/docker/prod/nginx.conf b/docker/prod/nginx.conf deleted file mode 100644 index 7e51ac9..0000000 --- a/docker/prod/nginx.conf +++ /dev/null @@ -1,68 +0,0 @@ -user www-data; -worker_processes auto; -error_log /dev/stderr warn; -pid /run/nginx/nginx.pid; - -events { - worker_connections 1024; - multi_accept on; -} - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" "$http_user_agent"'; - access_log /dev/stdout main; - - sendfile on; - tcp_nopush on; - tcp_nodelay on; - server_tokens off; - keepalive_timeout 65; - client_max_body_size 50M; - - gzip on; - gzip_vary on; - gzip_min_length 1024; - gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml; - - server { - listen 80 default_server; - server_name _; - root /var/www/html/public; - index index.php; - - location /build/ { - try_files $uri =404; - expires 1y; - add_header Cache-Control "public, immutable"; - access_log off; - } - - location /assets/ { - try_files $uri =404; - expires 1y; - add_header Cache-Control "public, immutable"; - access_log off; - } - - location / { - try_files $uri /index.php$is_args$args; - } - - location ~ ^/index\.php(/|$) { - fastcgi_pass 127.0.0.1:9000; - fastcgi_split_path_info ^(.+\.php)(/.*)$; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param DOCUMENT_ROOT $document_root; - internal; - } - - location ~ \.php$ { - return 404; - } - } -} diff --git a/docker/prod/php-fpm.conf b/docker/prod/php-fpm.conf deleted file mode 100644 index c432028..0000000 --- a/docker/prod/php-fpm.conf +++ /dev/null @@ -1,18 +0,0 @@ -[www] -user = www-data -group = www-data -listen = 127.0.0.1:9000 -listen.owner = www-data -listen.group = www-data - -pm = dynamic -pm.max_children = 20 -pm.start_servers = 4 -pm.min_spare_servers = 2 -pm.max_spare_servers = 6 -pm.max_requests = 500 - -catch_workers_output = yes -decorate_workers_output = no - -clear_env = no diff --git a/docker/prod/php.ini b/docker/prod/php.ini deleted file mode 100644 index b2da3f5..0000000 --- a/docker/prod/php.ini +++ /dev/null @@ -1,16 +0,0 @@ -memory_limit = 256M -upload_max_filesize = 32M -post_max_size = 32M -max_execution_time = 60 -expose_php = Off - -date.timezone = UTC - -opcache.enable = 1 -opcache.enable_cli = 0 -opcache.memory_consumption = 128 -opcache.interned_strings_buffer = 16 -opcache.max_accelerated_files = 10000 -opcache.validate_timestamps = 0 -opcache.jit = tracing -opcache.jit_buffer_size = 64M diff --git a/package-lock.json b/package-lock.json index e011d1d..3c26a6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { - "name": "chadmin-symfony", - "version": "1.0.0", + "name": "chadmin", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "chadmin-symfony", - "version": "1.0.0", + "name": "chadmin", + "version": "2.0.0", "license": "MIT", "dependencies": { "@clickhouse/click-ui": "0.1.0", From 265a4e55c1532cee346b3b703450436b22ddbcdf Mon Sep 17 00:00:00 2001 From: everythings-gonna-be-alright Date: Tue, 19 May 2026 03:56:46 +0300 Subject: [PATCH 2/5] Remove dev target --- docker-compose.yml | 2 +- docker/Dockerfile | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 96a70db..4d2720b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,7 @@ services: build: context: . dockerfile: docker/Dockerfile - target: dev + target: base volumes: - .:/var/www/html - php-sock:/sock diff --git a/docker/Dockerfile b/docker/Dockerfile index 0873d53..778bf4e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -46,13 +46,11 @@ COPY --chown=chadmin:chadmin . /var/www/html COPY --from=vendor --chown=chadmin:chadmin /app/vendor/ /var/www/html/vendor/ COPY --from=frontend --chown=chadmin:chadmin /app/public/build /var/www/html/public/build -# Target for php fpm mode -FROM base AS dev - COPY docker/configs/php-fpm.conf /usr/local/etc/php-fpm.d/www.conf USER chadmin CMD ["php-fpm", "-F"] + # Target for all in one image mode FROM base AS aio From e7ebd5b50148e763cb7511e04d539f467781fa19 Mon Sep 17 00:00:00 2001 From: everythings-gonna-be-alright Date: Tue, 19 May 2026 04:00:47 +0300 Subject: [PATCH 3/5] Pin composer version and change user --- docker-compose.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4d2720b..6825b44 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,6 +22,7 @@ services: context: . dockerfile: docker/Dockerfile target: base + user: "1984:1984" volumes: - .:/var/www/html - php-sock:/sock @@ -31,7 +32,8 @@ services: - docker-net composer: - image: composer:latest + image: composer:2.9.8 + user: "1984:1984" volumes: - .:/app working_dir: /app @@ -41,6 +43,7 @@ services: frontend: image: node:24.15.0-alpine3.23 + user: "1984:1984" volumes: - .:/app working_dir: /app From efcc5eb5163ad1daae4e5ec5f3141b05f2111e44 Mon Sep 17 00:00:00 2001 From: everythings-gonna-be-alright Date: Tue, 19 May 2026 04:06:23 +0300 Subject: [PATCH 4/5] Fix AIO dockerfile sequence --- docker/Dockerfile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index 778bf4e..65caf8b 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -32,6 +32,7 @@ COPY public/ ./public/ RUN npm run build +# Target for base php-fpm mode FROM php:8.5.5-fpm-alpine3.23 AS base RUN (docker-php-ext-enable opcache || true) @@ -43,17 +44,21 @@ RUN addgroup -S chadmin && adduser --uid 1984 -S chadmin -G chadmin && \ # Application source + built artifacts COPY --chown=chadmin:chadmin . /var/www/html -COPY --from=vendor --chown=chadmin:chadmin /app/vendor/ /var/www/html/vendor/ COPY --from=frontend --chown=chadmin:chadmin /app/public/build /var/www/html/public/build +COPY --from=vendor --chown=chadmin:chadmin /app/vendor/ /var/www/html/vendor/ COPY docker/configs/php-fpm.conf /usr/local/etc/php-fpm.d/www.conf + USER chadmin + CMD ["php-fpm", "-F"] # Target for all in one image mode FROM base AS aio +USER root + RUN apk add --no-cache \ nginx \ supervisor \ @@ -73,5 +78,6 @@ USER chadmin EXPOSE 80 +# Let's have some fun ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] -CMD ["supervisord", "-c", "/etc/supervisord.conf"] +CMD ["supervisord", "-c", "/etc/supervisord.conf"] \ No newline at end of file From 0e817aeb491bad869dd91c8edb2a1d84076187fa Mon Sep 17 00:00:00 2001 From: everythings-gonna-be-alright Date: Tue, 19 May 2026 04:10:31 +0300 Subject: [PATCH 5/5] Fix workflow --- .github/workflows/docker-publish.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 5ee8a2a..41a6bf5 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -67,7 +67,8 @@ jobs: uses: docker/build-push-action@v6 with: context: . - file: ./Dockerfile + file: docker/Dockerfile + target: aio platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }}