# How to run Discourse in Apache vhost, not Nginx

**URL:** https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112
**Category:** Self-hosting
**Tags:** unsupported-install
**Created:** [November 11, 2019, 2:18pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112 "2019-11-11T14:18:14Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 11, 2019, 2:18pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/1 "2019-11-11T14:18:14Z")

</div>

Has anyone successfully setup Discourse running on an Apache vhost, instead of the default nginx?

It looks like most of the chatter around apache on these forums is about running Discourse on a host that already runs apache. In every case that I’ve seen, people just proxy apache back to nginx. To be clear: I want the docker backend container running Discourse to run the virtual host in Apache, not Nginx.

Specifically, I’m hoping to run the Discourse backend in Apache instead of Nginx to enable mod\_security. Setting up Nginx with mod\_security requires compiling Nginx from source–a complexity I’d like to avoid.

My current production server is already running several sites (wordpress, mediawiki, etc). We use Nginx to terminate https and do some basic DOS rate limiting → varnish cache → apache backend with mod\_security. If possible, I’d like to keep this architecture for Discourse – with the backend Discourse docker container running Apache with mod\_security, not Nginx.

Has anyone successfully setup Discourse to run in Apache?

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 11, 2019, 2:36pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/2 "2019-11-11T14:36:57Z")

</div>

Sorry, I’m new to docker. I’m really struggling to find how the ‘/etc/nginx/conf.d/discourse.conf’ file is even put in-place on the docker container. Can someone elucidate the steps for how that file is generated and put in-place on the container by the ‘./launcher’ script?

> [@maltfield](#):
>
> Setting up Nginx with mod\_security requires compiling Nginx from source–a complexity I’d like to avoid.

EDIT: wait, is nginx _already_ being compiled from source by Discourse?

- [discourse\_docker/image/base/install-nginx at 416467f6ead98f82342e8a926dc6e06f36dfbd56 · discourse/discourse\_docker · GitHub](https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/image/base/install-nginx)

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [November 11, 2019, 2:51pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/3 "2019-11-11T14:51:35Z")

</div>

> [@maltfield](#):
>
> Has anyone successfully setup Discourse to run in Apache?

No they have not. Discourse is rather tightly connected with nginx. It will be difficult if impossible to replace it with apache. And since you’ll be the only person doing that, no one else will care when it breaks.

Just use the docker container that everyone on the planet uses and stick apache in front of it if you think that’ll help security somehow.

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [November 11, 2019, 2:53pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/4 "2019-11-11T14:53:55Z")

</div>

> [@maltfield](#):
>
> EDIT: wait, is nginx _already_ being compiled from source by Discourse?

It does look like it.

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 11, 2019, 3:09pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/5 "2019-11-11T15:09:59Z")

</div>

> [@maltfield](#):
>
> Sorry, I’m new to docker. I’m really struggling to find how the ‘/etc/nginx/conf.d/discourse.conf’ file is even put in-place on the docker container. Can someone elucidate the steps for how that file is generated and put in-place on the container by the ‘./launcher’ script?

So it looks like `/etc/nginx/conf.d/discourse.conf` is generated on the container by the template file [/var/docker/templates/web.template.yml](https://github.com/discourse/discourse_docker/blob/7440820f554b3db7d8ab5c2970debe64b3a70d57/templates/web.template.yml#L107) – which copies it in-place from `$home/config/nginx.sample.conf`, and then makes changes with the `replace` yaml blocks (which is further updated in subsequent templates, such as [templates/web.socketed.template.yml](https://github.com/discourse/discourse_docker/blob/ceffc4433e1bd6fcbd101f2427e17232fc99ab14/templates/web.socketed.template.yml#L14)).

I was assuming that the `nginx.sample.conf` file was just installed in-place by nginx when compiling from source in [image/base/install-nginx](https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/image/base/install-nginx), but the only `nginx.sample.conf` file I found on the container (`/var/www/discourse/config/nginx.sample.conf`) already had discourse-specific directives in it.

Where does `nginx.sample.conf` come from?

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 11, 2019, 3:15pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/6 "2019-11-11T15:15:42Z")

</div>

> [@pfaffman](#):
>
> No they have not. Discourse is rather tightly connected with nginx. It will be difficult if impossible to replace it with apache. And since you’ll be the only person doing that, no one else will care when it breaks.
> 
> Just use the docker container that everyone on the planet uses and stick apache in front of it if you think that’ll help security somehow.

> [@pfaffman](#):
>
> > EDIT: wait, is nginx _already_ being compiled from source by Discourse?
> 
> It does look like it.

I’d rather not have nginx → varnish → apache → nginx 🙂

To be clear: do you think it would be safer for me to update the ‘[image/base/install-nginx](https://github.com/discourse/discourse_docker/blob/ceffc4433e1bd6fcbd101f2427e17232fc99ab14/image/base/install-nginx)’ script to compile nginx on the Discourse docker container with mod\_security support rather than update the container to run the Discourse vhost behind apache (as opposed to Nginx)? If so, what are the risks of me modifying the `install-nginx` script? How could it break my Discourse install in the future?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [November 11, 2019, 3:29pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/7 "2019-11-11T15:29:07Z")

</div>

PSA: Everything you are proposing to do, while technically _feasible_ is completely unsupported. We can’t reasonably support every possible combination people come up with to serve Discourse on the web. So the support here on this forums are restricted to installs following the [discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/master/docs/INSTALL-cloud.md) guide.

> [@maltfield](#):
>
> Where does `nginx.sample.conf` come from?

[discourse/config/nginx.sample.conf at main · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/master/config/nginx.sample.conf)

> [@maltfield](#):
>
> If so, what are the risks of me modifying the `install-nginx` script? How could it break my Discourse install in the future?

It will, _eventually_, break in many ways. You will be on the hook on merging with upstream changes continually and handling your fork forever.

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 11, 2019, 3:37pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/8 "2019-11-11T15:37:00Z")

</div>

> [@Falco](#):
>
> > Where does `nginx.sample.conf` come from?
> 
> [discourse/nginx.sample.conf at master · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/master/config/nginx.sample.conf)

Perfect, thank you! Wow, it’s a totally different repo. How does the container get that file from the _other_ repo? Is it here?

- [discourse\_docker/image/base/Dockerfile at ceffc4433e1bd6fcbd101f2427e17232fc99ab14 · discourse/discourse\_docker · GitHub](https://github.com/discourse/discourse_docker/blob/ceffc4433e1bd6fcbd101f2427e17232fc99ab14/image/base/Dockerfile#L135)

And what is [$home](https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/templates/web.template.yml#L109)?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [November 11, 2019, 3:42pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/9 "2019-11-11T15:42:35Z")

</div>

You can read the source code to find all that and more at [discourse\_docker/image/base/Dockerfile at master · discourse/discourse\_docker · GitHub](https://github.com/discourse/discourse_docker/blob/master/image/base/Dockerfile)

---

<div class="post-metadata">

### Author: ![ledimeo](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/ledimeo/32/157962_2.png) [@ledimeo](https://meta.discourse.org/u/ledimeo)
#### Post date: [November 11, 2019, 7:02pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/10 "2019-11-11T19:02:08Z")

</div>

I resolved setting app.yml (Discouse) like so:  
` expose:`  
` - "2045:80" # http`  
` - "8443:443" # https`

.. and my vhost like so:  
`<VirtualHost *myhostIP*:443>`  
` ServerName forum.domain.org`  
` ServerAlias forum.domain.org`  
…  
` ProxyAddHeaders Off`  
` ProxyPass / "http://localhost:2045/"`  
` ProxyPassReverse / "http://localhost:2045/"`  
`</VirtualHost>`

I hope I didn’t misunderstand your question 😊

---

<div class="post-metadata">

### Author: ![lucasbasquerotto](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/lucasbasquerotto/32/133376_2.png) [@lucasbasquerotto](https://meta.discourse.org/u/lucasbasquerotto)
#### Post date: [November 12, 2019, 1:22am UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/11 "2019-11-12T01:22:03Z")

</div>

@ledimeo That’s what @pfaffman suggested, and what I think would be better in this case, to not break things badly in the future when new versions are released. But it seems that he already uses another nginx at the front as a reverse proxy and don’t want:

> [@maltfield](#):
>
> nginx → varnish → apache → nginx

That said, I think that proxing apache to nginx (even if it would end up with those 4 layers) would at least be more maintainable than trying to change the way discourse works in the official installation.

---

<div class="post-metadata">

### Author: ![supermathie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/supermathie/32/507518_2.png) [@supermathie](https://meta.discourse.org/u/supermathie)
#### Post date: [November 12, 2019, 2:21am UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/12 "2019-11-12T02:21:26Z")

</div>

> [@maltfield](#):
>
> I’d rather not have nginx → varnish → apache → nginx 🙂

For this purpose, you should mostly pretend that nginx is inside the “black box” of the docker container and not concern yourself with it.

So: nginx → varnish → apache → Discourse (comprising nginx and unicorn)

(except for configuring it to trust upstream proxy IPs)

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 12, 2019, 6:37am UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/13 "2019-11-12T06:37:19Z")

</div>

So adding apache as a proxy to the Discourse nginx is definitely an option.

I agree that a pro would be making future upgrades easier, and that’s an important point.

But adding another hop to the architecture would not only make debugging issues in the future more complex – I also have concerns about Apache’s performance as a proxy to a web application that uses long polling, as pointed out by @sam in this post from 2016.

- [Configure Apache proxy with Let's Encrypt](https://meta.discourse.org/t/howto-setup-discourse-with-lets-encrypt-and-apache-ssl/46139/2)

I generally prefer nginx to apache, except when it comes to mod\_security. It would be fantastic if the OS repos included packages to enable mod\_security in nginx like they do for Apache, but currently enabling mod\_security on nginx requires compiling nginx from source in both RHEL/Cent and Debian. And I avoid depending on packages compiled from source on production like the plague..

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 12, 2019, 11:39am UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/14 "2019-11-12T11:39:18Z")

</div>

related: I’ve been poking around with the `install-nginx` script, and I found a minor logic error: the cleanup line that’s _supposed_ to delete the nginx source from `/tmp/` actually doesn’t do anything.

There is no `/tmp/nginx/` directory: it’s `/tmp/nginx-$VERSION/` (at the moment it’s `/tmp/nginx-1.17.4/` and there’s also the tarball `/tmp/nginx-1.17.4.tar.gz`).

- [discourse\_docker/image/base/install-nginx at 416467f6ead98f82342e8a926dc6e06f36dfbd56 · discourse/discourse\_docker · GitHub](https://github.com/discourse/discourse_docker/blob/416467f6ead98f82342e8a926dc6e06f36dfbd56/image/base/install-nginx#L41)

I think you mean this instead:

```plaintext
rm -fr /tmp/nginx-${VERSION}*

```

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 12, 2019, 3:10pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/15 "2019-11-12T15:10:04Z")

</div>

Unfortunately, my updated `/var/discourse/image/base/install-nginx` script does not appear to be executed when I run a `/var/discourse/launcher destroy app && /var/discourse/launcher/rebuild app`.

Is there any reason this `rebuild` command would not re-execute the updated `install-nginx` script?

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [November 12, 2019, 3:11pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/16 "2019-11-12T15:11:15Z")

</div>

How are you amending the script after the rebuild? With a hook?

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 12, 2019, 3:12pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/17 "2019-11-12T15:12:08Z")

</div>

vim /var/discourse/image/base/install-nginx

---

<div class="post-metadata">

### Author: ![Stephen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/stephen/32/95011_2.png) [@Stephen](https://meta.discourse.org/u/Stephen)
#### Post date: [November 12, 2019, 3:13pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/18 "2019-11-12T15:13:09Z")

</div>

After a rebuild can you still see your changes? Editing files in the image directly like that won’t work.

You need to use hooks to amend the file from your app.yml

Have you worked with docker before?

---

<div class="post-metadata">

### Author: ![Falco](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/falco/32/179432_2.png) [@Falco](https://meta.discourse.org/u/Falco)
#### Post date: [November 12, 2019, 3:13pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/19 "2019-11-12T15:13:40Z")

</div>

If you aren’t familiar with Docker this is going to be a hard path…

`discourse_docker` contains the source code for our base docker image that lives in the public Docker registry, and that will never be run locally and the whole reason is having a reusable image.

---

<div class="post-metadata">

### Author: ![maltfield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/maltfield/32/160669_2.png) [@maltfield](https://meta.discourse.org/u/maltfield)
#### Post date: [November 12, 2019, 3:16pm UTC](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112/20 "2019-11-12T15:16:43Z")

</div>

ok. Well, I lied about vim for simplicity. I’m actually running these commands to idempotently & robustly update the script

```plaintext
cd /var/discourse/image/base
cp install-nginx install-nginx.`date "+%Y%m%d_%H%M%S"`.orig

# add a block to checkout the the modsecurity nginx module just before downloading the nginx source
grep 'ModSecurity' install-nginx || sed -i 's%\(curl.*nginx\.org/download.*\)%# mod_security --maltfield\napt-get install -y libmodsecurity-dev modsecurity-crs\ncd /tmp\ngit clone --depth 1 https://github.com/SpiderLabs/ModSecurity-nginx.git\n\n\1%' install-nginx

# update the configure line to include the ModSecurity module checked-out above
sed -i '/ModSecurity/! s%^[^#]*./configure \(.*nginx.*\)%#./configure \1\n./configure \1 --add-module=/tmp/ModSecurity-nginx%' install-nginx

# add a line to cleanup section
grep 'rm -fr /tmp/ModSecurity-nginx' install-nginx || sed -i 's%\(rm -fr.*/tmp/nginx.*\)%rm -fr /tmp/ModSecurity-nginx\n\1%' install-nginx

```

Where should I put these commands so that the _actual_ `install-nginx` script used by the container on bootstrap is modified?

[Next page](https://meta.discourse.org/t/how-to-run-discourse-in-apache-vhost-not-nginx/133112.md?page=2)
