# Does Discourse container use unattended-upgrades?

**URL:** https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296
**Category:** Self-hosting
**Tags:** hosting
**Created:** [December 17, 2019, 9:47am UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296 "2019-12-17T09:47:45Z")
**Posts on this page:** 10
**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: [December 17, 2019, 9:47am UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/1 "2019-12-17T09:47:46Z")

</div>

Does the Discourse docker container use `unattended-upgrades` to keep its Debian-backed docker container’s OS packages up-to-date?

I noticed that the `INSTALL-cloud.md` guide recommends installing unattended-upgrades on the docker host machine, so I got wondering about the state of the OS packages _inside_ the docker container. I searched both the `discourse` and `discourse_docker` repos on github, but the only reference I could find to `unattended-upgrades` was the same install doc

- [discourse/docs/INSTALL-cloud.md at 215f6d97e5e3fc7e4451b0cc20ec73631e28243e · discourse/discourse · GitHub](https://github.com/discourse/discourse/blob/215f6d97e5e3fc7e4451b0cc20ec73631e28243e/docs/INSTALL-cloud.md#post-install-maintenance)

But what about the Discourse docker container? Does _it_ use `unattended-upgrades`?

---

<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: [December 24, 2019, 6:03pm UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/3 "2019-12-24T18:03:17Z")

</div>

After further digging, it appears that `unattended-upgrades` is **installed but _not_ running** on the Discourse docker container.

First, it’s clearly installed

```plaintext
root@osestaging1-discourse-ose:/var/www/discourse# dpkg -l | grep -i unatt
ii unattended-upgrades 1.11.2 all automatic installation of security upgrades
root@osestaging1-discourse-ose:/var/www/discourse# 

```

Further inspecting of the `unattended-upgrades` package’s config per the relevant Debian wiki article shows

- [I Challenge Thee](https://wiki.debian.org/UnattendedUpgrades)

The default config looks sane

```plaintext
root@osestaging1-discourse-ose:/var/www/discourse# grep -ir 'origin=' /etc/apt/apt.conf.d/50unattended-upgrades 
// "origin=Debian,codename=${distro_codename}-updates";
// "origin=Debian,codename=${distro_codename}-proposed-updates";
		"origin=Debian,codename=${distro_codename},label=Debian";
		"origin=Debian,codename=${distro_codename},label=Debian-Security";
root@osestaging1-discourse-ose:/var/www/discourse# cat /etc/apt/apt.conf.d/20auto-upgrades 
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
root@osestaging1-discourse-ose:/var/www/discourse# 

```

But checking the logs show the last entry was 1 month ago

```plaintext
root@osestaging1-discourse-ose:/var/www/discourse# tail -f /var/log/unattended-upgrades/unattended-upgrades*.log
==> /var/log/unattended-upgrades/unattended-upgrades-dpkg.log <==
Log started: 2019-11-17 12:34:54
(Reading database ... 44559 files and directories currently installed.)
Removing freetype2-doc (2.9.1-3+deb10u1) ...
Log ended: 2019-11-17 12:34:54

Log started: 2019-11-17 12:34:56
(Reading database ... 44389 files and directories currently installed.)
Removing libjs-jquery (3.3.1~dfsg-3) ...
Log ended: 2019-11-17 12:34:57

==> /var/log/unattended-upgrades/unattended-upgrades.log <==
2019-11-26 16:37:47,549 INFO Initial blacklist : 
2019-11-26 16:37:47,550 INFO Initial whitelist: 
2019-11-26 16:37:47,551 INFO Starting unattended upgrades script
2019-11-26 16:37:47,552 INFO Allowed origins are: origin=Debian,codename=buster,label=Debian, origin=Debian,codename=buster,label=Debian-Security
2019-11-26 16:37:50,811 INFO Checking if system is running on battery is skipped. Please install powermgmt-base package to check power status and skip installing updates when the system is running on battery.
2019-11-26 16:37:50,814 INFO Initial blacklist : 
2019-11-26 16:37:50,815 INFO Initial whitelist: 
2019-11-26 16:37:50,815 INFO Starting unattended upgrades script
2019-11-26 16:37:50,815 INFO Allowed origins are: origin=Debian,codename=buster,label=Debian, origin=Debian,codename=buster,label=Debian-Security
2019-11-26 16:37:53,119 INFO No packages found that can be upgraded unattended and no pending auto-removals
^C
root@osestaging1-discourse-ose:/var/www/discourse# 

```

…Even though the default systemd timers defined for `unattended-upgrades` are set to run at least once per day

```plaintext
root@osestaging1-discourse-ose:/var/www/discourse# cat /lib/systemd/system/apt-daily.timer
[Unit]
Description=Daily apt download activities

[Timer]
OnCalendar=*-*-* 6,18:00
RandomizedDelaySec=12h
Persistent=true

[Install]
WantedBy=timers.target
root@osestaging1-discourse-ose:/var/www/discourse# cat /etc/systemd/system/apt-daily.timer.d/override.conf
cat: /etc/systemd/system/apt-daily.timer.d/override.conf: No such file or directory
root@osestaging1-discourse-ose:/var/www/discourse# cat /lib/systemd/system/apt-daily-upgrade.timer
[Unit]
Description=Daily apt upgrade and clean activities
After=apt-daily.timer

[Timer]
OnCalendar=*-*-* 6:00
RandomizedDelaySec=60m
Persistent=true

[Install]
WantedBy=timers.target
root@osestaging1-discourse-ose:/var/www/discourse# cat /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf
cat: /etc/systemd/system/apt-daily-upgrade.timer.d/override.conf: No such file or directory
root@osestaging1-discourse-ose:/var/www/discourse# 

```

But, indeed, those timers are disabled.

```plaintext
root@osestaging1-discourse-ose:/var/www/discourse# sudo systemctl status apt-daily.timer
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
root@osestaging1-discourse-ose:/var/www/discourse# sudo systemctl status apt-daily-upgrade.timer
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
root@osestaging1-discourse-ose:/var/www/discourse# 

```

This is further confirmed by manually running `unattended-upgrades`, which just happened to require an update to two git-related packages

```plaintext
root@osestaging1-discourse-ose:/var/www/discourse# sudo unattended-upgrade -d
...
Checking: git ([<Origin component:'main' archive:'stable' origin:'Debian' label:'Debian-Security' site:'security.debian.org' isTrusted:True>])
Checking: git-man ([<Origin component:'main' archive:'stable' origin:'Debian' label:'Debian-Security' site:'security.debian.org' isTrusted:True>])
pkgs that look like they should be upgraded: git   
git-man
...
All upgrades installed
InstCount=0 DelCount=0 BrokenCount=0
Extracting content from /var/log/unattended-upgrades/unattended-upgrades-dpkg.log since 2019-12-24 17:32:55
root@osestaging1-discourse-ose:/var/www/discourse# 

```

The git version that was updated in the above `unattended-upgrades` run was `git (1:2.20.1-2+deb10u1)`. I ran this test today (2019-12-24), but the security upgrade had been available to Debian Buster (the OS on which the Discourse docker image is built) for two weeks (since 2019-12-10)!

This is actually a pretty serious upgrade that fixes several vulnerabilities, including two vectors for Remote Code Execution. More info is available at the Debian Security Advisory 4581-1

- [I Challenge Thee](https://www.debian.org/security/2019/dsa-4581)

But git is just an example I happened to stumble on. It’s extremely concerning if the Discourse docker container doesn’t (by default) actually apply security-related patches to its OS.

Is this a bug? Or was this an intentional decision by the Discourse team? Or is this just the default in-lieu of a feature request to enable `unattended-upgrades` on the Discourse docker container?

---

<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: [December 24, 2019, 6:07pm UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/4 "2019-12-24T18:07:26Z")

</div>

My guess is that it’s off on purpose as it might break something, and the image itself is updated when a serious security issue is found.

You can enable it if you want, just enter the container.

---

<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: [December 24, 2019, 6:12pm UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/5 "2019-12-24T18:12:10Z")

</div>

Actually, I just realized that Discourse’s docker image is setup to use `runit`. Is `systemd` even installed on the Discourse docker container?

My guess is not having `systemd` installed is what’s breaking `unattended-upgrades`.

---

<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: [December 24, 2019, 7:53pm UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/6 "2019-12-24T19:53:52Z")

</div>

Sounds right. Some people really don’t like systemd. So you can either trust that the base container gets updated regularly by people running a large team of professionals that depends on it, or you can do it some other way yourself and hope that you don’t break anything.

---

<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: [December 24, 2019, 9:06pm UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/7 "2019-12-24T21:06:40Z")

</div>

> [@maltfield](#):
>
> But what about the Discourse docker container? Does _it_ use `unattended-upgrades` ?

No it doesn’t and we don’t plan to make it use. The recommendation is to keep your host OS updated with the latest security patches.

---

<div class="post-metadata">

### Author: ![riking](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/riking/32/170938_2.png) [@riking](https://meta.discourse.org/u/riking)
#### Post date: [December 24, 2019, 11:22pm UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/8 "2019-12-24T23:22:01Z")

</div>

> [@pfaffman](#):
>
> So you can either trust that the base container gets updated regularly by people running a large team of professionals that depends on it,

Which, for the record, it is.

---

<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: [April 23, 2020, 10:26am UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/9 "2020-04-23T10:26:11Z")

</div>

fyi, I fixed the broken `unattended-upgrades` install (which doesn’t actually run without systemd on the Discourse docker container) by triggering it to run via a cron job.

I created the following yaml template file in my `/var/discourse/templates/` dir to create the necessary cron job (note that it also has a command to [fix a bug with cron](https://meta.discourse.org/t/cron-in-docker-container-cannot-make-remove-an-entry-for-the-specified-session/148969/2) shipped in the Debian-based Discourse docker image):

```plaintext
cat << EOF > /var/discourse/templates/unattended-upgrades.template.yml
run:
  - file:
     path: /etc/cron.d/unattended-upgrades
     contents: |+
        ################################################################################
        # File: /etc/cron.d/unattended-upgrades
        # Version: 0.2
        # Purpose: run unattended-upgrades in lieu of systemd. For more info see
        # * https://wiki.opensourceecology.org/wiki/Discourse
        # * https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/3
        # Author: Michael Altfield <michael@opensourceecology.org>
        # Created: 2020-03-23
        # Updated: 2020-04-23
        ################################################################################
        20 04 * * * root /usr/bin/nice /usr/bin/unattended-upgrades --debug
        

  - exec: /bin/echo -e "\n" >> /etc/cron.d/unattended-upgrades
  # fix the Docker cron bug https://stackoverflow.com/questions/43323754/cannot-make-remove-an-entry-for-the-specified-session-cron
  - exec: /bin/sed --in-place=.\`date "+%Y%m%d_%H%M%S"\` 's%^\([^#]*\)\(session\s\+required\s\+pam_loginuid\.so\)$%\1#\2%' /etc/pam.d/cron
EOF

```

To enable the above template file, you have to add it to your list of `templates` in your app’s yaml file. For example,

```plaintext
[root@osestaging1 discourse]# head -n20 /var/discourse/containers/app.yml
## this is the all-in-one, standalone Discourse Docker container template
##
## After making changes to this file, you MUST rebuild
## /var/discourse/launcher rebuild app
##
## BE *VERY* CAREFUL WHEN EDITING!
## YAML FILES ARE SUPER SUPER SENSITIVE TO MISTAKES IN WHITESPACE OR ALIGNMENT!
## visit http://www.yamllint.com/ to validate this file as needed

templates:
  - "templates/unattended-upgrades.template.yml"
  - "templates/postgres.template.yml"
  - "templates/redis.template.yml"
  - "templates/web.template.yml"
# - "templates/web.socketed.template.yml"
  - "templates/web.modsecurity.template.yml"
  - "templates/web.ratelimited.template.yml"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
  #- "templates/web.ssl.template.yml"
  #- "templates/web.letsencrypt.ssl.template.yml"
[root@osestaging1 discourse]# 

```

---

<div class="post-metadata">

### Author: ![tormod](https://avatars.discourse-cdn.com/v4/letter/t/aca169/32.png) [@tormod](https://meta.discourse.org/u/tormod)
#### Post date: [May 23, 2020, 3:36pm UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/10 "2020-05-23T15:36:29Z")

</div>

It seems that it is enabled on a fresh Discourse docker image (running Debian 10). It is launched through runit → cron → /etc/cron.daily/apt-compat → /usr/lib/apt/apt.systemd.daily

It was also running on a one-year-old Ubuntu 16-based docker image (based on discourse/base:2.0.20190321-0122), I am pretty sure without any customization.

---

<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: [September 22, 2020, 7:46am UTC](https://meta.discourse.org/t/does-discourse-container-use-unattended-upgrades/136296/11 "2020-09-22T07:46:00Z")

</div>

> [@tormod](#):
>
> It is launched through runit → cron → /etc/cron.daily/apt-compat → /usr/lib/apt/apt.systemd.daily

systemd isn’t installed, so it never actually runs.
