diff --git a/.github/workflows/laravel.yml b/.github/workflows/laravel.yml index 77c73de..0d1cff9 100644 --- a/.github/workflows/laravel.yml +++ b/.github/workflows/laravel.yml @@ -1,8 +1,12 @@ -on: push +on: [push, pull_request] name: Build jobs: - deploy: - name: Build Laravel Images + build: + strategy: + fail-fast: false + matrix: + runtime: [ "hello-world:latest", "laravel:8.0-octane", "laravel:8.1-octane" ] + name: "bpkg.io/${{ matrix.runtime }}" runs-on: ubuntu-latest steps: - uses: actions/checkout@master @@ -16,17 +20,27 @@ jobs: registry: bpkg.io username: k3s password: ${{ secrets.DOCKER_PASSWORD }} - - name: Build and push bpkg.io/laravel:8.0-octane + - name: Build and push bpkg.io/${{ matrix.runtime }} + if: github.ref == 'refs/heads/main' uses: docker/build-push-action@v2 with: context: . - file: ./runtimes/laravel:8.0-octane/Dockerfile + file: ./runtimes/${{ matrix.runtime }}/Dockerfile platforms: | linux/amd64 - linux/arm/v7 + linux/arm64/v8 push: true - build-args: | - CICD_GIT_COMMIT=${{ steps.slug.outputs.sha8 }} tags: | - bpkg.io/laravel:latest - bpkg.io/laravel:8.0-octane + bpkg.io/${{ matrix.runtime }} + - name: Build and push bpkg.io/${{ matrix.runtime }}-develop + if: github.ref == 'refs/heads/develop' + uses: docker/build-push-action@v2 + with: + context: . + file: ./runtimes/${{ matrix.runtime }}/Dockerfile + platforms: | + linux/amd64 + linux/arm64/v8 + push: true + tags: | + bpkg.io/${{ matrix.runtime }}-develop diff --git a/README.md b/README.md index 364cd5c..9628604 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,33 @@ -# bpkg-laravel -bpkg.io/laravel +# bpkg.io Images + +The bkg.io images are a collection of images that are used as a base for building other images. Mostly they are used as +base images for our web projects. + +## Supported Images + +| Image | Version | Description | Architecture | Supported | +| ------ | ------- | ----------- | ------------ | ---------- | +| bpkg.io/laravel | 8.0-octane | PHP image containing all extensions for a laravel octane app. | amd64, arm64 | yes | +| bpkg.io/laravel | 8.0-octane-develop | Development build. | amd64, arm64 | no | +| bpkg.io/laravel | 8.1-octane | PHP image containing all extensions for a laravel octane app. | amd64, arm64 | yes | +| bpkg.io/laravel | 8.1-octane-develop | Development build. | amd64, arm64 | no | +| bpkg.io/hello-world | latest | Development build. | amd64, arm64 | no | +| bpkg.io/hello-world | latest-develop | Development build. | amd64, arm64 | no | + +## Concepts + +### Default Working Directory + +For web projects the default working directory is `/var/www/html`. This applies to all `bpkg.io/laravel` images. + +## Usage + +The following dockerfile show the usage of the bpkg.io/laravel image. Per default, it uses the +command `php artisan octane:start --host 0.0.0.0` to start the application and expose the application on port 8000. + +```dockerfile +FROM bpkg.io/laravel:8.0-octane + +# copy all your project files to the /var/www/html folder +COPY . /var/www/html +``` \ No newline at end of file diff --git a/runtimes/hello-world:latest/Dockerfile b/runtimes/hello-world:latest/Dockerfile new file mode 100644 index 0000000..16e0440 --- /dev/null +++ b/runtimes/hello-world:latest/Dockerfile @@ -0,0 +1,21 @@ +FROM node:14-alpine AS build + +WORKDIR /app +COPY runtimes/hello-world:latest/. /app + +RUN set -ex \ + # Build JS-Application + && npm install --production \ + # Delete unnecessary files + && rm package* \ + # Correct User's file access + && chown -R node:node /app + +FROM node:14-alpine AS final +WORKDIR /app +COPY --from=build /app /app +ENV HTTP_PORT=8000 +EXPOSE $HTTP_PORT $HTTPS_PORT +USER 1000 +EXPOSE 8000 +CMD ["node", "./index.js"] \ No newline at end of file diff --git a/runtimes/hello-world:latest/index.js b/runtimes/hello-world:latest/index.js new file mode 100644 index 0000000..59443dc --- /dev/null +++ b/runtimes/hello-world:latest/index.js @@ -0,0 +1,111 @@ +const express = require('express') +const morgan = require('morgan'); +const http = require('http') +const app = express() +const os = require('os'); +const jwt = require('jsonwebtoken'); +const concat = require('concat-stream'); +const { promisify } = require('util'); +const sleep = promisify(setTimeout); + +app.set('json spaces', 2); +app.set('trust proxy', ['loopback', 'linklocal', 'uniquelocal']); + +app.use(morgan('combined')); + +app.use(function(req, res, next){ + req.pipe(concat(function(data){ + req.body = data.toString('utf8'); + next(); + })); +}); + +app.all('*', (req, res) => { + const echo = { + path: req.path, + headers: req.headers, + method: req.method, + body: req.body, + cookies: req.cookies, + fresh: req.fresh, + hostname: req.hostname, + ip: req.ip, + ips: req.ips, + protocol: req.protocol, + query: req.query, + subdomains: req.subdomains, + xhr: req.xhr, + os: { + hostname: os.hostname() + }, + connection: { + servername: req.connection.servername + } + }; + + if(req.is('application/json')){ + echo.json = JSON.parse(req.body) + } + + if (process.env.JWT_HEADER) { + let token = req.headers[process.env.JWT_HEADER.toLowerCase()]; + if (!token) { + echo.jwt = token; + } else { + token = token.split(" ").pop(); + const decoded = jwt.decode(token, {complete: true}); + echo.jwt = decoded; + } + } + const setResponseStatusCode = parseInt(req.headers["x-set-response-status-code"] || req.query["x-set-response-status-code"], 10) + if (100 <= setResponseStatusCode && setResponseStatusCode < 600) { + res.status(setResponseStatusCode) + } + + const sleepTime = parseInt(req.headers["x-set-response-delay-ms"] || req.query["x-set-response-delay-ms"], 0) + sleep(sleepTime).then(() => { + + if (process.env.ECHO_BACK_TO_CLIENT != undefined && process.env.ECHO_BACK_TO_CLIENT == "false"){ + res.end(); + } else { + res.json(echo); + } + + if (process.env.LOG_IGNORE_PATH != req.path) { + console.log('-----------------') + + let spacer = 4; + if(process.env.LOG_WITHOUT_NEWLINE){ + spacer = null; + } + + console.log(JSON.stringify(echo, null, spacer)); + } + }); + + +}); + +let httpServer = http.createServer(app).listen(process.env.HTTP_PORT || 8000); +console.log(`Listening on port ${process.env.HTTP_PORT || 8000}`); + +let calledClose = false; + +process.on('exit', function () { + if (calledClose) return; + console.log('Got exit event. Trying to stop Express server.'); + server.close(function() { + console.log("Express server closed"); + }); +}); + +process.on('SIGINT', shutDown); +process.on('SIGTERM', shutDown); + +function shutDown(){ + console.log('Got a kill signal. Trying to exit gracefully.'); + calledClose = true; + httpServer.close(function() { + console.log("HTTP servers closed. Asking process to exit."); + }); +} \ No newline at end of file diff --git a/runtimes/hello-world:latest/package.json b/runtimes/hello-world:latest/package.json new file mode 100644 index 0000000..387e200 --- /dev/null +++ b/runtimes/hello-world:latest/package.json @@ -0,0 +1,21 @@ +{ + "name": "@bitinflow/hello-world", + "version": "1.0.0", + "description": "JSON service for debugging a web setup", + "main": "index.js", + "scripts": { + "start": "node index.js", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "bitinflow Containers Team ", + "license": "MIT", + "engines": { + "node": ">=6.3.0" + }, + "dependencies": { + "concat-stream": "^2.0.0", + "express": "^4.17.1", + "jsonwebtoken": "^8.5.0", + "morgan": "^1.10.0" + } +} \ No newline at end of file diff --git a/runtimes/laravel:8.1-octane/Dockerfile b/runtimes/laravel:8.1-octane/Dockerfile new file mode 100644 index 0000000..0ee9030 --- /dev/null +++ b/runtimes/laravel:8.1-octane/Dockerfile @@ -0,0 +1,20 @@ +FROM php:8.1-cli-alpine3.15 + +WORKDIR /var/www/html + +# STSTEM: Install required packages +RUN apk --no-cache upgrade && \ + apk --no-cache add bash git sudo openssh libxml2-dev postgresql-dev oniguruma-dev autoconf gcc g++ make npm freetype-dev libjpeg-turbo-dev libpng-dev libzip-dev + +# COMPOSER: install binary and prestissimo +RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer + +# PHP: install extensions +RUN pecl channel-update pecl.php.net +RUN pecl install ssh2 swoole +RUN docker-php-ext-configure gd --with-freetype --with-jpeg +RUN docker-php-ext-install mbstring xml pcntl gd zip sockets pdo pdo_pgsql pdo_mysql bcmath +RUN docker-php-ext-enable mbstring xml gd zip swoole pcntl sockets bcmath pdo pdo_pgsql pdo_mysql + +EXPOSE 8000 +CMD ["php","artisan","octane:start", "--host=0.0.0.0"]