<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lakshman Anumolu</title>
    <description>The latest articles on DEV Community by Lakshman Anumolu (@acrlakshman).</description>
    <link>https://dev.to/acrlakshman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F417694%2F74f74999-eda7-4ef0-bc16-c4a793695148.jpeg</url>
      <title>DEV Community: Lakshman Anumolu</title>
      <link>https://dev.to/acrlakshman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/acrlakshman"/>
    <language>en</language>
    <item>
      <title>Deploy mattermost to a docker swarm with secrets</title>
      <dc:creator>Lakshman Anumolu</dc:creator>
      <pubDate>Fri, 10 Jul 2020 13:59:14 +0000</pubDate>
      <link>https://dev.to/acrlakshman/deploy-mattermost-to-a-docker-swarm-with-secrets-2101</link>
      <guid>https://dev.to/acrlakshman/deploy-mattermost-to-a-docker-swarm-with-secrets-2101</guid>
      <description>&lt;p&gt;I deployed &lt;a href="https://mattermost.com/"&gt;mattermost&lt;/a&gt; to a &lt;a href="https://docs.docker.com/engine/swarm/"&gt;docker swarm&lt;/a&gt; using &lt;a href="https://docs.docker.com/engine/swarm/secrets/"&gt;docker secrets&lt;/a&gt;, while the process was smooth, I had to make some modifications to original &lt;a href="https://github.com/acrlakshman/mattermost-docker"&gt;mattermost-docker&lt;/a&gt; source to achieve desired goal. This article describes the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy mattermost on a single node swarm (e.g. on digitalocean) and publish under a subdomain.&lt;/li&gt;
&lt;li&gt;Pass secrets to the stack.&lt;/li&gt;
&lt;li&gt;Enable plugins upload.&lt;/li&gt;
&lt;li&gt;Configure mattermost for email notifications using gmail's smtp server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before presenting details, here are the final products:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repository: &lt;a href="https://github.com/acrlakshman/mattermost-docker"&gt;https://github.com/acrlakshman/mattermost-docker&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Self hosted mattermost: &lt;a href="https://mattermost.lakshmananumolu.com/public"&gt;https://mattermost.lakshmananumolu.com/public&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;username: &lt;span class="nb"&gt;test
&lt;/span&gt;password: test1234
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Docker images:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; * &lt;a href="https://hub.docker.com/repository/docker/acrlakshman/mattermost-team"&gt;https://hub.docker.com/repository/docker/acrlakshman/mattermost-team&lt;/a&gt;&lt;br&gt;
 * &lt;a href="https://hub.docker.com/repository/docker/acrlakshman/mattermost-prod-db"&gt;https://hub.docker.com/repository/docker/acrlakshman/mattermost-prod-db&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Deploy mattermost onto a single node swarm
&lt;/h2&gt;

&lt;p&gt;I found few articles that describe &lt;a href="https://medium.com/mattermost/mattermost-5-15-76cf34f87d05"&gt;deploying mattermost in kubernetes&lt;/a&gt;, &lt;a href="https://medium.com/mattermost/install-mattermost-with-a-1-click-app-on-the-digitalocean-marketplace-e8ccd7be2e0e"&gt;single click app on digitalocean&lt;/a&gt;. While there are other ways to install, I wanted to deploy it myself on my digitalocean server space, which helps me learn few things along the way and may be contribute to the project. Here are the steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ssh to server&lt;/span&gt;
ssh &amp;lt;user&amp;gt;@&amp;lt;public ip&amp;gt;
&lt;span class="c"&gt;# Prepare swarm&lt;/span&gt;
docker swarm init &lt;span class="nt"&gt;--advertise-addr&lt;/span&gt; &amp;lt;public-ip&amp;gt;
&lt;span class="c"&gt;# Clone the repository to your desired location&lt;/span&gt;
git clone https://github.com/acrlakshman/mattermost-docker
&lt;span class="c"&gt;# Prepare volumes&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;mattermost-docker
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; volumes/app/mattermost/logs
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; volumes/app/mattermost/data
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; volumes/app/mattermost/config
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; volumes/app/mattermost/plugins
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; volumes/app/mattermost/client_plugins
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 2000:2000 ./volumes/app/mattermost
&lt;span class="c"&gt;# create secrets to store database (postgresql) details&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"database_user"&lt;/span&gt; | docker secret create mm_db_user -                       &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"database_password"&lt;/span&gt; | docker secret create mm_db_password -                       &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"database_name"&lt;/span&gt; | docker secret create mm_db_name -
&lt;span class="c"&gt;# deploy stack&lt;/span&gt;
docker stack deploy &lt;span class="nt"&gt;-c&lt;/span&gt; docker-stack.yml mm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We now have a stack &lt;em&gt;&lt;strong&gt;mm&lt;/strong&gt;&lt;/em&gt; created that manages three services, &lt;em&gt;mm_app&lt;/em&gt;, &lt;em&gt;mm_db&lt;/em&gt;, &lt;em&gt;mm_visualizer&lt;/em&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;watch docker service ls&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6bcEr83e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8imdbnoyr6n1qxnasgn4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6bcEr83e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8imdbnoyr6n1qxnasgn4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While I have not presented the technical details above, some modifications are made to &lt;a href="https://github.com/mattermost/mattermost-docker"&gt;original mattermost-docker&lt;/a&gt; in order to use credentials via docker secrets. &lt;em&gt;entrypoint.sh&lt;/em&gt; scripts for both &lt;em&gt;mattermost-docker/app/&lt;/em&gt; and &lt;em&gt;mattermost-docker/db/&lt;/em&gt; are changed and are custom built to use in this stack. A slightly modified version of &lt;a href="https://medium.com/@basi"&gt;Basilio Vera&lt;/a&gt;'s script is used in this work which helped in &lt;a href="https://medium.com/@basi/docker-environment-variables-expanded-from-secrets-8fa70617b3bc"&gt;expanding secrets and assign them to environment variables&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Point subdomain to mattermost instance
&lt;/h2&gt;

