Installing writefreely 0.13.2 using docker on Ubuntu

docker install

curl https://get.docker.com | bash

docker-compose install

binary download

curl -s https://api.github.com/repos/docker/compose/releases/latest | grep browser_download_url  | grep docker-compose-linux-x86_64 | cut -d '"' -f 4 | wget -qi -

set permisisons

chmod +x docker-compose-linux-x86_64

moving

mv docker-compose-linux-x86_64 /usr/local/bin/docker-compose

done!

creating directories

mkdir -p /opt/writefreely
mkdir -p /opt/writefreely/{docker,data,code,keys,config}
mkdir -p /opt/writefreely/data/{mariadb,schema}
mkdir -p /opt/writefreely/code/{source,release}

download source code

cd /opt/writefreely/code/source 
wget https://github.com/writefreely/writefreely/archive/refs/tags/v0.13.2.tar.gz 
tar zxvf v0.13.2.tar.gz

download the compiled release

cd /opt/writefreely/code/release
wget https://github.com/writefreely/writefreely/releases/download/v0.13.2/writefreely_0.13.2_linux_amd64.tar.gz
tar zxvf writefreely_0.13.2_linux_amd64.tar.gz

creating the docker-compose config

vim /opt/writefreely/docker/docker-compose.yml

content

version: "3"

services:
  writefreely-web:
    container_name: "writefreely-web"
    image: "writeas/writefreely:latest"
    restart: unless-stopped
    volumes:
      - keys:/go/keys"
      - code:/opt/code"
      - "/opt/writefreely/config/config.ini:/go/config.ini"
     ports:
      - "8080:8080"
    depends_on:
      - "writefreely-db"
    networks:
      - "internal_writefreely"
      - "external_writefreely"

  writefreely-db:
    container_name: "writefreely-db"
    image: "mariadb:latest"
    volumes:
      - ariadb:/var/lib/mysql"
      - schema:/opt/schema"
      - code:/opt/code"
    environment:
      - MYSQL_DATABASE=writefreely
      - MYSQL_ROOT_PASSWORD=your_mariadb_password_here
    restart: unless-stopped
    networks:
      - "internal_writefreely"

networks:
  external_writefreely:
  internal_writefreely:
    internal: true

volumes:
  keys:
    driver_opts:
      type: none
      device: /opt/writefreely/keys
      o: bind    
  code:
    driver_opts:
      type: none
      device: /opt/writefreely/code
      o: bind    
  schema:
    driver_opts:
      type: none
      device: /opt/writefreely/data/schema
      o: bind    
  mariadb:
    driver_opts:
      type: none
      device: /opt/writefreely/data/mariadb
      o: bind

creating the config.ini file

vim /opt/writefreely/config/config.ini

content

[server]
hidden_host          =
port                 = 8080
bind                 = 0.0.0.0
tls_cert_path        =
tls_key_path         =
autocert             = false
templates_parent_dir =
static_parent_dir    =
pages_parent_dir     =
keys_parent_dir      =
hash_seed            =
gopher_port          = 0

[database]
type     = mysql
filename =
username = root
password = your_mariadb_password_here
database = writefreely
host     = writefreely-db
port     = 3306
tls      = false

[app]
site_name             = domain_here
site_description      = A site description here
host                  = https://your_writefreely_domain_here
theme                 = write
editor                =
disable_js            = false
webfonts              = true
landing               =
simple_nav            = false
wf_modesty            = false
chorus                = false
forest                = false
disable_drafts        = false
single_user           = false
open_registration     = false
open_deletion         = false
min_username_len      = 3
max_blogs             = 8
federation            = true
public_stats          = true
monetization          = false
notes_only            = false
private               = false
local_timeline        = true
user_invites          =
default_visibility    = public
update_checks         = true
disable_password_auth = false

[oauth.slack]
client_id          =
client_secret      =
team_id            =
callback_proxy     =
callback_proxy_api =

[oauth.writeas]
client_id          =
client_secret      =
auth_location      =
token_location     =
inspect_location   =
callback_proxy     =
callback_proxy_api =

[oauth.gitlab]
client_id          =
client_secret      =
host               =
display_name       =
callback_proxy     =
callback_proxy_api =

[oauth.gitea]
client_id          =
client_secret      =
host               =
display_name       =
callback_proxy     =
callback_proxy_api =

[oauth.generic]
client_id          =
client_secret      =
host               =
display_name       =
callback_proxy     =
callback_proxy_api =
token_endpoint     =
inspect_endpoint   =
auth_endpoint      =
scope              =
allow_disconnect   = false
map_user_id        =
map_username       =
map_display_name   =
map_email          =

creating the database

cd /opt/writefreely/docker
docker-compose up -d writefreely-db

running the schema

docker-compose exec writefreely-db sh -c 'exec mariadb -u root -pwritefreely-password writefreely < /opt/code/source/writefreely-0.13.2/schema.sql'

creating the keys

cd /opt/writefreely/code/release/writefreely
./writefreely -c /opt/writefreely/config/config.ini --gen-keys
chmod 644 keys/*
cp keys/* /opt/writefreely/keys/

starting writefreely

cd /opt/writefreely/docker
docker-compose up -d writefreely-web

check if it's running

docker-compose logs -f

expected output

writefreely-web  | 2023/06/10 13:09:05 Starting WriteFreely ...
writefreely-web  | 2023/06/10 13:09:05 Loading config.ini configuration...
writefreely-web  | 2023/06/10 13:09:05 Loading templates...
writefreely-web  | 2023/06/10 13:09:05 Loading pages...
writefreely-web  | 2023/06/10 13:09:05 Loading user pages...
writefreely-web  | 2023/06/10 13:09:06 Loading encryption keys...
writefreely-web  | 2023/06/10 13:09:06 Connecting to mysql database...
writefreely-web  | 2023/06/10 13:09:06 Initializing local timeline...
writefreely-web  | 2023/06/10 13:09:06 Adding blog.gcn.sh routes (multi-user)...
writefreely-web  | 2023/06/10 13:09:06 Going to serve...
writefreely-web  | 2023/06/10 13:09:06 Serving on http://0.0.0.0:8080
writefreely-web  | 2023/06/10 13:09:06 ---

initializing the database

cd /opt/writefreely/docker
docker-compose exec writefreely-web sh -c 'exec /go/cmd/writefreely/writefreely -c /go/config.ini --init-db'

expected output

2023/06/10 17:28:55 Loading /go/config.ini configuration...
2023/06/10 17:28:55 Connecting to mysql database...
2023/06/10 17:28:55 Creating table accesstokens...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table appcontent...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table appmigrations...
ERROR: 2023/06/10 17:28:55 app.go:903: Error 1050: Table 'appmigrations' already exists
2023/06/10 17:28:55 Creating table collectionattributes...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table collectionkeys...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table collectionpasswords...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table collectionredirects...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table collections...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table posts...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table remotefollows...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table remoteuserkeys...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table remoteusers...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table userattributes...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table userinvites...
ERROR: 2023/06/10 17:28:55 app.go:903: Error 1050: Table 'userinvites' already exists
2023/06/10 17:28:55 Creating table users...
2023/06/10 17:28:55 Created.
2023/06/10 17:28:55 Creating table usersinvited...
ERROR: 2023/06/10 17:28:55 app.go:903: Error 1050: Table 'usersinvited' already exists
2023/06/10 17:28:55 Initializing appmigrations table...
2023/06/10 17:28:55 Running migrations...
2023/06/10 17:28:55 Migrating to V2: support dynamic instance pages
2023/06/10 17:28:55 Migrating to V3: support users suspension
2023/06/10 17:28:55 Migrating to V4: support oauth
2023/06/10 17:28:55 Migrating to V5: support slack oauth
2023/06/10 17:28:55 Migrating to V6: support ActivityPub mentions
2023/06/10 17:28:55 Migrating to V7: support oauth attach
2023/06/10 17:28:55 Migrating to V8: support oauth via invite
2023/06/10 17:28:55 Migrating to V9: optimize drafts retrieval
2023/06/10 17:28:55 Migrating to V10: support post signatures
2023/06/10 17:28:55 Done.
2023/06/10 17:28:55 Closing database connection...

Yeah, it's done!

nginx config example

server {
    listen put_your_ip_here:80;
    server_name your_writefreely_domain_here;
    location / {
        return 301 https://your_writefreely_domain_here$request_uri;
    }
}

server {
    listen put_your_ip_here:443 ssl http2;
    server_name your_writefreely_domain_here;

    ssl_certificate /etc/letsencrypt/live/your_domain_dir_here/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your_domain_dir_here/privkey.pem;

    access_log /var/log/nginx/writefreely-access.log;
    error_log /var/log/nginx/gcn-blog-error.log;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_pass http://1.2.3.4:5678;
        proxy_redirect off;
    }
}

creating users

creating an admin user

cd /opt/writefreely/docker
docker-compose exec writefreely-web sh -c 'exec /go/cmd/writefreely/writefreely -c /go/config.ini --create-admin username:password'

ouput expected

2023/06/10 17:47:59 Loading /go/config.ini configuration...
2023/06/10 17:47:59 Connecting to mysql database...
2023/06/10 17:47:59 Creating admin USERNAME...
2023/06/10 17:47:59 Done!
2023/06/10 17:47:59 Closing database connection...

:)

creating a normal user

cd /opt/writefreely/docker
docker-compose exec writefreely-web sh -c 'exec /go/cmd/writefreely/writefreely -c /go/config.ini --create-user username:password'

reseting a user password

cd /opt/writefreely/docker
docker-compose exec writefreely-web sh -c 'exec /go/cmd/writefreely/writefreely -c /go/config.ini --reset-pass username'

Go to your blog!


Did you like our content?

We have a lot to share; visit our site!

Our fediverse services ;)

Chat and video? We have it!

Translation tools

Video Platform Frontends

Text Editors

You can also visit our hacking space!

Follow our founder!

Follow the status of our tools

Do you want to support us? You can!

See you!

[s]