From b0895a7a59b606cef9861e95b8b552efcd243c93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 19 May 2024 15:48:51 +0300 Subject: [PATCH 01/12] Update dockerfile to match the latest version --- Dockerfile | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/Dockerfile b/Dockerfile index 88eb37e..e2caa9f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,25 +14,33 @@ ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . -ARG GOLANG_VERSION=1.21 +ARG GOLANG_VERSION=1.22 # Build image FROM golang:${GOLANG_VERSION}-alpine as build -ARG WRITEFREELY_VERSION=v0.14.0 +LABEL org.opencontainers.image.source="https://github.com/writefreely/writefreely" +LABEL org.opencontainers.image.description="WriteFreely is a clean, minimalist publishing platform made for writers. Start a blog, share knowledge within your organization, or build a community around the shared act of writing." + +ARG WRITEFREELY_VERSION=v0.15.0 ARG WRITEFREELY_FORK=writeas/writefreely -RUN apk add --update nodejs npm make g++ git sqlite-dev +RUN apk -U upgrade \ + && apk add --no-cache nodejs npm make g++ git sqlite-dev \ + && npm install -g less less-plugin-clean-css \ + && mkdir -p /go/src/github.com/writefreely/writefreely RUN npm install -g less less-plugin-clean-css -RUN go get -u github.com/jteeuwen/go-bindata/... RUN mkdir -p /go/src/github.com/${WRITEFREELY_FORK} RUN git clone https://github.com/${WRITEFREELY_FORK}.git /go/src/github.com/${WRITEFREELY_FORK} -b ${WRITEFREELY_VERSION} WORKDIR /go/src/github.com/${WRITEFREELY_FORK} ENV GO111MODULE=on +ENV NODE_OPTIONS=--openssl-legacy-provider + RUN make build \ && make ui + RUN mkdir /stage && \ cp -R /go/bin \ /go/src/github.com/${WRITEFREELY_FORK}/templates \ @@ -44,14 +52,18 @@ RUN mkdir /stage && \ mv /stage/cmd/writefreely/writefreely /stage # Final image -FROM alpine:3.18 +FROM alpine:3.19 -RUN apk add --no-cache openssl ca-certificates +RUN apk -U upgrade && apk add --no-cache openssl ca-certificates COPY --from=build --chown=daemon:daemon /stage /writefreely COPY bin/writefreely-docker.sh /writefreely/ WORKDIR /writefreely VOLUME /data EXPOSE 8080 +USER daemon ENTRYPOINT ["/writefreely/writefreely-docker.sh"] + +HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \ + CMD curl -fSs http://localhost:8080/ || exit 1 From 0848e6689169de88c3ec733e24fe6a24f3f43ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 19 May 2024 15:49:28 +0300 Subject: [PATCH 02/12] Remove broken badges from readme --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 6ebc4a5..3d804e8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ # writefreely-docker -[![Build Status](https://ci.madhouse-project.org/api/badges/algernon/writefreely-docker/status.svg?branch=master)](https://ci.madhouse-project.org/algernon/writefreely-docker) -[![Docker Image](https://img.shields.io/badge/docker-latest-blue?style=flat-square)](https://hub.docker.com/r/algernon/writefreely) [![Source](https://img.shields.io/badge/source-git-brightgreen?style=flat-square)](https://git.madhouse-project.org/algernon/writefreely-docker) This is a [Docker][docker] image for [WriteFreely][writefreely], set up in a way From 697d3046923364bf29b36b56905372a3797346c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 19 May 2024 15:49:51 +0300 Subject: [PATCH 03/12] Make more environment variables available --- bin/writefreely-docker.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bin/writefreely-docker.sh b/bin/writefreely-docker.sh index 21079ac..570dcfb 100755 --- a/bin/writefreely-docker.sh +++ b/bin/writefreely-docker.sh @@ -35,6 +35,7 @@ fi WRITEFREELY_BIND_PORT="${WRITEFREELY_BIND_PORT:-8080}" WRITEFREELY_BIND_HOST="${WRITEFREELY_BIND_HOST:-0.0.0.0}" WRITEFREELY_SITE_NAME="${WRITEFREELY_SITE_NAME:-A Writefreely blog}" +WRITEFREELY_SITE_DESCRIPTION="${WRITEFREELY_SITE_DESCRIPTION:-My Writefreely blog}" cat >./config.ini < Date: Sun, 19 May 2024 15:50:15 +0300 Subject: [PATCH 04/12] Try to fix github workflows --- .github/workflows/docker-publish.yml | 78 +++++++++------------------- 1 file changed, 24 insertions(+), 54 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index bdd8e12..1b6bb34 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -1,88 +1,58 @@ name: Docker -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - on: - schedule: - - cron: '37 1 * * *' + workflow_dispatch: push: branches: [ main ] - # Publish semver tags as releases. tags: [ 'v*.*.*' ] - pull_request: - branches: [ main ] + schedule: + - cron: '37 1 * * *' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true env: - # Use docker.io for Docker Hub if empty REGISTRY: ghcr.io - # github.repository as / IMAGE_NAME: ${{ github.repository }} - jobs: build: - runs-on: ubuntu-latest permissions: contents: read packages: write - # This is used to complete the identity challenge - # with sigstore/fulcio when running outside of PRs. id-token: write steps: - - name: Checkout repository - uses: actions/checkout@v3 + - name: Checkout code + uses: actions/checkout@v4 - # Workaround: https://github.com/docker/build-push-action/issues/461 - - name: Setup Docker buildx - uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf - - # Login against a Docker registry except on PR - # https://github.com/docker/login-action - - name: Log into registry ${{ env.REGISTRY }} - if: github.event_name != 'pull_request' - uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GH_TOKEN }} - - name: Log in to Docker Hub - uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} - # Extract metadata (tags, labels) for Docker - # https://github.com/docker/metadata-action - - name: Extract Docker metadata + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Get metadata id: meta - uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + uses: docker/metadata-action@v5 with: images: | jrasanen/writefreely ghcr.io/${{ github.repository }} - - # Build and push Docker image with Buildx (don't push on PR) - # https://github.com/docker/build-push-action - - name: Build and push Docker image - id: build-and-push - uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a - with: - context: . - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - - - name: Build and push Docker images - uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + - name: Build and Push + uses: docker/build-push-action@v5 with: context: . + file: ./Dockerfile push: true - tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + tags: | + ${{ steps.meta.outputs.tags }} + ${{ env.DOCKERHUB_REPO }}:latest + platforms: linux/amd64,linux/arm64 From 2caf947ab4d059b44433e637ddc15397bebe0684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 19 May 2024 15:52:52 +0300 Subject: [PATCH 05/12] fix invalid reference format --- .github/workflows/docker-publish.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 1b6bb34..c0bdb65 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -52,7 +52,5 @@ jobs: file: ./Dockerfile push: true labels: ${{ steps.meta.outputs.labels }} - tags: | - ${{ steps.meta.outputs.tags }} - ${{ env.DOCKERHUB_REPO }}:latest + tags: ${{ steps.meta.outputs.tags }} platforms: linux/amd64,linux/arm64 From 1275ba1e23cb79521e250209a2789f45d774a654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 19 May 2024 16:36:41 +0300 Subject: [PATCH 06/12] add layer caching, build args --- .github/workflows/docker-publish.yml | 22 +++++++++++++++------- Dockerfile | 16 ---------------- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index c0bdb65..c3384e8 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -15,6 +15,7 @@ concurrency: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} + WRITEFREELY_VERSION: v0.15.0 jobs: build: @@ -37,13 +38,14 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Get metadata - id: meta - uses: docker/metadata-action@v5 + - uses: actions/cache@v3 with: - images: | - jrasanen/writefreely - ghcr.io/${{ github.repository }} + path: | + ~/.cache/go-build + ~/go/pkg/mod + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- - name: Build and Push uses: docker/build-push-action@v5 @@ -52,5 +54,11 @@ jobs: file: ./Dockerfile push: true labels: ${{ steps.meta.outputs.labels }} - tags: ${{ steps.meta.outputs.tags }} + build-args: | + WRITEFREELY_VERSION=${{ env.WRITEFREELY_VERSION }} + tags: | + ${{ env.DOCKERHUB_REPO }}:${{ env.WRITEFREELY_VERSION }} + ${{ env.DOCKERHUB_REPO }}:latest platforms: linux/amd64,linux/arm64 + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/Dockerfile b/Dockerfile index e2caa9f..658f9bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,19 +1,3 @@ -## Writefreely Docker image -## Copyright (C) 2019, 2020 Gergely Nagy -## -## This program is free software: you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation, either version 3 of the License, or -## (at your option) any later version. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program. If not, see . - ARG GOLANG_VERSION=1.22 # Build image From 45b5922be6e91d8b86f424d4dc6486e7498690fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 19 May 2024 16:39:15 +0300 Subject: [PATCH 07/12] remove unused variables, add dockerhub repo --- .github/workflows/docker-publish.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index c3384e8..3e172ff 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -13,9 +13,8 @@ concurrency: cancel-in-progress: true env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} WRITEFREELY_VERSION: v0.15.0 + DOCKERHUB_REPO: jrasanen/writefreely jobs: build: @@ -38,7 +37,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - uses: actions/cache@v3 + - uses: actions/cache@v4 with: path: | ~/.cache/go-build From 05b16210421e3bc1e7e2e5073038767b7c087465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 19 May 2024 17:36:54 +0300 Subject: [PATCH 08/12] remove healthcheck --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 658f9bf..e7212e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,5 +49,3 @@ USER daemon ENTRYPOINT ["/writefreely/writefreely-docker.sh"] -HEALTHCHECK --start-period=5s --interval=15s --timeout=5s \ - CMD curl -fSs http://localhost:8080/ || exit 1 From 0f4b06fa8fb8a96ebf6ce07953f7c45375100354 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Mon, 20 May 2024 08:00:55 +0300 Subject: [PATCH 09/12] Document all environment variables available --- README.md | 81 +++++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 3d804e8..4de4e38 100644 --- a/README.md +++ b/README.md @@ -1,56 +1,55 @@ -# writefreely-docker +# WriteFreely Docker Build -[![Source](https://img.shields.io/badge/source-git-brightgreen?style=flat-square)](https://git.madhouse-project.org/algernon/writefreely-docker) +This project builds a Docker image for [WriteFreely](https://github.com/writefreely/writefreely), a minimalist, privacy-focused, and federated blogging platform. The image is uses on Alpine Linux. -This is a [Docker][docker] image for [WriteFreely][writefreely], set up in a way -that makes it easier to deploy it in production, including the initial setup step. - - [docker]: https://www.docker.com/ - [writefreely]: https://github.com/writeas/writefreely - -## Overview - -The image is set up to use SQLite for the database, it does not support MySQL -out of the box - but you can always provide your own `config.ini`. The config -file, the database, and the generated keys are all stored on the single volume -the image uses, mounted on `/data`. - -The primary purpose of the image is to provide a single-step setup and upgrade -experience, where the initial setup and any upgrades are handled by the image -itself. As such, the image will create a default `config.ini` unless one already -exists, with reasonable defaults. It will also run database migrations, and save -a backup before doing so (which it will delete, if no migrations were -necessary). - -## Getting started +## Getting s tarted To get started, the easiest way to test it out is running the following command: -```shell +```bash docker run -p 8080:8080 -it --rm -v /some/path/to/data:/data \ - algernon/writefreely + jrasanen/writefreely ``` -Then point your browser to `http://localhost:8080`, and you should see -WriteFreely up and running. +Then point your browser to http://localhost:8080, and you should see WriteFreely up and running. ## Setup -The image will perform an initial setup, unless the supplied volume already -contains a `config.ini`. Settings can be tweaked via environment variables, of -which you can find a list below. Do note that these environment variables are -*only* used for the initial setup as of this writing! If a configuration file -already exists, the environment variables will be blissfully ignored. +The image will perform an initial setup, unless the supplied volume already contains a config.ini. Settings can be tweaked via environment variables, of which you can find a list below. Do note that these environment variables are only used for the initial setup as of this writing! If a configuration file already exists, the environment variables will be blissfully ignored. ### Environment variables -- `WRITEFREELY_BIND_HOST` and `WRITEFREELY_BIND_PORT` determine the host and port WriteFreely will bind to. Defaults to `0.0.0.0` and `8080`, respectively. -- `WRITEFREELY_SITE_NAME` is the site title one wants. Defaults to "A Writefreely blog". -- `WRITEFREELY_SINGLE_USER`, `WRITEFREELY_OPEN_REGISTRATION`, - `WRITEFREELY_MIN_USERNAME_LEN`, `WRITEFREELY_MAX_BLOG`, - `WRITEFREELY_FEDERATION`, `WRITEFREELY_PUBLIC_STATS`, `WRITEFREELY_PRIVATE`, - `WRITEFREELY_LOCAL_TIMELINE`, and `WRITEFREELY_USER_INVITES` all correspond to - the similarly named `config.ini` settings. See the [WriteFreely docs][wf:docs] - for more information about them. +The following variables will be used to construct the `config.ini` on first start. After it has been configured, you can edit it on the volume. - [wf:docs]: https://writefreely.org/docs/latest/admin/config +## General Configuration + +- **`WRITEFREELY_BIND_PORT`**: Specifies the port on which the WriteFreely server will listen. Defaults to `8080`. +- **`WRITEFREELY_BIND_HOST`**: Defines the host IP to bind to. Defaults to `0.0.0.0`. +- **`WRITEFREELY_SITE_NAME`**: Sets the name of your WriteFreely site. Used to identify the site in federation. +- **`WRITEFREELY_SITE_DESCRIPTION`**: Provides a short description of your site. This description may be used in federated networks. + +## Database Configuration + +- **`WRITEFREELY_DATABASE_DATABASE`**: Specifies the type of database used, such as `mysql` or `sqlite3`. +- **`WRITEFREELY_DATABASE_USERNAME`**: The username for the database. +- **`WRITEFREELY_DATABASE_PASSWORD`**: The password for the database. +- **`WRITEFREELY_DATABASE_NAME`**: The name of the database to connect to. +- **`WRITEFREELY_DATABASE_HOST`**: The hostname or IP address of the database server. +- **`WRITEFREELY_DATABASE_PORT`**: The port number on which the database server is running. + +## Application Settings + +- **`WRITEFREELY_HOST`**: The full URL where the site will be accessible. +- **`WRITEFREELY_SINGLE_USER`**: Set to `true` to run the instance as a single-user blog, otherwise `false`. +- **`WRITEFREELY_OPEN_REGISTRATION`**: Whether or not anyone can register via the landing page +- **`WRITEFREELY_MIN_USERNAME_LEN`**: The minimum length for usernames. +- **`WRITEFREELY_MAX_BLOG`**: Maximum number of blogs a single user can create under one account +- **`WRITEFREELY_FEDERATION`**: Whether or not federation via ActivityPub is enabled +- **`WRITEFREELY_PUBLIC_STATS`**: DWhether or not usage stats are made public via NodeInfo +- **`WRITEFREELY_PRIVATE`**: Set to `true` to make the site private. +- **`WRITEFREELY_LOCAL_TIMELINE`**: Whether or not the instance reader (and the Public option on blogs) is enabled +- **`WRITEFREELY_USER_INVITES`**: Who is allowed to send user invites, if anyone. A blank value disables invites for all users. Valid choices: empty, user, or admin + +### Volumes + +* `/data`: Directory where WriteFreely stores its data, including database files and configuration. From a15d4e58cd4378bb393668ce3ab4733425162ea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Mart=C3=ADn?= Date: Wed, 12 Jun 2024 11:59:37 +0200 Subject: [PATCH 10/12] Add enhanced configuration and Docker Compose support for WriteFreely (#2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update ini configuration. Add docker-compose examples * remove unneeded network config * Add docker compose instructions * Correct sqlite location * do not wait for MariaDB * Use writefreely user * Add .env instructions for docker compose * Retry init if database is not ready * Ignore production directories * Improve init checks * refactor init script --------- Co-authored-by: Germán Martín --- .dockerignore | 2 + .env.mariadb | 38 +++++++ .env.sqlite | 31 ++++++ .gitignore | 2 + Dockerfile | 13 ++- README.md | 90 ++++++++++++++- bin/writefreely-docker.sh | 217 +++++++++++++++++++++++++++++------- docker-compose.mariadb.yaml | 32 ++++++ docker-compose.sqlite3.yaml | 15 +++ 9 files changed, 399 insertions(+), 41 deletions(-) create mode 100644 .env.mariadb create mode 100644 .env.sqlite create mode 100644 docker-compose.mariadb.yaml create mode 100644 docker-compose.sqlite3.yaml diff --git a/.dockerignore b/.dockerignore index 1269488..4f8233a 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,3 @@ data +db-data +.env diff --git a/.env.mariadb b/.env.mariadb new file mode 100644 index 0000000..21e328e --- /dev/null +++ b/.env.mariadb @@ -0,0 +1,38 @@ + +# General Configuration +WRITEFREELY_BIND_PORT=8080 +WRITEFREELY_BIND_HOST=0.0.0.0 +WRITEFREELY_SITE_NAME="My Blog" +WRITEFREELY_SITE_DESCRIPTION="My fancy blog" + +# Database Configuration +MARIADB_USER=writefreely +MARIADB_PASSWORD=changeme +MARIADB_DATABASE=writefreely +MARIADB_ROOT_PASSWORD=changeme + +WRITEFREELY_DATABASE_DATABASE=mysql +WRITEFREELY_DATABASE_USERNAME=${MARIADB_USER} +WRITEFREELY_DATABASE_PASSWORD=${MARIADB_PASSWORD} +WRITEFREELY_DATABASE_NAME=${MARIADB_DATABASE} +WRITEFREELY_DATABASE_HOST=writefreely-db +WRITEFREELY_DATABASE_PORT=3306 + + +# Application Settings +WRITEFREELY_HOST= +WRITEFREELY_SINGLE_USER=true +WRITEFREELY_OPEN_REGISTRATION=false +WRITEFREELY_MIN_USERNAME_LEN=4 +WRITEFREELY_MAX_BLOG=4 +WRITEFREELY_FEDERATION=true +WRITEFREELY_PUBLIC_STATS=true +WRITEFREELY_PRIVATE=false +WRITEFREELY_LOCAL_TIMELINE=true +WRITEFREELY_USER_INVITES= + +# Writefreely Users +WRITEFREELY_ADMIN_USER=admin +WRITEFREELY_ADMIN_PASSWORD=changeme +WRITEFREELY_WRITER_USER= +WRITEFREELY_WRITER_PASSWORD= diff --git a/.env.sqlite b/.env.sqlite new file mode 100644 index 0000000..5e8292a --- /dev/null +++ b/.env.sqlite @@ -0,0 +1,31 @@ + +# General Configuration +WRITEFREELY_BIND_PORT=8080 +WRITEFREELY_BIND_HOST=0.0.0.0 +WRITEFREELY_SITE_NAME="My Blog" +WRITEFREELY_SITE_DESCRIPTION="My fancy blog" + +# Database Configuration +WRITEFREELY_DATABASE_DATABASE=sqlite3 +WRITEFREELY_SQLITE_FILENAME=./writefreely.db +WRITEFREELY_DATABASE_USERNAME=writefreely +WRITEFREELY_DATABASE_PASSWORD=changeme +WRITEFREELY_DATABASE_NAME=writefreely + +# Application Settings +WRITEFREELY_HOST= +WRITEFREELY_SINGLE_USER=true +WRITEFREELY_OPEN_REGISTRATION=false +WRITEFREELY_MIN_USERNAME_LEN=4 +WRITEFREELY_MAX_BLOG=4 +WRITEFREELY_FEDERATION=true +WRITEFREELY_PUBLIC_STATS=true +WRITEFREELY_PRIVATE=false +WRITEFREELY_LOCAL_TIMELINE=true +WRITEFREELY_USER_INVITES= + +# Writefreely Users +WRITEFREELY_ADMIN_USER=admin +WRITEFREELY_ADMIN_PASSWORD=changeme +WRITEFREELY_WRITER_USER= +WRITEFREELY_WRITER_PASSWORD= diff --git a/.gitignore b/.gitignore index 82f0c3a..b1ee384 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /data/ +/db-data/ +/.env diff --git a/Dockerfile b/Dockerfile index e7212e6..f09c749 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ LABEL org.opencontainers.image.source="https://github.com/writefreely/writefreel LABEL org.opencontainers.image.description="WriteFreely is a clean, minimalist publishing platform made for writers. Start a blog, share knowledge within your organization, or build a community around the shared act of writing." ARG WRITEFREELY_VERSION=v0.15.0 -ARG WRITEFREELY_FORK=writeas/writefreely +ARG WRITEFREELY_FORK=writefreely/writefreely RUN apk -U upgrade \ && apk add --no-cache nodejs npm make g++ git sqlite-dev \ @@ -38,14 +38,23 @@ RUN mkdir /stage && \ # Final image FROM alpine:3.19 +ARG WRITEFREELY_UID=1000 +ARG WRITEFREELY_GID=1000 + RUN apk -U upgrade && apk add --no-cache openssl ca-certificates + +RUN addgroup -g ${WRITEFREELY_GID} -S writefreely && adduser -u ${WRITEFREELY_UID} -S -G writefreely writefreely + COPY --from=build --chown=daemon:daemon /stage /writefreely COPY bin/writefreely-docker.sh /writefreely/ WORKDIR /writefreely VOLUME /data EXPOSE 8080 -USER daemon + +RUN chown -R writefreely:writefreely /writefreely + +USER writefreely ENTRYPOINT ["/writefreely/writefreely-docker.sh"] diff --git a/README.md b/README.md index 4de4e38..2311d4a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This project builds a Docker image for [WriteFreely](https://github.com/writefreely/writefreely), a minimalist, privacy-focused, and federated blogging platform. The image is uses on Alpine Linux. -## Getting s tarted +## Getting started To get started, the easiest way to test it out is running the following command: @@ -31,6 +31,7 @@ The following variables will be used to construct the `config.ini` on first star ## Database Configuration - **`WRITEFREELY_DATABASE_DATABASE`**: Specifies the type of database used, such as `mysql` or `sqlite3`. +- **`WRITEFREELY_SQLITE_FILENAME`**: (Optional) DB filename if `sqlite3` detabase is selected. Defaults to `/data/writefreely.db`. - **`WRITEFREELY_DATABASE_USERNAME`**: The username for the database. - **`WRITEFREELY_DATABASE_PASSWORD`**: The password for the database. - **`WRITEFREELY_DATABASE_NAME`**: The name of the database to connect to. @@ -50,6 +51,93 @@ The following variables will be used to construct the `config.ini` on first star - **`WRITEFREELY_LOCAL_TIMELINE`**: Whether or not the instance reader (and the Public option on blogs) is enabled - **`WRITEFREELY_USER_INVITES`**: Who is allowed to send user invites, if anyone. A blank value disables invites for all users. Valid choices: empty, user, or admin +## Writefreely Users + +- **`WRITEFREELY_ADMIN_USER`**: Administrator user name. In single user instances is editor too. +- **`WRITEFREELY_ADMIN_PASSWORD`**: Administrator password + ### Volumes * `/data`: Directory where WriteFreely stores its data, including database files and configuration. + +### Using Docker Compose + +You can use Docker Compose to set up WriteFreely with different database configurations. The configuration files are already included in this repository. Follow the steps below to start the services. + +#### Clone the Repository + +First, clone this repository: + +```bash +git clone https://github.com/yourusername/writefreely-docker.git +cd writefreely-docker +``` + +#### Prepare the Data Directory + +Create the data directory and assign the appropriate permissions: + +```bash +mkdir data +sudo chown 1000:1000 data +``` + +#### Configure the Environment + +Before starting the services, you need to copy the appropriate .env file and edit it to configure the environment variables, especially the passwords. + +##### For MariaDB + +Copy the .env.mariadb file to .env: + +```bash +cp .env.mariadb .env +``` + +##### For SQLite + +Copy the .env.sqlite file to .env: + +```bash +cp .env.sqlite .env +``` + +Then, edit the .env file to set the appropriate values for your environment: + +```bash +nano .env +``` + +Ensure to set secure passwords and other necessary configuration options. + +#### Start the Services + +##### MariaDB + +To use the **MariaDB** configuration, run: + +```bash +docker-compose -f docker-compose.mariadb.yaml up +``` + +##### SQLite + +To use the **SQLite** configuration, run: + +```bash +docker-compose -f docker-compose.sqlite3.yaml up +``` + +### Building the Image + +If you want to build the image yourself, clone this repository and run the following command inside the repository's directory: + +```bash +docker build -t yourusername/writefreely . +``` + +Replace `yourusername` with your Docker Hub username or a suitable image name. + +### Contributing + +Contributions are welcome! Please fork this repository and submit pull requests for any enhancements or bug fixes. diff --git a/bin/writefreely-docker.sh b/bin/writefreely-docker.sh index 570dcfb..da78a9f 100755 --- a/bin/writefreely-docker.sh +++ b/bin/writefreely-docker.sh @@ -20,16 +20,85 @@ set -e cd /data WRITEFREELY=/writefreely/writefreely +attempts=0 +max_attempts=5 + +log() { + echo "$(date '+%Y/%m/%d %H:%M:%S') $1" +} + +validate_url() { + URL="$1" + if echo "$URL" | grep -Eq "^https?://[a-zA-Z0-9._-]+"; then + return 0 # Success + else + return 1 # Failure + fi +} + +retry_command() { + local cmd=$1 + attempts=0 + until $cmd; do + attempts=$((attempts+1)) + if [ $attempts -ge $max_attempts ]; then + log "Failed to execute '$cmd' after $attempts attempts." + return 1 + fi + log "Retrying '$cmd' ($attempts/$max_attempts)..." + sleep 5 + done + return 0 +} + +initialize_database() { + log "Initializing database..." + if ! retry_command "${WRITEFREELY} --init-db"; then + log "Initialization of database failed. Removing config.ini." + rm ./config.ini + exit 1 + fi +} + +generate_keys() { + log "Generating keys..." + ${WRITEFREELY} --gen-keys +} + +create_admin_user() { + if [ -n "$WRITEFREELY_ADMIN_USER" ]; then + ${WRITEFREELY} user create --admin ${WRITEFREELY_ADMIN_USER}:${WRITEFREELY_ADMIN_PASSWORD} + log "Created admin user ${WRITEFREELY_ADMIN_USER}" + else + log "Admin user not defined" + exit 1 + fi +} + +create_writer_user() { + if [ -n "$WRITEFREELY_WRITER_USER" ]; then + ${WRITEFREELY} user create ${WRITEFREELY_WRITER_USER}:${WRITEFREELY_WRITER_PASSWORD} + log "Created writer user ${WRITEFREELY_WRITER_USER}" + fi +} + +validate_url "$WRITEFREELY_HOST" || { + log "Error: $WRITEFREELY_HOST is not a valid URL. It must start with http:// or https:// and be followed by a valid hostname." + exit 1 +} if [ -e ./config.ini ] && [ -e ./keys/email.aes256 ]; then - ${WRITEFREELY} -migrate - exec ${WRITEFREELY} + log "Migration required. Running migration..." + ${WRITEFREELY} -migrate + exec ${WRITEFREELY} fi if [ -e ./config.ini ]; then - ${WRITEFREELY} -init-db - ${WRITEFREELY} -gen-keys - exec ${WRITEFREELY} + initialize_database + generate_keys + create_admin_user + create_writer_user + exec ${WRITEFREELY} fi WRITEFREELY_BIND_PORT="${WRITEFREELY_BIND_PORT:-8080}" @@ -39,44 +108,116 @@ WRITEFREELY_SITE_DESCRIPTION="${WRITEFREELY_SITE_DESCRIPTION:-My Writefreely blo cat >./config.ini < Date: Sun, 3 Nov 2024 09:55:00 +0200 Subject: [PATCH 11/12] update to 0.15.1 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index f09c749..9572f3f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,7 +6,7 @@ FROM golang:${GOLANG_VERSION}-alpine as build LABEL org.opencontainers.image.source="https://github.com/writefreely/writefreely" LABEL org.opencontainers.image.description="WriteFreely is a clean, minimalist publishing platform made for writers. Start a blog, share knowledge within your organization, or build a community around the shared act of writing." -ARG WRITEFREELY_VERSION=v0.15.0 +ARG WRITEFREELY_VERSION=v0.15.1 ARG WRITEFREELY_FORK=writefreely/writefreely RUN apk -U upgrade \ From 7f5284fedc5e0bf5b36717ba8851faedad8c29a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jussi=20R=C3=A4s=C3=A4nen?= Date: Sun, 3 Nov 2024 09:59:21 +0200 Subject: [PATCH 12/12] Update docker workflow WriteFreely version --- .github/workflows/docker-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index 3e172ff..b4b6758 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -13,7 +13,7 @@ concurrency: cancel-in-progress: true env: - WRITEFREELY_VERSION: v0.15.0 + WRITEFREELY_VERSION: v0.15.1 DOCKERHUB_REPO: jrasanen/writefreely jobs: