├── .dockerignore
├── .github
├── FUNDING.yml
├── config.yml
├── dependabot.yml
├── workflows
│ ├── main.yml
│ └── manual.yml
└── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── install
├── etc
│ ├── services.available
│ │ ├── 30-sidekiq
│ │ │ └── run
│ │ └── 20-discourse
│ │ │ └── run
│ └── cont-init.d
│ │ └── 20-discourse
└── assets
│ ├── defaults
│ └── 20-discourse
│ └── functions
│ └── 20-discourse
├── LICENSE
├── examples
└── compose.yml
├── CHANGELOG.md
├── Dockerfile
└── README.md
/.dockerignore:
--------------------------------------------------------------------------------
1 | examples/
2 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [tiredofit]
2 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | # Maintain dependencies for GitHub Actions
4 | - package-ecosystem: "github-actions"
5 | directory: "/"
6 | schedule:
7 | interval: "daily"
8 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: "build_image"
2 |
3 | on:
4 | push:
5 | paths:
6 | - "**"
7 | - "!README.md"
8 |
9 | jobs:
10 | build:
11 | uses: tiredofit/github_actions/.github/workflows/default_amd64.yml@main
12 | #uses: tiredofit/github_actions/.github/workflows/default_amd64.yml@main
13 | #uses: tiredofit/github_actions/.github/workflows/default_amd64_armv7_arm64.yml@main
14 | #uses: tiredofit/github_actions/.github/workflows/default_amd64_arm64.yml@main
15 | secrets: inherit
16 |
--------------------------------------------------------------------------------
/.github/workflows/manual.yml:
--------------------------------------------------------------------------------
1 | name: "manual_build_image"
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | Manual Build:
7 | description: 'Manual Build'
8 | required: false
9 |
10 | jobs:
11 | build:
12 | uses: tiredofit/github_actions/.github/workflows/default_amd64.yml@main
13 | #uses: tiredofit/github_actions/.github/workflows/default_amd64.yml@main
14 | #uses: tiredofit/github_actions/.github/workflows/default_amd64_armv7_arm64.yml@main
15 | #uses: tiredofit/github_actions/.github/workflows/default_amd64_arm64.yml@main
16 | secrets: inherit
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea or feature
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | ---
11 | name: Feature Request
12 | about: Suggest an idea for this project
13 |
14 | ---
15 |
16 | **Description of the feature**
17 |
18 |
19 | **Benftits of feature**
20 |
21 |
22 | **Additional context**
23 |
24 |
--------------------------------------------------------------------------------
/install/etc/services.available/30-sidekiq/run:
--------------------------------------------------------------------------------
1 | #!/command/with-contenv bash
2 |
3 | source /assets/functions/00-container
4 | source /assets/defaults/20-discourse
5 | prepare_service
6 | PROCESS_NAME="sidekiq"
7 |
8 | check_container_initialized
9 | check_service_initialized 20-discourse
10 | liftoff
11 |
12 | print_start "Starting Sidekiq"
13 | cd /app/
14 | silent sudo -Eu discourse \
15 | exec bundle exec sidekiq \
16 | --concurrency ${SIDEKIQ_THREADS} \
17 | --environment production \
18 | --logfile "${LOG_PATH}"/"${SIDEKIQ_LOG_FILE}" \
19 | ${SIDEKIQ_ADDITIONAL_ARGS} >> "${LOG_PATH}"/"${SIDEKIQ_LOG_FILE}"
20 |
--------------------------------------------------------------------------------
/install/etc/services.available/20-discourse/run:
--------------------------------------------------------------------------------
1 | #!/command/with-contenv bash
2 |
3 | source /assets/functions/00-container
4 | prepare_service
5 | PROCESS_NAME="rails"
6 |
7 | check_container_initialized
8 | liftoff
9 |
10 | if var_true "${DELIVER_SECURE_ASSETS}" ; then export DISCOURSE_FORCE_HTTPS=true ; fi
11 | export DISCOURSE_SITE_TITLE=${SITE_TITLE}
12 | export UNICORN_WORKERS=${UNICORN_WORKERS}
13 |
14 | cd /app/
15 | print_start "Starting Unicorn - Discourse version ${DISCOURSE_VERSION}"
16 | s6-setuidgid discourse \
17 | exec bin/unicorn \
18 | -E production \
19 | -o 0.0.0.0 \
20 | -p "${LISTEN_PORT}" \
21 | -c "config/unicorn.conf.rb" ${UNICORN_ADDITIONAL_ARGS}
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: If something isn't working right..
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### Summary
11 |
12 |
13 |
14 |
15 | ### Steps to reproduce
16 |
17 |
18 |
19 |
20 | ### What is the expected *correct* behavior?
21 |
22 |
23 |
24 |
25 | ### Relevant logs and/or screenshots
26 |
27 |
28 |
29 | ### Environment
30 |
31 |
32 | - Image version / tag:
33 | - Host OS:
34 |
35 |
36 | Any logs | docker-compose.yml
37 |
38 |
39 |
40 |
41 | ### Possible fixes
42 |
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2024 Dave Conroy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/install/etc/cont-init.d/20-discourse:
--------------------------------------------------------------------------------
1 | #!/command/with-contenv bash
2 |
3 | source /assets/functions/00-container
4 | prepare_service
5 | PROCESS_NAME="discourse"
6 |
7 | cat <
2 |
3 | Add EOL notice and deprecate image
4 |
5 |
6 | ## 3.2.17 2025-08-31
7 |
8 | ### Added
9 | - Discourse 3.5.0
10 |
11 |
12 | ## 3.2.16 2025-07-29
13 |
14 | ### Added
15 | - RubyLang 3.3.9
16 | - Discourse 3.4.7
17 |
18 |
19 | ## 3.2.15 2025-06-25
20 |
21 | ### Added
22 | - Discourse 3.4.6
23 |
24 |
25 | ## 3.2.14 2025-06-13
26 |
27 | ### Changed
28 | - Fix issue with Plugins path not linking properly
29 | - Fix issue with Uploads path not being created properly with correct permissions
30 |
31 |
32 | ## 3.2.13 2025-06-09
33 |
34 | ### Added
35 | - Discourse 3.4.5
36 |
37 | ### Changed
38 | - Fix permissions when compiling_assets (credit: DrChat@github)
39 |
40 |
41 | ## 3.2.12 2025-05-28
42 |
43 | ### Added
44 | - Force change ownership of log directory post compilation of assets
45 |
46 |
47 | ## 3.2.11 2025-05-28
48 |
49 | ### Added
50 | - Discourse 3.4.4
51 |
52 |
53 | ## 3.2.10 2025-04-29
54 |
55 | ### Added
56 | - RubyLang 3.3.8
57 | - Discourse 3.4.3
58 |
59 |
60 | ## 3.2.9 2025-03-26
61 |
62 | ### Changed
63 | - Downgrade Ruby 3.3.7
64 |
65 |
66 | ## 3.2.8 2025-03-26
67 |
68 | ### Added
69 | - Discourse 3.4.2
70 | - Ruby 3.3.8
71 |
72 |
73 | ## 3.2.7 2025-02-24
74 |
75 | ### Added
76 | - Ruby Lang 3.3.7
77 | - Discourse 3.4.1
78 |
79 |
80 | ## 3.2.6 2025-02-04
81 |
82 | ### Added
83 | - Discourse 3.4.0
84 |
85 |
86 | ## 3.2.5 2025-02-01
87 |
88 | ### Changed
89 | - Rename mermaid plugin to discourse-mermaid
90 |
91 |
92 | ## 3.2.4 2025-02-01
93 |
94 | ### Changed
95 | - Fix to sidekiq not starting trying to reference old named init script
96 |
97 |
98 | ## 3.2.3 2025-02-01
99 |
100 | ### Changed
101 | - Create /app/tmp ahead of time and set proper permissions
102 | - Set permissions on introducing app plugins
103 | - Fix an issue with a shell alias
104 |
105 |
106 | ## 3.2.2 2024-12-20
107 |
108 | ### Added
109 | - 3.2.1 Patch
110 |
111 |
112 | ## 3.2.1 2024-12-20
113 |
114 | ### Added
115 | - Image cleanup
116 | - Refine Options
117 | - Add rake alias
118 | - Set Mermaid plugin to true
119 | - Change defaults
120 |
121 |
122 | ## 3.2.0 2024-12-19
123 |
124 | ### Added
125 | - Discourse 3.3.3
126 | - Debian Bookworm
127 | - Ruby 3.3.6
128 | - Ability to create admin user and admin pass on first install
129 | - Switch to Unicorn from Puma
130 | - Added more plugin support
131 |
132 |
133 | ## 3.1.4 2023-03-17
134 |
135 | ### Added
136 | - Discourse 3.0.2
137 |
138 |
139 | ## 3.1.3 2023-02-26
140 |
141 | ### Changed
142 | - Fix for building chat plugin
143 |
144 |
145 | ## 3.1.2 2023-02-26
146 |
147 | ### Added
148 | - Discourse 3.0.1
149 |
150 |
151 | ## 3.1.1 2023-02-26
152 |
153 | ### Added
154 | - Discourse 2.8.14
155 |
156 |
157 | ## 3.1.0 2022-12-19
158 |
159 | ### Added
160 | - Change base image to use `tiredofit/nginx`
161 | - Set Nginx to be disabled
162 | - Set Nginx to automatically proxy all requests in to 127.0.0.1:3000
163 |
164 |
165 | ## 3.0.1 2022-12-16
166 |
167 | ### Changed
168 | - Remove directories that are not necessary to reduce image size
169 |
170 |
171 | ## 3.0.0 2022-12-15
172 |
173 | This has breaking changes all over the image, specifically related to paths and environment variables. Please read the README.md carefully and view examples and port over accordingly.
174 |
175 | ### Added
176 | - Discourse 2.8.13
177 | - Debian Bullseye
178 | - Ruby 3.0.5 compiled w/ JemAlloc
179 | - Node 16
180 | - Added new image optimization packages
181 | - Postgresql 15 Support
182 | - Rewrote initialization routines and configured configurable paths for uploads, backups, plugins, logs
183 | - Logrotate routines for all logs
184 | - Switchable environment variables for plugins
185 | - New plugins added: Footnote, Formatting Toolbar, Mermaid, Post Voting, Spoiler Alert
186 |
187 | ### Changed
188 | - Reworked all environment variables, now use standard variables for those used to other tiredofit images
189 |
190 |
191 | ## 2.5.1 2021-12-15
192 |
193 | ### Added
194 | - Discourse 2.7.9
195 |
196 |
197 | ## 2.5.0 2020-07-17
198 |
199 | ### Added
200 | - Update to Discourse 2.6.0-beta1
201 | - Remove some plugins
202 |
203 |
204 | ## 2.4.1 2019-11-29
205 |
206 | ### Added
207 | - Discourse 2.3.6
208 |
209 | ### Changed
210 | - Ruby 2.6
211 |
212 | ## 2.4 2019-09-01
213 |
214 | * Update Discourse version to 2.3.2
215 |
216 | ## 2.3 2019-07-02
217 |
218 | * Discourse 2.3.1
219 |
220 | ## 2.2.1 2019-03-26
221 |
222 | * Discourse 2.2.3
223 |
224 | ## 2.2 2019-02-28
225 |
226 | * Discourse 2.2.0
227 | * Ruby 2.5
228 | * NodeJS 11
229 |
230 | ## 2.1-dev 2018-08-26
231 |
232 | * Putting Nginx in front of 3000 for CORS
233 |
234 | ## 2.0.2 2018-08-26
235 |
236 | * Bump to 2.0.4
237 |
238 | ## 2.01 2018-07-10
239 |
240 | * Bump to 2.02
241 |
242 | ## 2.0 2018-06-04
243 |
244 | * Migrate to Debian Stretch
245 | * Ruby 2.4
246 | * Discourse 2.0
247 |
248 | ## 1.4 2018-02-01
249 |
250 | * Rebase
251 |
252 | ## 1.3 2017-10-19
253 |
254 | * Version Bump and Cleanup
255 |
256 |
257 | ## 1.2 2017-08-25
258 |
259 | * A few more plugins added
260 |
261 | ## 1.1 2017-08-25
262 |
263 | * Major Cleanup
264 | * Added a few plugins specific to SelfDesign and BB-Code Colour
265 |
266 | ## 1.0 2017-08-06
267 |
268 | * Initial Release
269 | * Debian Base
270 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 |
2 |
3 | ARG DISTRO="debian"
4 | ARG DISTRO_VARIANT="bookworm"
5 |
6 | FROM docker.io/tiredofit/nginx:${DISTRO}-${DISTRO_VARIANT}
7 | LABEL maintainer="Dave Conroy (github.com/tiredofit)"
8 |
9 | ARG DISCOURSE_VERSION
10 | ARG RUBY_VERSION
11 |
12 | ### Environment Variables
13 | ENV DISCOURSE_VERSION=${DISCOURSE_VERSION:-"v3.5.0"} \
14 | RUBY_VERSION=${RUBY_VERSION:-"3.3.9"} \
15 | RUBY_ALLOCATOR=/usr/lib/libjemalloc.so.2 \
16 | RAILS_ENV=production \
17 | RUBY_GC_MALLOC_LIMIT=90000000 \
18 | RUBY_GLOBAL_METHOD_CACHE_SIZE=131072 \
19 | PATH=/usr/local/share/pnpm:$PATH \
20 | ENABLE_NGINX=FALSE \
21 | NGINX_MODE=PROXY \
22 | NGINX_PROXY_URL=http://127.0.0.1:3000 \
23 | NGINX_ENABLE_CREATE_SAMPLE_HTML=FALSE \
24 | IMAGE_NAME="tiredofit/discourse" \
25 | IMAGE_REPO_URL="https://github.com/tiredofit/docker-discourse/"
26 |
27 | ### Install Dependencies
28 | RUN source /assets/functions/00-container && \
29 | BUILD_DEPS=" \
30 | build-essential \
31 | g++ \
32 | gcc \
33 | gettext \
34 | libbz2-dev \
35 | libfreetype6-dev \
36 | libicu-dev \
37 | libjemalloc-dev \
38 | libjpeg-dev \
39 | libssl-dev \
40 | libpq-dev \
41 | libtiff-dev \
42 | libxslt-dev \
43 | libxml2-dev \
44 | libyaml-dev \
45 | make \
46 | patch \
47 | pkg-config \
48 | zlib1g-dev \
49 | " && \
50 | set -x && \
51 | addgroup --gid 9009 --system discourse && \
52 | adduser --uid 9009 --gid 9009 --home /dev/null --gecos "Discourse" --shell /sbin/nologin --disabled-password discourse && \
53 | curl -sSL https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - && \
54 | echo "deb https://deb.nodesource.com/node_22.x nodistro main" > /etc/apt/sources.list.d/nodejs.list && \
55 | curl -ssL https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - && \
56 | echo "deb http://apt.postgresql.org/pub/repos/apt/ $(cat /etc/os-release |grep "VERSION=" | awk 'NR>1{print $1}' RS='(' FS=')')-pgdg main" > /etc/apt/sources.list.d/postgres.list && \
57 | package update && \
58 | package upgrade -y && \
59 | package install \
60 | ${BUILD_DEPS} \
61 | advancecomp \
62 | brotli \
63 | ghostscript \
64 | gifsicle \
65 | git \
66 | gsfonts \
67 | imagemagick \
68 | jhead \
69 | jpegoptim \
70 | libicu72 \
71 | libjemalloc2 \
72 | libjpeg-turbo-progs \
73 | libpq5 \
74 | libssl3 \
75 | libxml2 \
76 | nodejs \
77 | npm \
78 | optipng \
79 | pngquant \
80 | postgresql-client-17 \
81 | postgresql-contrib-17 \
82 | zlib1g \
83 | && \
84 | \
85 | mkdir -p /usr/src/oxipng && \
86 | curl -sSL https://github.com/shssoichiro/oxipng/releases/download/v7.0.0/oxipng-7.0.0-x86_64-unknown-linux-musl.tar.gz | tar xvfz - --strip 1 -C /usr/src/oxipng && \
87 | cp -R /usr/src/oxipng/oxipng /usr/bin && \
88 | \
89 | ### Setup Ruby
90 | mkdir -p /usr/src/ruby && \
91 | curl -sSL https://cache.ruby-lang.org/pub/ruby/$(echo ${RUBY_VERSION} | cut -c1-3)/ruby-${RUBY_VERSION}.tar.gz | tar xvfz - --strip 1 -C /usr/src/ruby && \
92 | cd /usr/src/ruby && \
93 | ./configure \
94 | --disable-install-rdoc \
95 | --enable-shared \
96 | --with-jemalloc \
97 | && \
98 | make -j$(getconf _NPROCESSORS_ONLN) && \
99 | make install && \
100 | \
101 | echo 'gem: --no-document' >> /usr/local/etc/gemrc && \
102 | gem update --system && \
103 | \
104 | npm install --global \
105 | svgo \
106 | terser \
107 | uglify-js \
108 | pnpm@9 \
109 | && \
110 | \
111 | clone_git_repo "https://github.com/discourse/discourse" "${DISCOURSE_VERSION}" /app && \
112 | BUNDLER_VERSION="$(grep "BUNDLED WITH" Gemfile.lock -A 1 | grep -v "BUNDLED WITH" | tr -d "[:space:]")" && \
113 | gem install bundler:"${BUNDLER_VERSION}" && \
114 | chown -R discourse:discourse /app && \
115 | bundle config build.nokogiri --use-system-libraries && \
116 | bundle config --local path ./vendor/bundle && \
117 | bundle config set --local deployment true && \
118 | bundle config set --local without development test && \
119 | bundle install --jobs $(nproc) && \
120 | cd /app && \
121 | git config --global --add safe.directory /app && \
122 | mkdir -p /usr/local/share/pnpm && \
123 | pnpm install --frozen-lockfile && \
124 | #pnpm run postinstall && \
125 | #pnpm cache clean && \
126 | pnpm cache delete && \
127 | find /app/vendor/bundle -name tmp -type d -exec rm -rf {} + && \
128 | curl -sSL https://git.io/GeoLite2-ASN.mmdb -o /app/vendor/data/GeoLite2-ASN.mmdb && \
129 | curl -sSL https://git.io/GeoLite2-City.mmdb -o /app/vendor/data/GeoLite2-City.mmdb && \
130 | sed -i "5i\ \ require 'uglifier'" /app/config/environments/production.rb && \
131 | sed -i "s|config.assets.js_compressor = :uglifier|config.assets.js_compressor = Uglifier.new(harmony: true)|g" /app/config/environments/production.rb && \
132 | ln -sf "$(which convert)" "/usr/bin/magick" && \
133 | \
134 | mkdir -p /assets/discourse/plugins && \
135 | mv /app/plugins/* /assets/discourse/plugins && \
136 | rm -rf /assets/discourse/plugins/discourse-nginx-performance-report && \
137 | ### Allow Same Origin
138 | git clone https://github.com/TheBunyip/discourse-allow-same-origin.git /assets/discourse/plugins/allow-same-origin && \
139 | ### Allow Accepted Answers on Topics
140 | git clone https://github.com/discourse/discourse-solved /assets/discourse/plugins/solved && \
141 | #### Assign Plugin
142 | git clone https://github.com/discourse/discourse-assign /assets/discourse/plugins/assign && \
143 | #### Events Plugin
144 | git clone https://github.com/angusmcleod/discourse-events /assets/discourse/plugins/events && \
145 | #### Formatting Toolbar Plugin
146 | git clone https://github.com/MonDiscourse/discourse-formatting-toolbar /assets/discourse/plugins/formatting-toolbar && \
147 | #### Mermaid
148 | git clone https://github.com/unfoldingWord/discourse-mermaid /assets/discourse/plugins/discourse-mermaid && \
149 | #### Post Voting
150 | git clone https://github.com/discourse/discourse-post-voting /assets/discourse/plugins/post-voting && \
151 | ### Push Notifications
152 | git clone https://github.com/discourse/discourse-push-notifications /assets/discourse/plugins/push && \
153 | ### Adds the ability for voting on a topic in category
154 | git clone https://github.com/discourse/discourse-voting.git /assets/discourse/plugins/voting && \
155 | chown -R discourse:discourse \
156 | /assets/discourse \
157 | /app \
158 | && \
159 | ### Cleanup
160 | package remove ${BUILD_DEPS} && \
161 | package cleanup && \
162 | rm -rf \
163 | /app/.devcontainer \
164 | /app/.editorconfig \
165 | /app/.github \
166 | /app/.*ignore \
167 | /app/.prettier* \
168 | /app/.vscode-sample \
169 | /app/bin/docker \
170 | /app/Brewfile \
171 | /app/CODEOWNERS \
172 | /app/CONTRIBUTING.md \
173 | /app/config/dev_defaults.yml \
174 | /app/config/*.sample \
175 | /app/config/logrotate.conf \
176 | /app/config/multisite.yml.production-sample \
177 | /app/config/nginx* \
178 | /app/config/puma* \
179 | /app/config/unicorn_upstart.conf \
180 | /app/deploy.rb.sample \
181 | /app/d \
182 | /app/discourse.sublime-project \
183 | /app/install-imagemagick \
184 | /app/lefthook.yml \
185 | /app/test \
186 | /app/translator.yml \
187 | /app/vendor/bundle/ruby/${RUBY_VERSION:0:3}/cache/* \
188 | /root/.bundle \
189 | /root/.config \
190 | /root/.local \
191 | /root/.npm \
192 | /root/.profile \
193 | /tmp/* \
194 | /usr/src/*
195 |
196 | WORKDIR /app
197 | EXPOSE 3000
198 | COPY install/ /
199 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # github.com/tiredofit/docker-discourse
2 |
3 | [](https://github.com/tiredofit/docker-discourse/releases/latest)
4 | [](https://github.com/tiredofit/docker-discourse/actions)
5 | [](https://hub.docker.com/r/tiredofit/discourse/)
6 | [](https://hub.docker.com/r/tiredofit/discourse/)
7 | [](https://github.com/sponsors/tiredofit)
8 | [](https://www.paypal.me/tiredofit)
9 |
10 | * * *
11 | ## About
12 |
13 | This will build a Docker Image for [Discourse](https://www.discourse.org/) - A web based discussion forum.
14 |
15 | * Unlike the official Discourse image, this is meant to be self contained without requiring a base image or use the `launcher`
16 | * Additional Plugins installed
17 | * Flexible Volatile Storage
18 |
19 |
20 | [Changelog](CHANGELOG.md)
21 |
22 | ## Maintainer
23 |
24 | - [Dave Conroy](http://github/tiredofit/)
25 |
26 | ## Table of Contents
27 |
28 | - [About](#about)
29 | - [Maintainer](#maintainer)
30 | - [Table of Contents](#table-of-contents)
31 | - [Prerequisites and Assumptions](#prerequisites-and-assumptions)
32 | - [Installation](#installation)
33 | - [Build from Source](#build-from-source)
34 | - [Prebuilt Images](#prebuilt-images)
35 | - [Configuration](#configuration)
36 | - [Quick Start](#quick-start)
37 | - [Persistent Storage](#persistent-storage)
38 | - [Base Images used](#base-images-used)
39 | - [Container Options](#container-options)
40 | - [Admin Options](#admin-options)
41 | - [Log Options](#log-options)
42 | - [Performance Options](#performance-options)
43 | - [Database Options](#database-options)
44 | - [Postgresql](#postgresql)
45 | - [Redis](#redis)
46 | - [SMTP Options](#smtp-options)
47 | - [Plugins](#plugins)
48 | - [Networking](#networking)
49 | - [Maintenance](#maintenance)
50 | - [Shell Access](#shell-access)
51 | - [Support](#support)
52 | - [Usage](#usage)
53 | - [Bugfixes](#bugfixes)
54 | - [Feature Requests](#feature-requests)
55 | - [Updates](#updates)
56 | - [License](#license)
57 |
58 | ## Prerequisites and Assumptions
59 | * Assumes you are using some sort of SSL terminating reverse proxy such as:
60 | * [Traefik](https://github.com/tiredofit/docker-traefik)
61 | * [Nginx](https://github.com/jc21/nginx-proxy-manager)
62 | * [Caddy](https://github.com/caddyserver/caddy)
63 | * Requires access to a Postgres Server
64 | * Requires access to a Redis Server
65 |
66 | ## Installation
67 |
68 | ### Build from Source
69 | Clone this repository and build the image with `docker build -t (imagename) .`
70 |
71 | ### Prebuilt Images
72 | Builds of the image are available on [Docker Hub](https://hub.docker.com/r/tiredofit/discourse)
73 |
74 | ```bash
75 | docker pull docker.io/tiredofit/discourse:(imagetag)
76 | ```
77 |
78 | Builds of the image are also available on the [Github Container Registry](https://github.com/tiredofit/docker-discourse/pkgs/container/docker-discourse)
79 |
80 | ```
81 | docker pull ghcr.io/tiredofit/docker-discourse:(imagetag)
82 | ```
83 |
84 | The following image tags are available along with their tagged release based on what's written in the [Changelog](CHANGELOG.md):
85 |
86 | | Container OS | Tag |
87 | | ------------ | --------- |
88 | | Debian | `:latest` |
89 |
90 | ## Configuration
91 |
92 | ### Quick Start
93 |
94 | - The quickest way to get started is using [docker-compose](https://docs.docker.com/compose/). See the examples folder for a working [compose.yml](examples/compose.yml) that can be modified for development or production use.
95 |
96 | - Set various [environment variables](#environment-variables) to understand the capabilities of this image.
97 | - Map [persistent storage](#data-volumes) for access to configuration and data files for backup.
98 | - Make [networking ports](#networking) available for public access if necessary
99 |
100 | **The first boot can take from 2 minutes - 5 minutes depending on your CPU to setup the proper schemas and precompile assets**
101 |
102 |
103 | ### Persistent Storage
104 |
105 | The container operates heavily from the `/app` folder, however there are a few folders that should be persistently mapped to ensure data persistence. The following directories are used for configuration and can be mapped for persistent storage.
106 |
107 | | Directory | Description |
108 | | --------------- | ----------------- |
109 | | `/data/logs` | Logfiles |
110 | | `/data/uploads` | Uploads Directory |
111 | | `/data/backups` | Backups Directory |
112 | | `/data/plugins` | Plugins Driectory |
113 |
114 | #### Base Images used
115 |
116 | This image relies on a [Debian Linux](https://hub.docker.com/r/tiredofit/debian) base image that relies on an [init system](https://github.com/just-containers/s6-overlay) for added capabilities. Outgoing SMTP capabilities are handlded via `msmtp`. Individual container performance monitoring is performed by [zabbix-agent](https://zabbix.org). Additional tools include: `bash`,`curl`,`less`,`logrotate`,`nano`.
117 |
118 | Be sure to view the following repositories to understand all the customizable options:
119 |
120 | | Image | Description |
121 | | ------------------------------------------------------ | -------------------------------------- |
122 | | [OS Base](https://github.com/tiredofit/docker-debian/) | Customized Image based on Debian Linux |
123 | | [Nginx](https://github.com/tiredofit/docker-nginx/) | Nginx webserver |
124 |
125 |
126 | #### Container Options
127 | | Parameter | Description | Default |
128 | | -------------------------- | ------------------------------------------------------------------ | ---------------------- |
129 | | `BACKUP_PATH` | Place to store in app backups | `{DATA_PATH}/backups/` |
130 | | `DELIVER_SECURE_ASSETS` | Enable serving of HTTPS assets | `FALSE` |
131 | | `ENABLE_DB_MIGRATE` | Enable DB Migrations on startup | `TRUE` |
132 | | `ENABLE_MINIPROFILER` | Enable Mini Profiler | `FALSE` |
133 | | `ENABLE_PRECOMPILE_ASSETS` | Enable Precompiling Assets on statup | `TRUE` |
134 | | `SETUP_MODE` | Automatically generate config based on these environment variables | `AUTO` |
135 | | `ENABLE_CORS` | Enable CORS | `FALSE` |
136 | | `CORS_ORIGIN` | CORS Origin | `` |
137 | | `UPLOADS_PATH` | Path to store Uploads | `{DATA_PATH}/uploads/` |
138 |
139 | #### Admin Options
140 |
141 | >> Only used on first boot
142 |
143 | | Parameter | Description | Default |
144 | | ------------- | ------------------------------------------- | --------------------- |
145 | | `ADMIN_USER` | Username for admin | `admin` |
146 | | `ADMIN_EMAIL` | Admin email address | `admin@example.com` |
147 | | `ADMIN_PASS` | Admin password - Must be over 10 characters | `tiredofit-discourse` |
148 | | `ADMIN_NAME` | Admin Name (First and Last) | `Admin User` |
149 |
150 | #### Log Options
151 | | Parameter | Description | Default |
152 | | ------------------------ | ---------------------- | ------------------- |
153 | | `LOG_FILE` | Discourse Log File | `discourse.log` |
154 | | `LOG_LEVEL` | Discourse Log Level | `info` |
155 | | `LOG_PATH` | Path to store logfiles | `{DATA_PATH}/logs/` |
156 | | `UNICORN_LOG_FILE` | Unicorn Log | `unicorn.log` |
157 | | `UNICORN_LOG_ERROR_FILE` | Unicorn Error Log | `unicorn_error.log` |
158 | | `SIDEKIQ_LOG_FILE` | SideKiq Log | `sidekiq.log` |
159 |
160 | #### Performance Options
161 | | Parameter | Description | Default |
162 | | ----------------- | ------------------- | ------- |
163 | | `UNICORN_WORKERS` | How many Workers | `8` |
164 | | `SIDEKIQ_THREADS` | Sidekiq Concurrency | `25` |
165 |
166 |
167 | #### Database Options
168 |
169 | ##### Postgresql
170 | | Parameter | Description | Default |
171 | | -------------------- | --------------------------------------------- | ------- |
172 | | `DB_POOL` | How many Database connections | `8` |
173 | | `DB_PORT` | Database Port | `5432` |
174 | | `DB_TIMEOUT` | Timeout for established connection in seconds | `5000` |
175 | | `DB_TIMEOUT_CONNECT` | Connection Timeout in Seconds | `5` |
176 | | `DB_USER` | Username of Database | |
177 | | `DB_NAME` | Database name | |
178 | | `DB_PASS` | Database Password | |
179 | | `DB_HOST` | Hostname of Database Server | |
180 |
181 | ##### Redis
182 | | Parameter | Description | Default |
183 | | ---------------------------- | ------------------------------------------- | ------- |
184 | | `REDIS_DB` | Redis Database Number | `0` |
185 | | `REDIS_ENABLE_TLS` | Enable TLS when communication to REDIS_HOST | `FALSE` |
186 | | `REDIS_PORT` | Redis Host Listening Port | `6379` |
187 | | `REDIS_SKIP_CLIENT_COMMANDS` | Skip client commands if unsupported | `FALSE` |
188 |
189 | #### SMTP Options
190 | | Parameter | Description | Default |
191 | | --------------------- | ---------------------------------------- | --------------- |
192 | | `SMTP_AUTHENTICATION` | SMTP Authentication type `plain` `login` | `plain` |
193 | | `SMTP_DOMAIN` | HELO Domain for remote SMTP Host | `example.com` |
194 | | `SMTP_HOST` | SMTP Hostname | `postfix-relay` |
195 | | `SMTP_USER` | SMTP Username | |
196 | | `SMTP_PASS` | SMTP Username | |
197 | | `SMTP_PORT` | SMTP Port | `25` |
198 | | `SMTP_START_TLS` | Enable STARTTLS on connection | `TRUE` |
199 | | `SMTP_TLS_FORCE` | Force TLS on connection | `FALSE` |
200 | | `SMTP_TLS_VERIFY` | TLS Certificate verification | `none` |
201 |
202 | #### Plugins
203 | | Parameter | Description | Default |
204 | | ---------------------------------- | ----------------------------- | ---------------------- |
205 | | `PLUGIN_PATH` | Path where plugins are stored | `{DATA_PATH}/plugins/` |
206 | | `PLUGIN_ENABLE_AUTOMATION` | | `FALSE` |
207 | | `PLUGIN_ENABLE_ASSIGN` | | `FALSE` |
208 | | `PLUGIN_ENABLE_CHAT_INTEGRATION` | | `FALSE` |
209 | | `PLUGIN_ENABLE_CHECKLIST` | | `FALSE` |
210 | | `PLUGIN_ENABLE_DETAILS` | | `TRUE` |
211 | | `PLUGIN_ENABLE_EVENTS` | | `FALSE` |
212 | | `PLUGIN_ENABLE_FOOTNOTES` | | `FALSE` |
213 | | `PLUGIN_ENABLE_FORMATTING_TOOLBAR` | | `FALSE` |
214 | | `PLUGIN_ENABLE_LAZY_VIDEOS` | | `TRUE` |
215 | | `PLUGIN_ENABLE_LOCAL_DATES` | | `TRUE` |
216 | | `PLUGIN_ENABLE_MERMAID` | | `TRUE` |
217 | | `PLUGIN_ENABLE_NARRATIVE_BOT` | | `TRUE` |
218 | | `PLUGIN_ENABLE_POLLS` | | `TRUE` |
219 | | `PLUGIN_ENABLE_POST_VOTING` | | `FALSE` |
220 | | `PLUGIN_ENABLE_PRESENCE` | | `TRUE` |
221 | | `PLUGIN_ENABLE_PUSH_NOTIFICATIONS` | | `FALSE` |
222 | | `PLUGIN_ENABLE_SAME_ORIGIN` | | `FALSE` |
223 | | `PLUGIN_ENABLE_SOLVED` | | `FALSE` |
224 | | `PLUGIN_ENABLE_SPOILER_ALERT` | | `FALSE` |
225 | | `PLUGIN_ENABLE_STYLEGUIDE` | | `TRUE` |
226 | | `PLUGIN_ENABLE_VOTING` | | `FALSE` |
227 |
228 | ### Networking
229 |
230 | The following ports are exposed.
231 |
232 | | Port | Description |
233 | | ------ | ----------- |
234 | | `3000` | Unicorn |
235 |
236 | * * *
237 | ## Maintenance
238 |
239 | ### Shell Access
240 |
241 | For debugging and maintenance purposes you may want access the containers shell.
242 |
243 | ``bash
244 | docker exec -it (whatever your container name is) bash
245 | ``
246 |
247 | Try using the command `rake --tasks`
248 |
249 | ## Support
250 |
251 | These images were built to serve a specific need in a production environment and gradually have had more functionality added based on requests from the community.
252 | ### Usage
253 | - The [Discussions board](../../discussions) is a great place for working with the community on tips and tricks of using this image.
254 | - [Sponsor me](https://tiredofit.ca/sponsor) for personalized support
255 | ### Bugfixes
256 | - Please, submit a [Bug Report](issues/new) if something isn't working as expected. I'll do my best to issue a fix in short order.
257 |
258 | ### Feature Requests
259 | - Feel free to submit a feature request, however there is no guarantee that it will be added, or at what timeline.
260 | - [Sponsor me](https://tiredofit.ca/sponsor) regarding development of features.
261 |
262 | ### Updates
263 | - Best effort to track upstream changes, More priority if I am actively using the image in a production environment.
264 | - [Sponsor me](https://tiredofit.ca/sponsor) for up to date releases.
265 |
266 | ## License
267 | MIT. See [LICENSE](LICENSE) for more details.
268 | # References
269 |
270 | * https://www.discourse.org
271 |
272 |
273 |
--------------------------------------------------------------------------------
/install/assets/functions/20-discourse:
--------------------------------------------------------------------------------
1 | #!/usr/bin/with-contenv bash
2 |
3 | bootstrap_filesystem() {
4 | if [ ! -d "${DATA_PATH}" ]; then
5 | mkdir -p "${DATA_PATH}"
6 | fi
7 | if [ $(stat -c %U "${DATA_PATH}") != "discourse" ] ; then chown discourse:discourse "${DATA_PATH}" ; fi
8 |
9 | if [ ! -d "${BACKUP_PATH}" ]; then
10 | mkdir -p "${BACKUP_PATH}"
11 | fi
12 | if [ "${BACKUP_PATH}" != "/app/public/backups/" ] ; then
13 | rm -rf /app/public/backups
14 | ln -sf "${BACKUP_PATH}" /app/public/backups
15 | fi
16 | if [ $(stat -c %U "${BACKUP_PATH}") != "discourse" ] ; then chown discourse:discourse "${BACKUP_PATH}" ; fi
17 |
18 | if [ ! -d "${LOG_PATH}" ] ; then
19 | mkdir -p "${LOG_PATH}"
20 | fi
21 | if [ $(stat -c %U "${LOG_PATH}") != "discourse" ] ; then chown -R discourse:discourse "${LOG_PATH}" ; fi
22 |
23 | if [ "${LOG_PATH}" != "/app/log/" ] ; then
24 | rm -rf /app/log
25 | ln -sf "${LOG_PATH}" /app/log
26 | fi
27 |
28 | create_logrotate discourse "${LOG_PATH}"/${LOG_FILE} discourse discourse
29 | create_logrotate discourse_unicorn "${UNICORN_LOG_PATH}"/${UNICORN_LOG_FILE} discourse discourse
30 | create_logrotate discourse_unicorn_error "${UNICORN_LOG_PATH}"/${UNICORN_LOG_ERROR_FILE} discourse discourse
31 | create_logrotate discourse_sidekiq "${LOG_PATH}"/${SIDEKIQ_LOG_FILE} discourse discourse
32 |
33 | #chown -R discourse:discourse /app "${LOG_PATH}"
34 |
35 | if [ ! -d "${PLUGIN_PATH}" ]; then
36 | mkdir -p "${PLUGIN_PATH}"
37 | fi
38 | if [ "${PLUGIN_PATH}" != "/app/plugins/" ] ; then
39 | rm -rf /app/plugins
40 | ln -sf "${PLUGIN_PATH}" /app/plugins
41 | fi
42 | if [ $(stat -c %U "${PLUGIN_PATH}") != "discourse" ] ; then chown discourse:discourse "${PLUGIN_PATH}" ; fi
43 |
44 | if [ ! -d "${UPLOADS_PATH}" ]; then
45 | mkdir -p "${UPLOADS_PATH}"
46 | fi
47 |
48 | if [ "${UPLOADS_PATH}" != "/app/public/uploads/" ] ; then
49 | rm -rf /app/public/uploads
50 | ln -sf "${UPLOADS_PATH}" /app/public/uploads
51 | fi
52 |
53 | if [ $(stat -c %U "${UPLOADS_PATH}") != "discourse" ] ; then chown discourse:discourse "${UPLOADS_PATH}" ; fi
54 |
55 | mkdir -p \
56 | /app/tmp/cache \
57 | /app/tmp/pids
58 |
59 | chown -R discourse:discourse /app/tmp
60 | }
61 |
62 | configure_discourse() {
63 | sanity_db postgres
64 | db_ready postgres
65 | sanity_db redis
66 | db_ready redis
67 |
68 | cat <> /root/.bashrc
559 | }
560 |
--------------------------------------------------------------------------------