Bud inside container

Hello,

I would like to know if some use bud (with sage) in a docker container.

It doesn’t matter which solution: lando, ddev, docksal, etc.

The goal would be to know what works and how.

The main question is: how to run bud in a docker container?

I think this could help a lot of people including me.
And why not write a little guide behind.

Thanks :slight_smile:

VSCode has dev containers for example.

I don’t build in containers, for reproducible builds I use nvm to lock the node version, but I had indeed issues with installing the dependencies again for very old projects (mostly library/compile/ABI stuff). A container may have helped here.

:thinking: There is a .docker directory in bud repository, including a docker-compose.yml.

We use a Sage 10 / Bud / Bedrock / PHP 8.1 / Nginx / Percona XtraDB / Longhorn stack on Kubernetes for development and production parity. Docker / Kaniko builds our containers.

I’ve had a writeup on my todo list for ages, I’ll get round to it soon.

Here are some things I’ve learned relating to Docker and the Roots ecosystem specifically:

  • Bitpoke build WordPress runtime images (including Bedrock ones), which give us a great starting point.
  • Bring up MySQL with Docker Compose (or just run an instance locally). In K8s production, Percona XDB Cluster seems to be the best choice (we evaluated Galera, ProxySQL + Orchestrator + HyperDB and MySQL Replication + HyperDB)
  • Launching VSCode inside the container makes for a great developer experience
  • Although it’s not considered best practice, we found bundling Nginx into the same container as PHP via supervisord made sense, as we like to consider PHP + Nginx as a single stack layer, and interlock both versions together

Here’s a dockerfile I’m currently using for WordPress 6.1, PHP 8.1, Bedrock. It also has all dependencies for Bud / Sage installed too. This probably could be done much more elegantly, but it works for our specific use-case. You’ll need to provide a valid supervisord config in ./etc/supervisor/application.conf that brings up PHP-FPM on tcp/9000 and Nginx.

Note that this isn’t an out-of-the-box solution, it’s just something to get you started. I’ll write up our Docker / K8s workflow and put a starter repo together when I can.

ARG PHP_VERSION=8.1
FROM docker.io/bitpoke/wordpress-runtime:bedrock-build-php-${PHP_VERSION} as builder
ARG PHP_VERSION
FROM node:16 as nodebuilder
ARG PHP_VERSION
FROM docker.io/bitpoke/wordpress-runtime:bedrock-php-${PHP_VERSION} as base
ARG PHP_VERSION
ARG WP_ENV=development
ARG ENABLE_SHELL
USER root
COPY --from=nodebuilder /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=nodebuilder /usr/local/bin/node /usr/local/bin/node
RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm
RUN npm i -g yarn npx
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && sync && install-php-extensions gd mysqli pdo_mysql zip imagick sockets memcached
RUN apt-get update && apt-get install git unzip supervisor sudo wget default-mysql-client -y
RUN if [[ -z "$ENABLE_SHELL" ]] ; then echo No Shell ; else chsh -s /bin/bash www-data ; fi
USER www-data
COPY --from=builder --chown=www-data:www-data /app /app
COPY ./etc/supervisor /etc/supervisor/
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/application.conf"]

When arriving at the above solution, we wanted something that met all the following criteria:

  1. Total dev vs prod parity (including, optionally, the database layer)
  2. Easily install PHP extensions
  3. Fully containerised dev environment - VSCode should run inside the dev container itself, on cluster.
  4. NodeJS, Mysql-Client, GIT, Wget, unzip, GNU Screen for dev tooling
  5. Shell access for www-data only in development environment. No shell in prod.
  6. Runs as Docker container, runs on K8s.

Those requirements may or may not be appropriate for your project, so you may be able to use a simpler Dockerfile.

1 Like

@talss89 interesting setup, thanks for sharing. :+1:

@aksld your main goal is local development on docker?

@talss89 Thanks for sharing, you use something complete, maybe too much for me :stuck_out_tongue:

@RistoKaalma Exactly, I want to use docker to reproduce my production environments and when everything works well, it is quite simple!

I start to write a small doc to use ddev with sage

I’d personally suggest Lando with it’s WordPress recipe that is quite straight forward and relatively easy to set up on Ubuntu or Mac. Not sure about Windows. Quick Lando WP recipe conf overview:

Features of this plugin:

  • Configurable php version from 5.3 all the way to 8.1
  • Configurable webroot
  • Configurable web server (apache or nginx)
  • Configurable database backend (mariadb, mysql, or postgres)
  • Configurable composer
  • wp cli
  • xdebug

All main services and their versions easily configurable.

My typical directory setup:

# directory structure of project_root

.
├── .lando/ # directory for Lando configuration files
│   ├── php.ini
│   └── ...
├── .vscode/ # directory for VS Code specific configuration
│   └── launch.json # for xdebug configuration
├── site/ # directory for roots/bedrock
│   ├── .env
│   └── ...
├── trellis/ # directory for roots/trellis
│   └── ...
├── .lando.yml
└── .gitignore

Lando configuration file:

# project_root/.lando.yml

name: example
recipe: wordpress
env_file:
  -  site/.env
config:
  php: "8.0"
  composer_version: "2-latest"
  via: nginx
  webroot: site/web
  database: mariadb
  xdebug: true
  config:
    php: .lando/php.ini
proxy:
  phpmyadmin:
    - pma.example.lndo.site
  mailhog:
    - mail.example.lndo.site
services:
  phpmyadmin:
    type: phpmyadmin
    hosts:
      - database
  mailhog:
    type: mailhog
    hogfrom:
      - appserver
  dev:
    type: node:16
    overrides:
      ports:
        - 3000:3000 # for bud dev
tooling:
  yarn:
    service: dev

Env setup:

# project_root/site/.env

DB_NAME='wordpress' # default for Lando
DB_USER='wordpress' # default for Lando
DB_PASSWORD='wordpress' # default for Lando
DB_HOST='database' # default for Lando

WP_ENV='development'
WP_HOME='http://example.lndo.site'
WP_SITEURL="${WP_HOME}/wp"

VS Code launch conf for Xdebug:

# project_root/.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
      {
        "name": "Listen for XDebug (9003)",
        "type": "php",
        "request": "launch",
        "port": 9003,
        "log": false,
        "pathMappings": {
          "/app/site/": "${workspaceFolder}/site/"
        }
      }
    ],
    "sourceFileMap": {
      "/app/site/": "${workspaceFolder}/site/"
    }
  }

PHP ini conf for Lando and Xdebug:

; Xdebug
xdebug.max_nesting_level = 512
xdebug.show_exception_trace = 0
xdebug.collect_params = 0
; Extra custom Xdebug setting for debug to work in VSCode.
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
xdebug.remote_host = ${LANDO_HOST_IP}
xdebug.remote_connect_back = 1
xdebug.remote_log = /tmp/xdebug.log
; Test
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.client_host = ${LANDO_HOST_IP}
xdebug.log = /tmp/xdebug.log

With all this set up, just lando start from project root where .lando.yml is, then lando composer install from site dir, lando composer install + lando yarn + lando yarn build from sage (^v10.x) directory.

To make bud dev work you should make changes to your theme’s bud.config.js file accordingly:

/**
 * Proxy origin (`WP_HOME`)
 */
.proxy("http://example.lndo.site")

/**
 * Development origin
 */
.serve("http://example.lndo.site:3000")

Then lando yarn dev

That’s pretty much it.

1 Like