&lt;p&gt;Webserver: nginx&lt;br&gt;
CDN: &lt;a href="https://www.cloudflare.com/"&gt;cloudflare&lt;/a&gt;&lt;br&gt;
OS: Debian&lt;/p&gt;

&lt;p&gt;Mattermost app now runs in docker and listens to host port at &lt;em&gt;7070&lt;/em&gt;. I have used nginx as a proxy webserver on Debian. Here are the details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /etc/nginx/sites-available

&lt;span class="c"&gt;# Create a file with &amp;lt;sub.domain.com&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;# In my case this is mattermost.lakshmananumolu.com&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;vim &amp;lt;sub.domain.com&amp;gt;

&lt;span class="c"&gt;# My &amp;lt;sub.domain.com&amp;gt; has the following&lt;/span&gt;
server &lt;span class="o"&gt;{&lt;/span&gt;
  listen 80&lt;span class="p"&gt;;&lt;/span&gt;
  listen &lt;span class="o"&gt;[&lt;/span&gt;::]:80&lt;span class="p"&gt;;&lt;/span&gt;
  server_name &amp;lt;sub.domain.com&amp;gt; www.&amp;lt;sub.domain.com&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;301 https://&amp;lt;sub.domain.com&amp;gt;&lt;span class="nv"&gt;$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

map &lt;span class="nv"&gt;$http_x_forwarded_proto&lt;/span&gt; &lt;span class="nv"&gt;$proxy_x_forwarded_proto&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  default &lt;span class="nv"&gt;$http_x_forwarded_proto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="s1"&gt;''&lt;/span&gt;      &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

server &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;# SSL configuration&lt;/span&gt;
  listen 443&lt;span class="p"&gt;;&lt;/span&gt;
  listen &lt;span class="o"&gt;[&lt;/span&gt;::]:443&lt;span class="p"&gt;;&lt;/span&gt;

  ssl     on&lt;span class="p"&gt;;&lt;/span&gt;
  ssl_certificate &amp;lt;path-to&amp;gt;/&amp;lt;domain.com&amp;gt;.pem&lt;span class="p"&gt;;&lt;/span&gt;
  ssl_certificate_key &amp;lt;path-to&amp;gt;/&amp;lt;domain.com&amp;gt;.key&lt;span class="p"&gt;;&lt;/span&gt;
  ssl_session_timeout 5m&lt;span class="p"&gt;;&lt;/span&gt;
  ssl_prefer_server_ciphers on&lt;span class="p"&gt;;&lt;/span&gt;

  server_name &amp;lt;sub.domain.com&amp;gt; www.&amp;lt;sub.domain.com&amp;gt;&lt;span class="p"&gt;;&lt;/span&gt;
  include hhvm.conf&lt;span class="p"&gt;;&lt;/span&gt;

  location ~ /api/v[0-9]+/&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;users&lt;/span&gt;/&lt;span class="o"&gt;)&lt;/span&gt;?websocket&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
    proxy_set_header Upgrade &lt;span class="nv"&gt;$http_upgrade&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Forwarded-Ssl on&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header Connection &lt;span class="s2"&gt;"upgrade"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    client_max_body_size 50M&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header Host &lt;span class="nv"&gt;$http_host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Real-IP &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Forwarded-For &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Forwarded-Proto &lt;span class="nv"&gt;$proxy_x_forwarded_proto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Frame-Options SAMEORIGIN&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_buffers 256 16k&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_buffer_size 16k&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_read_timeout 600s&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_pass http://127.0.0.1:7070&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  location / &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;# First attempt to serve request as file, then&lt;/span&gt;
    &lt;span class="c"&gt;# as directory, then fall back to displaying a 404.&lt;/span&gt;
    &lt;span class="nb"&gt;gzip &lt;/span&gt;on&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Forwarded-Ssl on&lt;span class="p"&gt;;&lt;/span&gt;

    client_max_body_size 50M&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header Connection &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header Host &lt;span class="nv"&gt;$http_host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Real-IP &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Forwarded-For &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_set_header X-Frame-Options SAMEORIGIN&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_buffers 256 16k&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_buffer_size 16k&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_read_timeout 600s&lt;span class="p"&gt;;&lt;/span&gt;
    proxy_pass http://127.0.0.1:7070&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# enable this site.&lt;/span&gt;
