Skip to content
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

Node assets build should occur after composer install #68

Open
Velka-DEV opened this issue Apr 3, 2024 · 4 comments
Open

Node assets build should occur after composer install #68

Velka-DEV opened this issue Apr 3, 2024 · 4 comments
Labels
enhancement New feature or request

Comments

@Velka-DEV
Copy link

The docker build will fail if any javascript file import a resource from composer vendor folder (e.g Alpine / Livewire)

import { Livewire, Alpine } from '../../vendor/livewire/livewire/dist/livewire.esm';

This import is from the Livewire documentation: https://livewire.laravel.com/docs/alpine#manually-bundling-alpine-in-your-javascript-build

@smortexa
Copy link
Member

smortexa commented Apr 4, 2024

PHP dependencies (vendor directory) are not available during the build of front-end assets in these Dockerfiles. You can do this:

// composer.json
"post-update-cmd": [
     ...
      "@php -r \"copy('vendor/livewire/livewire/dist/livewire.esm', 'resources/js/lib/livewire/livewire.esm');\""
    ],

// app.js
import { Livewire, Alpine } from './lib/livewire/livewire.esm';

Then, run composer update and rebuild the image.

@Velka-DEV
Copy link
Author

We need to expose vendor directory, this is not actually reliable to copy all dependencies.

The ESM module make relative imports like "../alpine/packages/alpinejs/dist/module.cjs.js", we can't copy every single file manually

@smortexa smortexa added the enhancement New feature or request label Apr 5, 2024
@Velka-DEV
Copy link
Author

Maybe this is a good occasion to work on it along with alpine & bun support as it's on the to-do list and would be a rewrite

@sanasol
Copy link

sanasol commented Sep 12, 2024

Did this locally for RoadRunner.Alpine.Dockerfile

Only caveat that I use --ignore-platform-reqs to just install composer dependencies from lightweight composer image without building whole image with all php extensions etc.

Then use it for frontend build and backend steps.

###########################################
# Install Composer dependencies
###########################################

FROM composer:${COMPOSER_VERSION} AS vendor

WORKDIR /app

COPY composer.json composer.lock auth.json ./
RUN composer install \
    --no-dev \
    --no-interaction \
    --no-autoloader \
    --no-ansi \
    --no-scripts \
    --ignore-platform-reqs \
    --audit

frontend image build

COPY --from=vendor /app/vendor ./vendor

php image build

COPY --link --chown=${USER}:${USER} --from=vendor /usr/bin/composer /usr/bin/composer
COPY --link --chown=${USER}:${USER} --from=vendor /app/vendor ./vendor

Full RoadRunner.Alpine.Dockerfile file for example

# Accepted values: 8.3 - 8.2
ARG PHP_VERSION=8.3

ARG COMPOSER_VERSION=latest
ARG NODE_VERSION=20-alpine

###########################################
# Install Composer dependencies
###########################################

FROM composer:${COMPOSER_VERSION} AS vendor

WORKDIR /app

COPY composer.json composer.lock auth.json ./
RUN composer install \
    --no-dev \
    --no-interaction \
    --no-autoloader \
    --no-ansi \
    --no-scripts \
    --ignore-platform-reqs \
    --audit

###########################################
# Build frontend assets with NPM
###########################################

FROM node:${NODE_VERSION} AS build

ENV ROOT=/var/www/html

WORKDIR ${ROOT}

RUN yarn config set update-notifier false && yarn config set no-progress

COPY --link package.json yarn.lock* ./
COPY --from=vendor /app/vendor ./vendor

RUN if [ -f $ROOT/yarn.lock ]; \
    then \
    yarn install --frozen-lockfile --silent; \
    else \
    yarn install --silent; \
    fi

COPY --link . .

RUN yarn build

###########################################

FROM php:${PHP_VERSION}-cli-alpine

LABEL maintainer="SMortexa <[email protected]>"
LABEL org.opencontainers.image.title="Laravel Octane Dockerfile"
LABEL org.opencontainers.image.description="Production-ready Dockerfile for Laravel Octane"
LABEL org.opencontainers.image.source=https://github.com/exaco/laravel-octane-dockerfile
LABEL org.opencontainers.image.licenses=MIT

ARG WWWUSER=1000
ARG WWWGROUP=1000
ARG TZ=UTC

ENV TERM=xterm-color \
    WITH_HORIZON=false \
    WITH_SCHEDULER=false \
    OCTANE_SERVER=roadrunner \
    USER=octane \
    ROOT=/var/www/html \
    COMPOSER_FUND=0 \
    COMPOSER_MAX_PARALLEL_HTTP=24

