How To Deploy WriteFreely via Docker (Tutorial)

The “Golden Path” Guide: Installing WriteFreely with Docker (2025 Edition)

This method builds the image directly from the official WriteFreely source code, ensuring you are up-to-date. It also fixes common “split-brain” configuration issues where the app can’t talk to the database.

Prerequisites:

  • A server or computer (Linux is best).
  • docker and git installed.

Step 1: Create the Directory Structure

We need a clean folder structure. We will use two separate folders for data to avoid file conflicts.

1. Create the main folder

sudo mkdir -p /opt/writefreely

2. Create the data sub-folders

app_data holds your config and keys.

sudo mkdir -p /opt/writefreely/app_data

db_data holds the database files.

sudo mkdir -p /opt/writefreely/db_data

3. Enter the directory

cd /opt/writefreely

Step 2: Get the Official Code

We aren’t downloading a pre-made image; we are downloading the recipe to build it ourselves.

git clone https://github.com/writefreely/writefreely.git

Step 3: Create the Configuration Files

We need two files.

1. The .env file
This configures the Database. Create a file named .env and paste this in. Change the passwords!


# /opt/writefreely/.env

MARIADB_ROOT_PASSWORD=change_this_to_a_strong_root_password
MARIADB_DATABASE=writefreely
MARIADB_USER=writefreely
MARIADB_PASSWORD=change_this_to_a_strong_user_password

2. The docker-compose.yml file
This tells Docker how to run everything. Create a file named docker-compose.yml and paste this exact content:

services:
  app:
    # Build from the official code we cloned
    build:
    context: ./writefreely
    dockerfile: Dockerfile.prod
    image: writefreely-local-prod:latest
    container_name: writefreely-app
    depends_on:
      db:
        condition: service_healthy
      ports:
        - 8080:8080
    volumes:
      # Map the app_data folder to the container
      - ./app_data:/data
    restart: unless-stopped
    networks:
      - writefreely-net
  db:
    image: mariadb:latest
    container_name: writefreely-db
    init: true
    volumes:
      # Map the db_data folder to the container
      - ./db_data:/var/lib/mysql
    env_file:
      - .env
    restart: unless-stopped
    healthcheck:
      test: [“CMD-SHELL”, “mysqladmin ping -h localhost -u $$MARIADB_USER -p$$MARIADB_PASSWORD”]
    interval: 30s
    timeout: 10s
    retries: 5
    start_period: 10s
    networks:
      - writefreely-net
  networks:
    writefreely-net:
    driver: bridge

Step 4: Build the Image

This might take a few minutes. It compiles the latest version of WriteFreely for your machine.

docker compose build app

Step 5: Start the Database

We need the database running before we can configure the app.

docker compose up -d db

Wait!

Run

docker ps -a --format "table {{.Names}}\\t{{.Status}}"

Wait until the status for writefreely-db says (healthy). Do not proceed until it is healthy.

Step 6: Run the Configuration Wizard

This is the most critical step. We need to create a config.ini file that matches your .env file.

docker compose run --rm app writefreely config start

Answer the prompts exactly like this:

  1. Choose your configuration: Select Production, behind reverse proxy.
  2. Database setup: Select MySQL.
  3. Username: writefreely
  4. Password: (Enter the exact MARIADB_PASSWORD you put in your .env file).
  5. Database name: writefreely
  6. Host: db (Important: Type db, do NOT type localhost).
  7. Port: 3306

Follow the rest of the prompts to name your blog and create your admin user.

Step 7: Final Initialization

Run these commands one by one to finish the setup.

1. Generate encryption keys

docker compose run --rm app writefreely keys generate

2. Create the database tables

docker compose run --rm app writefreely --init-db

Step 8: Launch!

Everything is ready. Start the application.

docker compose up -d

Your blog is now running at http://YOUR_IP:8080.

1 Like

Awesome tutorial – thanks for sharing this!

1 Like