&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/&amp;lt;sub.domain.com&amp;gt; /etc/nginx/sites-enabled/&amp;lt;sub.domain.com&amp;gt;

&lt;span class="c"&gt;# restart nginx.&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;service nginx restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I used &lt;a href="https://www.cloudflare.com/"&gt;cloudflare&lt;/a&gt; as CDN, from where I obtained &lt;em&gt;ssl certificate&lt;/em&gt; and &lt;em&gt;key&lt;/em&gt;, that are used in nginx configuration above.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mattermost initial configuration and enable plugins upload
&lt;/h2&gt;

&lt;p&gt;Subdomain now points to mattermost instance. At this point we can create a new account and remember the credentials. Role of this user is &lt;em&gt;System Admin&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;At this point we can change mattermost config file to enable uploads for plugin. Edit &lt;em&gt;volumes/app/mattermost/config/config.json&lt;/em&gt; to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vim &amp;lt;mattermost-repo-clone&amp;gt;/volumes/app/mattermost/config/config.json

&lt;span class="c"&gt;# Search and set `EnableUploads` to true.&lt;/span&gt;
PluginSettings &lt;span class="o"&gt;{&lt;/span&gt;
  ...
  &lt;span class="s2"&gt;"EnableUploads"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
  ...
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Execute &lt;em&gt;docker stack deploy&lt;/em&gt;… that will restart mattermost app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker stack deploy &lt;span class="nt"&gt;-c&lt;/span&gt; docker-stack.yml mm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Plugins can now be uploaded to mattermost instance.&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;code&gt;System Console -&amp;gt; Plugin Management&lt;/code&gt;
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AVNO3ZbJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tiuox69mlsi26sxsuvb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AVNO3ZbJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/tiuox69mlsi26sxsuvb9.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SMTP Email setup
&lt;/h2&gt;

&lt;p&gt;Mattermost has excellent &lt;a href="https://docs.mattermost.com/install/smtp-email-setup.html"&gt;documentation&lt;/a&gt; for this settings, I used that webpage to configure SMTP. Minor detail that I followed to get it to work with gmail is included here.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;System Console -&amp;gt; Environment -&amp;gt; SMTP&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;SMTP Server: smtp.gmail.com
SMTP Server Port: 587
Enable SMTP Authentication: &lt;span class="nb"&gt;true
&lt;/span&gt;SMTP Server Username: &amp;lt;gmail address&amp;gt;
SMTP Server Password: &amp;lt;Generated app password with 2-factor authentication ON&amp;gt;
Connection Security: STARTTLS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For SMTP Server Password, I did the following&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I have 2-factor authentication enabled for my gmail account.&lt;/li&gt;
&lt;li&gt;Visit &lt;em&gt;Google account settings -&amp;gt; Security -&amp;gt; App passwords&lt;/em&gt;

&lt;ul&gt;
&lt;li&gt;Generate an app password and use that for SMTP Server Password in mattermost.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Visualizer
&lt;/h2&gt;

&lt;p&gt;Above docker deployment comes with visualizer, which can be viewed on port &lt;em&gt;&lt;em&gt;7071&lt;/em&gt;&lt;/em&gt;. For my mattermost installation here is the &lt;a href="https://visualizer.lakshmananumolu.com/"&gt;visualizer&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extras
&lt;/h2&gt;

&lt;p&gt;For extra installations such as &lt;a href="https://hub.docker.com/r/dpage/pgadmin4/"&gt;pgadmin4&lt;/a&gt; alongside above services, please refer to &lt;code&gt;team-extras&lt;/code&gt; branch (&lt;a href="https://github.com/acrlakshman/mattermost-docker/tree/team-extras"&gt;https://github.com/acrlakshman/mattermost-docker/tree/team-extras&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Some plugins
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/streamer45/mattermost-plugin-voice"&gt;https://github.com/streamer45/mattermost-plugin-voice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/blindsidenetworks/mattermost-plugin-bigbluebutton"&gt;https://github.com/blindsidenetworks/mattermost-plugin-bigbluebutton&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/scottleedavis/mattermost-plugin-remind"&gt;https://github.com/scottleedavis/mattermost-plugin-remind&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/mattermost/mattermost-5-15-76cf34f87d05"&gt;https://medium.com/mattermost/mattermost-5-15-76cf34f87d05&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@basi/docker-environment-variables-expanded-from-secrets-8fa70617b3bc"&gt;https://medium.com/@basi/docker-environment-variables-expanded-from-secrets-8fa70617b3bc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.mattermost.com/mobile/mobile-hpns.html"&gt;https://docs.mattermost.com/mobile/mobile-hpns.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mattermost</category>
      <category>docker</category>
      <category>selfhosted</category>
      <category>security</category>
    </item>
  </channel>
</rss>
