Skip to content

Commit 4fab1fc

Browse files
committed
feat: initial commit
0 parents  commit 4fab1fc

File tree

16 files changed

+628
-0
lines changed

16 files changed

+628
-0
lines changed

.editorconfig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true
10+
11+
# YAML files
12+
[*.yml]
13+
indent_size = 2
14+
15+
[*.yaml]
16+
indent_size = 2
17+
18+
# Dockerfile
19+
[Dockerfile]
20+
indent_style = space
21+
indent_size = 2
22+
trim_trailing_whitespace = true

.github/workflows/release.yaml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Build and Release Stochastix
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*.*.*'
7+
workflow_dispatch:
8+
9+
env:
10+
REGISTRY: ghcr.io
11+
APP_IMAGE_NAME: phpquant/stochastix
12+
INSTALLER_IMAGE_NAME: phpquant/stochastix-installer
13+
14+
jobs:
15+
build_and_push_app:
16+
name: Build & Push App Image
17+
runs-on: ubuntu-latest
18+
permissions:
19+
contents: read
20+
packages: write
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Log in to GitHub Container Registry
26+
uses: docker/login-action@v3
27+
with:
28+
registry: ${{ env.REGISTRY }}
29+
username: ${{ github.actor }}
30+
password: ${{ secrets.GITHUB_TOKEN }}
31+
32+
- name: Build and push App image
33+
uses: docker/build-push-action@v5
34+
with:
35+
context: .
36+
file: ./build/app.Dockerfile
37+
target: frankenphp_dev
38+
push: true
39+
tags: ${{ env.REGISTRY }}/${{ env.APP_IMAGE_NAME }}:${{ github.ref_name }},${{ env.REGISTRY }}/${{ env.APP_IMAGE_NAME }}:latest
40+
build-args: |
41+
UI_REPO=phpquant/stochastix-ui
42+
UI_VERSION=latest
43+
44+
build_and_push_installer:
45+
name: Build & Push Installer Image
46+
runs-on: ubuntu-latest
47+
needs: build_and_push_app
48+
permissions:
49+
contents: read
50+
packages: write
51+
steps:
52+
- name: Checkout repository
53+
uses: actions/checkout@v4
54+
55+
- name: Log in to GitHub Container Registry
56+
uses: docker/login-action@v3
57+
with:
58+
registry: ${{ env.REGISTRY }}
59+
username: ${{ github.actor }}
60+
password: ${{ secrets.GITHUB_TOKEN }}
61+
62+
- name: Build and push Installer image
63+
uses: docker/build-push-action@v5
64+
with:
65+
context: .
66+
file: ./build/installer/Dockerfile
67+
push: true
68+
tags: ${{ env.REGISTRY }}/${{ env.INSTALLER_IMAGE_NAME }}:latest

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Stochastix Installer
2+
3+
This repository builds the official Stochastix application images and installer.
4+
5+
## Quick Start
6+
7+
To create a new Stochastix project, run the following command, replacing `your-project-name` with the desired name for your project folder:
8+
9+
```bash
10+
docker run --rm -it --pull=always -v "$PWD":/app -v /var/run/docker.sock:/var/run/docker.sock \
11+
ghcr.io/phpquant/stochastix-installer your-project-name
12+
```
13+
14+
This command will create the `your-project-name` directory, scaffold all the necessary files, and start the application. Once it's finished, your Stochastix instance will be running and accessible.

build/app.Dockerfile

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# This Dockerfile builds the main stochastix image.
2+
# It contains the PHP environment and the pre-built UI, but NO Symfony source code.
3+
4+
# Stage 1: Fetch the latest UI release assets
5+
FROM alpine:latest AS ui-fetcher
6+
7+
ARG UI_REPO="phpquant/stochastix-ui"
8+
ARG UI_VERSION="latest"
9+
10+
WORKDIR /downloads
11+
12+
RUN apk add --no-cache curl jq
13+
14+
# Use the GitHub API to get the download URL for the .tar.gz asset
15+
RUN ASSET_URL=$(curl -sL https://api.github.com/repos/${UI_REPO}/releases/${UI_VERSION} | jq -r '.assets[] | select(.name | endswith(".tar.gz")) | .browser_download_url') && \
16+
if [ -z "$ASSET_URL" ] || [ "$ASSET_URL" = "null" ]; then echo "Error: Could not find UI release asset." >&2; exit 1; fi && \
17+
curl -L -o stochastix-ui.tar.gz "${ASSET_URL}" && \
18+
mkdir -p /ui_assets && \
19+
tar -xzf stochastix-ui.tar.gz -C /ui_assets
20+
21+
# Stage 2: Prepare the final application environment image
22+
# Versions
23+
FROM dunglas/frankenphp:1-php8.4 AS frankenphp_upstream
24+
25+
# The different stages of this Dockerfile are meant to be built into separate images
26+
# https://docs.docker.com/develop/develop-images/multistage-build/#stop-at-a-specific-build-stage
27+
# https://docs.docker.com/compose/compose-file/#target
28+
29+
30+
# Base FrankenPHP image
31+
FROM frankenphp_upstream AS frankenphp_base
32+
33+
WORKDIR /app
34+
35+
VOLUME /app/var/
36+
37+
# persistent / runtime deps
38+
# hadolint ignore=DL3008
39+
RUN apt-get update && apt-get install -y --no-install-recommends \
40+
libgmp-dev \
41+
acl \
42+
file \
43+
gettext \
44+
git \
45+
&& rm -rf /var/lib/apt/lists/*
46+
47+
RUN set -eux; \
48+
install-php-extensions \
49+
@composer \
50+
apcu \
51+
intl \
52+
opcache \
53+
zip \
54+
bcmath \
55+
gmp \
56+
pdo \
57+
pdo_sqlite \
58+
; \
59+
pecl install \
60+
trader \
61+
ds \
62+
; \
63+
docker-php-ext-enable \
64+
bcmath \
65+
gmp \
66+
trader \
67+
ds \
68+
;
69+
70+
RUN git config --global --add safe.directory /app && git config --global --add safe.directory /repos/core
71+
72+
# https://getcomposer.org/doc/03-cli.md#composer-allow-superuser
73+
ENV COMPOSER_ALLOW_SUPERUSER=1
74+
75+
# Transport to use by Mercure (default to Bolt)
76+
ENV MERCURE_TRANSPORT_URL=bolt:///data/mercure.db
77+
78+
ENV PHP_INI_SCAN_DIR=":$PHP_INI_DIR/app.conf.d"
79+
80+
COPY --link templates/frankenphp/conf.d/10-app.ini $PHP_INI_DIR/app.conf.d/
81+
COPY --link --chmod=755 templates/frankenphp/docker-entrypoint.sh /usr/local/bin/docker-entrypoint
82+
COPY --link templates/frankenphp/Caddyfile /etc/caddy/Caddyfile
83+
84+
COPY --from=ui-fetcher /ui_assets/ /srv/ui/
85+
RUN chown -R www-data:www-data /srv/ui
86+
87+
ENTRYPOINT ["docker-entrypoint"]
88+
89+
HEALTHCHECK --start-period=60s CMD curl -f http://localhost:2019/metrics || exit 1
90+
CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile" ]
91+
92+
# Dev FrankenPHP image
93+
FROM frankenphp_base AS frankenphp_dev
94+
95+
ENV APP_ENV=dev
96+
ENV XDEBUG_MODE=off
97+
ENV FRANKENPHP_WORKER_CONFIG=watch
98+
99+
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
100+
101+
RUN set -eux; \
102+
install-php-extensions \
103+
xdebug \
104+
;
105+
106+
COPY --link templates/frankenphp/conf.d/20-app.dev.ini $PHP_INI_DIR/app.conf.d/
107+
108+
CMD [ "frankenphp", "run", "--config", "/etc/caddy/Caddyfile", "--watch" ]
109+
110+
# Prod FrankenPHP image
111+
FROM frankenphp_base AS frankenphp_prod
112+
113+
ENV APP_ENV=prod
114+
115+
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"
116+
117+
COPY --link templates/frankenphp/conf.d/20-app.prod.ini $PHP_INI_DIR/app.conf.d/
118+
119+
# prevent the reinstallation of vendors at every changes in the source code
120+
COPY --link composer.* symfony.* ./
121+
RUN set -eux; \
122+
composer install --no-cache --prefer-dist --no-dev --no-autoloader --no-scripts --no-progress
123+
124+
# copy sources
125+
COPY --link . ./
126+
RUN rm -Rf frankenphp/
127+
128+
RUN set -eux; \
129+
mkdir -p var/cache var/log; \
130+
composer dump-autoload --classmap-authoritative --no-dev; \
131+
composer dump-env prod; \
132+
composer run-script --no-dev post-install-cmd; \
133+
chmod +x bin/console; sync;

build/app.Dockerfile.dockerignore

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
**/*.log
2+
**/*.md
3+
**/*.php~
4+
**/*.dist.php
5+
**/*.dist
6+
**/*.cache
7+
**/._*
8+
**/.dockerignore
9+
**/.DS_Store
10+
**/.git/
11+
**/.gitattributes
12+
**/.gitignore
13+
**/.gitmodules
14+
**/compose.*.yaml
15+
**/compose.*.yml
16+
**/compose.yaml
17+
**/compose.yml
18+
**/docker-compose.*.yaml
19+
**/docker-compose.*.yml
20+
**/docker-compose.yaml
21+
**/docker-compose.yml
22+
**/Dockerfile
23+
**/Thumbs.db
24+
.github/
25+
docs/
26+
public/bundles/
27+
tests/
28+
var/
29+
vendor/
30+
.editorconfig
31+
.env.*.local
32+
.env.local
33+
.env.local.php
34+
.env.test

build/installer/Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# This Dockerfile builds the lightweight installer image.
2+
FROM alpine:latest
3+
4+
# Install tools needed by the installer script (Docker client and curl)
5+
RUN apk add --no-cache docker-cli docker-compose curl
6+
7+
# Copy the project templates into the image
8+
COPY templates/ /templates/
9+
10+
# Copy the installer script into the image and make it executable
11+
COPY build/installer/install.sh /usr/local/bin/install.sh
12+
RUN chmod +x /usr/local/bin/install.sh
13+
14+
ENTRYPOINT ["/usr/local/bin/install.sh"]

build/installer/install.sh

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/sh
2+
set -e
3+
4+
# This script runs inside the installer container.
5+
# The user's current directory on their host machine is mounted at /app.
6+
7+
PROJECT_NAME=$1
8+
9+
if [ -z "$PROJECT_NAME" ]; then
10+
echo "Error: Please provide a project name."
11+
echo "Usage: install.sh <project-name>"
12+
exit 1
13+
fi
14+
15+
# The full path inside the container where the new project will be created
16+
PROJECT_PATH="/app/${PROJECT_NAME}"
17+
18+
if [ -d "$PROJECT_PATH" ]; then
19+
# Check if the directory is not empty. Allows creation in an existing empty directory.
20+
if [ -n "$(ls -A "$PROJECT_PATH")" ]; then
21+
echo "Error: Directory '${PROJECT_NAME}' already exists and is not empty."
22+
exit 1
23+
fi
24+
fi
25+
26+
echo "Creating new Stochastix project in './${PROJECT_NAME}'..."
27+
mkdir -p "$PROJECT_PATH"
28+
mkdir -p "$PROJECT_PATH/frankenphp"
29+
30+
# Copy the template files from the image into the new project directory
31+
echo "Scaffolding project files..."
32+
cp /templates/compose.yaml "${PROJECT_PATH}/compose.yaml"
33+
cp /templates/compose.override.yaml "${PROJECT_PATH}/compose.override.yaml"
34+
cp /templates/.editorconfig "${PROJECT_PATH}/.editorconfig"
35+
cp /templates/.gitattributes "${PROJECT_PATH}/.gitattributes"
36+
cp /templates/frankenphp/Caddyfile "${PROJECT_PATH}/frankenphp/Caddyfile"
37+
cp /templates/frankenphp/conf.d/20-app.dev.ini "${PROJECT_PATH}/frankenphp/conf.d/20-app.dev.ini"
38+
39+
echo "✅ Project files created."
40+
echo "🚀 Launching Stochastix application... (This may take a minute on the first run)"
41+
42+
# Use the mounted Docker socket to run docker-compose on the host machine,
43+
# specifying the project directory for context.
44+
docker compose -p "${PROJECT_NAME}" -f "${PROJECT_PATH}/compose.yaml" up --wait
45+
46+
echo
47+
echo "✅ Stochastix is running!"
48+
echo "You can now access the UI at https://localhost (or the host you configured)."
49+
echo

templates/.editorconfig

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# EditorConfig helps developers define and maintain consistent
2+
# coding styles between different editors and IDEs
3+
# editorconfig.org
4+
5+
root = true
6+
7+
[*]
8+
# Change these settings to your own preference
9+
indent_style = space
10+
indent_size = 4
11+
12+
# We recommend you to keep these unchanged
13+
end_of_line = lf
14+
charset = utf-8
15+
trim_trailing_whitespace = true
16+
insert_final_newline = true
17+
18+
[*.{js,html,ts,tsx}]
19+
indent_size = 2
20+
21+
[*.json]
22+
indent_size = 2
23+
24+
[*.md]
25+
trim_trailing_whitespace = false
26+
27+
[*.sh]
28+
indent_style = tab
29+
30+
[*.xml.dist]
31+
indent_style = space
32+
indent_size = 4
33+
34+
[*.{yaml,yml}]
35+
trim_trailing_whitespace = false
36+
37+
[.github/workflows/*.yml]
38+
indent_size = 2
39+
40+
[.gitmodules]
41+
indent_style = tab
42+
43+
[.php_cs.dist]
44+
indent_style = space
45+
indent_size = 4
46+
47+
[composer.json]
48+
indent_size = 4
49+
50+
[{compose,docker-compose}*.{yaml,yml}]
51+
indent_size = 2
52+
53+
[*.*Dockerfile]
54+
indent_style = tab
55+
56+
[*.*Caddyfile]
57+
indent_style = tab

0 commit comments

Comments
 (0)