WORKDIR ${ROOT}

SHELL ["/bin/sh", "-eou", "pipefail", "-c"]

RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime \
  && echo ${TZ} > /etc/timezone

ADD --chmod=0755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

RUN apk update; \
    apk upgrade; \
    apk add --no-cache \
    curl \
    wget \
    nano \
    git \
    ncdu \
    procps \
    ca-certificates \
    supervisor \
    libsodium-dev
    # Install PHP extensions
RUN install-php-extensions \
    bz2 \
    pcntl \
    mbstring
RUN install-php-extensions \
    bcmath \
    sockets \
    opcache \
    exif
RUN install-php-extensions \   
    pdo_mysql \
    zip \
    intl \
    gd
RUN install-php-extensions \   
    redis \
    memcached \
    igbinary \
    && docker-php-source delete \
    && rm -rf /var/cache/apk/* /tmp/* /var/tmp/*

RUN arch="$(apk --print-arch)" \
    && case "$arch" in \
    armhf) _cronic_fname='supercronic-linux-arm' ;; \
    aarch64) _cronic_fname='supercronic-linux-arm64' ;; \
    x86_64) _cronic_fname='supercronic-linux-amd64' ;; \
    x86) _cronic_fname='supercronic-linux-386' ;; \
    *) echo >&2 "error: unsupported architecture: $arch"; exit 1 ;; \
    esac \
    && wget -q "https://github.com/aptible/supercronic/releases/download/v0.2.29/${_cronic_fname}" \
    -O /usr/bin/supercronic \
    && chmod +x /usr/bin/supercronic \
    && mkdir -p /etc/supercronic \
    && echo "*/1 * * * * php ${ROOT}/artisan schedule:run --no-interaction" > /etc/supercronic/laravel

RUN addgroup -g ${WWWGROUP} ${USER} \
    && adduser -D -h ${ROOT} -G ${USER} -u ${WWWUSER} -s /bin/sh ${USER}

RUN mkdir -p /var/log/supervisor /var/run/supervisor \
    && chown -R ${USER}:${USER} ${ROOT} /var/log /var/run \
    && chmod -R a+rw ${ROOT} /var/log /var/run

RUN cp ${PHP_INI_DIR}/php.ini-production ${PHP_INI_DIR}/php.ini

USER ${USER}

COPY --link --chown=${USER}:${USER} --from=vendor /usr/bin/composer /usr/bin/composer
COPY --link --chown=${USER}:${USER} --from=vendor /app/vendor ./vendor
COPY --link --chown=${USER}:${USER} . .
COPY --link --chown=${USER}:${USER} --from=build ${ROOT}/public public

RUN mkdir -p \
    storage/framework/sessions \
    storage/framework/views \
    storage/framework/cache \
    storage/framework/testing \
    storage/logs \
    bootstrap/cache && chmod -R a+rw storage

COPY --link --chown=${USER}:${USER} deployment/supervisord.conf /etc/supervisor/
COPY --link --chown=${USER}:${USER} deployment/octane/RoadRunner/supervisord.roadrunner.conf /etc/supervisor/conf.d/
COPY --link --chown=${USER}:${USER} deployment/supervisord.*.conf /etc/supervisor/conf.d/
COPY --link --chown=${USER}:${USER} deployment/php.ini ${PHP_INI_DIR}/conf.d/99-octane.ini
COPY --link --chown=${USER}:${USER} deployment/octane/RoadRunner/.rr.prod.yaml ./.rr.yaml
COPY --link --chown=${USER}:${USER} deployment/start-container /usr/local/bin/start-container
COPY --link --chown=${USER}:${USER} deployment/healthcheck /usr/local/bin/healthcheck

RUN composer dump-autoload \
    --classmap-authoritative \
    --no-interaction \
    --no-ansi \
    --no-dev

RUN if composer show | grep spiral/roadrunner-cli >/dev/null; then \
    ./vendor/bin/rr get-binary --quiet; else \
    echo "`spiral/roadrunner-cli` package is not installed. Exiting..."; exit 1; \
    fi

RUN chmod +x rr /usr/local/bin/start-container /usr/local/bin/healthcheck

RUN cat deployment/utilities.sh >> ~/.bashrc

EXPOSE 8000
EXPOSE 6001

ENTRYPOINT ["start-container"]

HEALTHCHECK --start-period=5s --interval=2s --timeout=5s --retries=8 CMD healthcheck || exit 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants