diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..793573a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +.DS_Store +.env +*.env +!.env.example + +.git +.github +.stencil +.vagrant + +bin +node_modules +server +www diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index b0d2f0c..b5a7c70 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,26 +1,62 @@ -name: Build & Deploy +name: Publish & Deploy + on: push: branches: [master] + workflow_dispatch: + +permissions: + contents: read + packages: write jobs: + image: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Read package version + id: package + shell: bash + run: | + echo "version=$(node -p "require('./package.json').version")" >> "$GITHUB_OUTPUT" + + - name: Publish image + uses: broadsheet-technology/publisher@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + image: ghcr.io/${{ github.repository }} + tags: | + ${{ github.sha }} + ${{ steps.package.outputs.version }} + latest + deploy: + needs: image + if: github.event_name == 'push' runs-on: ubuntu-latest environment: production steps: - name: Deploy uses: appleboy/ssh-action@v0.1.2 + env: + WORDPRESS_IMAGE: ghcr.io/${{ github.repository }}:${{ github.sha }} + GHCR_USERNAME: ${{ github.actor }} + GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: host: ${{secrets.SSH_HOST}} # IP address of the server you wish to ssh into key: ${{secrets.SSH_KEY}} # Private or public key of the server username: ${{ secrets.SSH_USER}} # User of the server you want to ssh into + envs: WORDPRESS_IMAGE,GHCR_USERNAME,GHCR_TOKEN script: | + set -eu cd ~/wjh.dev - git reset --hard HEAD - git pull - git checkout master - npm install - npm run build - docker-compose up -d + git fetch origin main + git checkout -B main origin/main + git reset --hard origin/main + echo "$GHCR_TOKEN" | docker login ghcr.io -u "$GHCR_USERNAME" --password-stdin + docker-compose pull wordpress + docker-compose up -d --build echo 'Deployment successful to Digital Ocean' diff --git a/.github/workflows/stage-image.yml b/.github/workflows/stage-image.yml new file mode 100644 index 0000000..3c2d273 --- /dev/null +++ b/.github/workflows/stage-image.yml @@ -0,0 +1,32 @@ +name: Stage Image + +on: + pull_request: + types: [opened, synchronize, reopened, labeled, unlabeled, closed] + +permissions: + contents: read + packages: write + pull-requests: read + +jobs: + image: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Publish staging image + if: github.event.action != 'closed' && contains(github.event.pull_request.labels.*.name, 'stage') + uses: broadsheet-technology/publisher@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + image: ghcr.io/${{ github.repository }} + tags: stage-pr-${{ github.event.pull_request.number }} + + - name: Delete staging image + if: github.event.action == 'closed' || !contains(github.event.pull_request.labels.*.name, 'stage') + uses: broadsheet-technology/publisher@v1 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + image: ghcr.io/${{ github.repository }} + delete-tags: stage-pr-${{ github.event.pull_request.number }} diff --git a/Dockerfile b/Dockerfile index 9ef55ea..acab4b4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,26 +1,18 @@ FROM node:17.5.0 AS stencil WORKDIR /app -COPY . . - -# 1/ build the worpdress theme +COPY package*.json ./ RUN npm install -RUN npm run build - -FROM wordpress:5.9.1-php7.4-fpm - -# 1/ install redis -RUN pecl install redis && docker-php-ext-enable redis +# Build the WordPress theme. +COPY . . +RUN npm run build -# 2/ install cron -RUN apt-get update && apt-get -y install cron +FROM ghcr.io/broadsheet-technology/wordpress:0.5 -# 3/ install wordpress cronjob -RUN crontab -l | { cat; echo "*/10 * * * * /usr/local/bin/php -q /var/www/html/wp-cron.php >> /tmp/cron.log"; } | crontab - +COPY --from=stencil --chown=www-data:www-data /app/bin/wp-content/themes/wjh.dev /opt/wjh.dev/themes/wjh.dev +COPY --from=stencil --chown=www-data:www-data /app/bin/stencil-stats.json /opt/wjh.dev/stencil-stats.json +COPY config/wordpress/entrypoint.sh /usr/local/bin/wjhdev-entrypoint -# 4/ symolically link wordpress theme -COPY --from=stencil /app/bin/wp-content/themes /app/bin/themes -RUN touch /var/www/html/wp-content/themes; ln -s /app/bin/themes /var/www/html/wp-content/themes +RUN chmod +x /usr/local/bin/wjhdev-entrypoint -# 5/ dump env vars (for cron process), start cron service & run wordpress's docker-entrypoint -CMD printenv > /etc/environment && service cron start && bash /usr/local/bin/docker-entrypoint.sh php-fpm \ No newline at end of file +ENTRYPOINT ["/usr/local/bin/wjhdev-entrypoint"] diff --git a/config/wordpress/entrypoint.sh b/config/wordpress/entrypoint.sh new file mode 100755 index 0000000..42a574e --- /dev/null +++ b/config/wordpress/entrypoint.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -euo pipefail + +theme_source="/opt/wjh.dev/themes/wjh.dev" +theme_target="/var/www/html/wp-content/themes/wjh.dev" +stats_source="/opt/wjh.dev/stencil-stats.json" +stats_target="/srv/stencil-stats.json" + +mkdir -p "$(dirname "$theme_target")" "$(dirname "$stats_target")" + +rm -rf "$theme_target" +cp -a "$theme_source" "$theme_target" +cp "$stats_source" "$stats_target" +chown -R www-data:www-data "$theme_target" "$stats_target" + +if command -v docker-entrypoint.sh >/dev/null 2>&1; then + exec docker-entrypoint.sh "$@" +fi + +exec "$@" diff --git a/dev.env b/dev.env index 046cbd0..deb27cd 100644 --- a/dev.env +++ b/dev.env @@ -6,6 +6,13 @@ SITE_URL=wjh.dev.test SITE_WP_CONTENT_DIR=/bin/wp-content # WORDPRESS: +WORDPRESS_IMAGE=ghcr.io/wjhdev/wjh.dev:latest +BT_PHP_PM=dynamic +BT_PHP_PM_MAX_CHILDREN=30 +BT_PHP_PM_MAX_REQUESTS=500 +BT_PHP_UPLOAD_MAX_FILESIZE=6M +BT_PHP_OPCACHE_MAX_ACCELERATED_FILES=20000 +BT_PHP_OPCACHE_MEMORY_CONSUMPTION=256 WORDPRESS_DB_HOST=mariadb:3306 WORDPRESS_DB_NAME=wordpress WORDPRESS_DB_USER=wordpress @@ -16,4 +23,4 @@ WORDPRESS_UPLOADS_DIR=/bin/wp-content/uploads REDIS_PASSWORD=12345 # NEW RELIC -NRIA_LICENSE_KEY= \ No newline at end of file +NRIA_LICENSE_KEY= diff --git a/docker-compose.yml b/docker-compose.yml index 03195de..48b38b2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,6 @@ services: - 443:443 volumes: - wjh.dev-wordpress:/var/www/html - - ./${SITE_WP_CONTENT_DIR}/themes:/var/www/html/wp-content/themes - ./${SITE_WP_CONTENT_DIR}/uploads:/var/www/html/wp-content/uploads restart: always logging: @@ -23,7 +22,7 @@ services: DOMAIN: ${SITE_URL} wordpress: - image: ghcr.io/broadsheet-technology/wordpress:0.4 + image: ${WORDPRESS_IMAGE:-ghcr.io/wjhdev/wjh.dev:latest} container_name: ${COMPOSE_PROJECT_NAME}-wordpress links: - redis @@ -36,12 +35,16 @@ services: max-file: 10 volumes: - wjh.dev-wordpress:/var/www/html - - ./${SITE_WP_CONTENT_DIR}/themes:/var/www/html/wp-content/themes - ./${SITE_WP_CONTENT_DIR}/uploads:/var/www/html/wp-content/uploads - - ./bin/stencil-stats.json:/srv/stencil-stats.json environment: NRIA_LICENSE_KEY: ${NRIA_LICENSE_KEY} NRIA_APP_NAME: ${SITE_URL}-wordpress\/app + BT_PHP_PM: ${BT_PHP_PM:-dynamic} + BT_PHP_PM_MAX_CHILDREN: ${BT_PHP_PM_MAX_CHILDREN:-30} + BT_PHP_PM_MAX_REQUESTS: ${BT_PHP_PM_MAX_REQUESTS:-500} + BT_PHP_UPLOAD_MAX_FILESIZE: ${BT_PHP_UPLOAD_MAX_FILESIZE:-6M} + BT_PHP_OPCACHE_MAX_ACCELERATED_FILES: ${BT_PHP_OPCACHE_MAX_ACCELERATED_FILES:-20000} + BT_PHP_OPCACHE_MEMORY_CONSUMPTION: ${BT_PHP_OPCACHE_MEMORY_CONSUMPTION:-256} WORDPRESS_DB_HOST: ${WORDPRESS_DB_HOST} WORDPRESS_DB_USER: ${WORDPRESS_DB_USER} WORDPRESS_DB_PASSWORD: ${WORDPRESS_DB_PASSWORD} diff --git a/readme.md b/readme.md index 963aeac..24f94b8 100644 --- a/readme.md +++ b/readme.md @@ -16,8 +16,11 @@ vagrant up #### Deploying -To **deploy** install docker & docker compose. Then run: +To **deploy** install docker & docker compose. The GitHub Actions workflow publishes +`ghcr.io/wjhdev/wjh.dev` from `main` and then starts compose with that image: ``` -docker-compose up -d -``` \ No newline at end of file +WORDPRESS_IMAGE=ghcr.io/wjhdev/wjh.dev:latest docker-compose up -d +``` + +Pull requests labeled `stage` publish `ghcr.io/wjhdev/wjh.dev:stage-pr-`.