<?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>Forem: Pierangelo</title>
    <description>The latest articles on Forem by Pierangelo (@pierangelo1982).</description>
    <link>https://forem.com/pierangelo1982</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%2F382013%2F7374a2c0-91f2-4523-9c18-872751a0556a.png</url>
      <title>Forem: Pierangelo</title>
      <link>https://forem.com/pierangelo1982</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/pierangelo1982"/>
    <language>en</language>
    <item>
      <title>Keycloak Setup and Deployment Guide</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Wed, 26 Feb 2025 17:24:50 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/keycloak-setup-and-deployment-guide-4ebg</link>
      <guid>https://forem.com/pierangelo1982/keycloak-setup-and-deployment-guide-4ebg</guid>
      <description>&lt;h1&gt;
  
  
  Keycloak Setup and Deployment Guide
&lt;/h1&gt;

&lt;p&gt;This document details how to install and deploy Keycloak in both development and production environments. The setup integrates PostgreSQL as the database and uses an NGINX reverse proxy for HTTPS access.&lt;/p&gt;

&lt;p&gt;OS Debian and Ubuntu&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Java:&lt;/strong&gt; Ensure that OpenJDK is installed. For example, on Debian/Ubuntu you can install the default JDK using:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;default-jdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker:&lt;/strong&gt; Docker must be installed to run the Keycloak and PostgreSQL containers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certbot (for NGINX):&lt;/strong&gt; Required for managing SSL certificates with Let's Encrypt.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Development Mode
&lt;/h2&gt;

&lt;p&gt;To quickly test Keycloak in development mode, you can use the following Docker command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8090:8080 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;admin &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;KEYCLOAK_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;ADMIN_PASSWORD&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--dns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8.8.8.8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; keycloak_data:/opt/keycloak/data &lt;span class="se"&gt;\&lt;/span&gt;
  quay.io/keycloak/keycloak:23.0.4 &lt;span class="se"&gt;\&lt;/span&gt;
  start-dev 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Port Mapping:&lt;/strong&gt; The container exposes port 8080, which is mapped to port 8090 on the host.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin Credentials:&lt;/strong&gt; Environment variables set the admin username and password.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS:&lt;/strong&gt; Uses Google's DNS (8.8.8.8) for name resolution.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volume:&lt;/strong&gt; Data is persisted in a Docker volume named &lt;code&gt;keycloak_data&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version:&lt;/strong&gt; This command uses Keycloak version 23.0.4 in development mode (&lt;code&gt;start-dev&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Production Mode
&lt;/h2&gt;

&lt;p&gt;For a production deployment, you must configure HTTPS certificates and properly set up the container.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Generating Certificates
&lt;/h3&gt;

&lt;p&gt;Generate the necessary certificates using OpenSSL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Generate the Private Key:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  openssl genrsa &lt;span class="nt"&gt;-out&lt;/span&gt; keycloak.key 2048
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create a Self-Signed Certificate (valid for 365 days):&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  openssl req &lt;span class="nt"&gt;-new&lt;/span&gt; &lt;span class="nt"&gt;-x509&lt;/span&gt; &lt;span class="nt"&gt;-sha256&lt;/span&gt; &lt;span class="nt"&gt;-key&lt;/span&gt; keycloak.key &lt;span class="nt"&gt;-out&lt;/span&gt; keycloak.crt &lt;span class="nt"&gt;-days&lt;/span&gt; 365
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create the PEM File:&lt;/strong&gt;
Rename the private key file and concatenate the certificate:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;mv &lt;/span&gt;keycloak.key keycloak.pem
  &lt;span class="nb"&gt;cat &lt;/span&gt;keycloak.crt &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; keycloak.pem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; You may need to adjust parameters (like CN, O, C, etc.) during certificate generation.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Creating a Keystore with keytool
&lt;/h3&gt;

&lt;p&gt;Use the &lt;code&gt;keytool&lt;/code&gt; command to generate a key pair and create the keystore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;keytool &lt;span class="nt"&gt;-genkeypair&lt;/span&gt; &lt;span class="nt"&gt;-alias&lt;/span&gt; localhost &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-keyalg&lt;/span&gt; RSA &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-keysize&lt;/span&gt; 2048 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-validity&lt;/span&gt; 365 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-keystore&lt;/span&gt; server.keystore &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-dname&lt;/span&gt; &lt;span class="s2"&gt;"CN=Server Administrator,O=OrgName,C=IN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-keypass&lt;/span&gt; &amp;lt;KEY_PASSWORD&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-storepass&lt;/span&gt; &amp;lt;KEY_PASSWORD&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After completion, you will have three files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;keycloak.crt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;keycloak.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;server.keystore&lt;/code&gt; (which should be converted to PKCS12 format and then renamed)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These files will be provided as arguments when launching Keycloak:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--https-certificate-file=&amp;lt;path&amp;gt;/keycloak.crt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--https-certificate-key-file=&amp;lt;path&amp;gt;/keycloak.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--https-trust-store-file=&amp;lt;path&amp;gt;/server.keystore&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Docker and PostgreSQL Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Create a Docker Network
&lt;/h3&gt;

&lt;p&gt;Create a dedicated Docker network for container communication:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network create kcnetwork
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Set Up PostgreSQL
&lt;/h3&gt;

&lt;p&gt;Create a Docker volume for PostgreSQL data persistence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker volume create pgdata
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the PostgreSQL container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; kc_pg_cont &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--network&lt;/span&gt; kcnetwork &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;POSTGRES_PASSWORD&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-p&lt;/span&gt; 5432:5432 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"always"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; pgdata:/var/lib/postgresql/data &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Building a Custom Docker Image for Keycloak
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Prepare the Directory
&lt;/h3&gt;

&lt;p&gt;Create a directory for Keycloak files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;keycloak
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside this directory, create a &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Dockerfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the certificate and keystore files into this directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;keycloak.crt keycloak/
&lt;span class="nb"&gt;cp &lt;/span&gt;keycloak.pem keycloak/
&lt;span class="nb"&gt;cp &lt;/span&gt;server.keystore keycloak/server.keystore.p12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Dockerfile Contents
&lt;/h3&gt;

&lt;p&gt;Place the following content in your &lt;code&gt;Dockerfile&lt;/code&gt; (passwords have been anonymized):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Dockerfile contents START&lt;/span&gt;

&lt;span class="c"&gt;# Use the latest Keycloak image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; quay.io/keycloak/keycloak:latest&lt;/span&gt;

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; root&lt;/span&gt;

&lt;span class="c"&gt;# Copy the certificates and keystore into the configuration directory&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; keycloak.crt /opt/keycloak/conf/keycloak.crt&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; keycloak.pem /opt/keycloak/conf/keycloak.pem&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; server.keystore.p12 /opt/keycloak/conf/server.keystore.p12&lt;/span&gt;

&lt;span class="c"&gt;# Debug: list the copied files to confirm their presence&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /opt/keycloak/conf/

&lt;span class="c"&gt;# Set the trust store type to PKCS12&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; KC_HTTPS_TRUST_STORE_TYPE=PKCS12&lt;/span&gt;

&lt;span class="c"&gt;# Database configuration&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; KC_DB=postgres&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; KC_DB_USERNAME=postgres&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; KC_DB_PASSWORD=&amp;lt;POSTGRES_PASSWORD&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; KC_DB_URL=jdbc:postgresql://kc_pg_cont:5432/postgres&lt;/span&gt;

&lt;span class="c"&gt;# Keycloak admin credentials&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; KEYCLOAK_ADMIN=admin&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; KEYCLOAK_ADMIN_PASSWORD=&amp;lt;ADMIN_PASSWORD&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# (Optional) Set correct permissions on the files&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /opt/keycloak/conf/keycloak.pem
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /opt/keycloak/conf/keycloak.crt
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /opt/keycloak/conf/server.keystore.p12

&lt;span class="c"&gt;# Start the Keycloak server with HTTPS options and specified hostname&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["/opt/keycloak/bin/kc.sh", "start",&lt;/span&gt;
  "--https-port=9443", "--http-port=8095",
  "--https-certificate-file", "/opt/keycloak/conf/keycloak.crt",
  "--https-certificate-key-file", "/opt/keycloak/conf/keycloak.pem",
  "--https-trust-store-file", "/opt/keycloak/conf/server.keystore.p12",
  "--https-trust-store-password", "&amp;lt;KEYSTORE_PASSWORD&amp;gt;",
  "--hostname", "keycloak-develop.example.com",
  "--https-trust-store-type", "PKCS12"]

# Dockerfile contents END
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Build the Docker Image
&lt;/h3&gt;

&lt;p&gt;Build your custom Keycloak image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; kcprod_v1 &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Run the Container
&lt;/h3&gt;

&lt;p&gt;Start the Keycloak container on the created network:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; kctest_container &lt;span class="nt"&gt;--network&lt;/span&gt; kcnetwork &lt;span class="nt"&gt;-p&lt;/span&gt; 9443:9443 &lt;span class="nt"&gt;-p&lt;/span&gt; 8095:8095 &lt;span class="nt"&gt;-d&lt;/span&gt; kcprod_v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Configuring NGINX as a Reverse Proxy
&lt;/h2&gt;

&lt;p&gt;To expose Keycloak under your domain and manage HTTPS, set up NGINX.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create the NGINX Site Configuration File
&lt;/h3&gt;

&lt;p&gt;For example, create a file at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo touch&lt;/span&gt; /etc/nginx/sites-available/keycloak-develop.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configure the File with the Following Content
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;keycloak-develop.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;client_max_body_size&lt;/span&gt; &lt;span class="mi"&gt;100M&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;https://keycloak-develop.example.com:9443&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;# Disable SSL verification for Keycloak if necessary:&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_ssl_verify&lt;/span&gt; &lt;span class="no"&gt;off&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Managed by Certbot&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/keycloak-develop.example.com/fullchain.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Managed by Certbot&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/live/keycloak-develop.example.com/privkey.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Managed by Certbot&lt;/span&gt;
    &lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/options-ssl-nginx.conf&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Managed by Certbot&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_dhparam&lt;/span&gt; &lt;span class="n"&gt;/etc/letsencrypt/ssl-dhparams.pem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Managed by Certbot&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;if&lt;/span&gt; &lt;span class="s"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;keycloak-develop.example.com)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt; &lt;span class="s"&gt;https://&lt;/span&gt;&lt;span class="nv"&gt;$host$request_uri&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;keycloak-develop.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Enable the Site and Restart NGINX
&lt;/h3&gt;

&lt;p&gt;Link the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/keycloak-develop.example.com /etc/nginx/sites-enabled/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nginx &lt;span class="nt"&gt;-t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart NGINX:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Accessing Keycloak
&lt;/h2&gt;

&lt;p&gt;After the configuration, Keycloak will be available at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://keycloak-develop.example.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure that DNS records point to your server and that Let's Encrypt certificates are properly obtained and installed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Verify the permissions on the certificate and keystore files. Consider using secure environment variables for passwords.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Persistence:&lt;/strong&gt; Make sure Docker volumes for both Keycloak and PostgreSQL are correctly configured to persist data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and Logging:&lt;/strong&gt; Set up monitoring to observe container performance in production.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Updates:&lt;/strong&gt; Plan for periodic updates to Keycloak, the operating system, and security components.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;This guide provides a comprehensive overview for setting up and deploying Keycloak in a Docker environment with HTTPS support, PostgreSQL as the database, and an NGINX reverse proxy. Replace the placeholder values (e.g., &lt;code&gt;&amp;lt;ADMIN_PASSWORD&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;POSTGRES_PASSWORD&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;KEYSTORE_PASSWORD&amp;gt;&lt;/code&gt;, and domain names) with your actual production values while keeping them secure.&lt;/p&gt;

</description>
      <category>keycloak</category>
      <category>ubuntu</category>
      <category>debian</category>
      <category>docker</category>
    </item>
    <item>
      <title>Monitoring with Prometheus &amp; Grafana
</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Tue, 10 Aug 2021 19:45:02 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/monitoring-with-prometheus-grafana-3i4b</link>
      <guid>https://forem.com/pierangelo1982/monitoring-with-prometheus-grafana-3i4b</guid>
      <description>&lt;p&gt;How set a monitoring system with prometheus, node_exporter and grafana dashboard.&lt;/p&gt;

&lt;p&gt;N.B: this tutorial is based on UBUNTU&lt;/p&gt;

&lt;h3&gt;
  
  
  Prometheus
&lt;/h3&gt;

&lt;p&gt;create prometheus user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo useradd --no-create-home --shell /bin/false prome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create directories&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo mkdir /etc/prometheus

sudo mkdir /var/lib/prometheus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;download prometheus on your server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://github.com/prometheus/prometheus/releases/download/v2.29.0-rc.1/prometheus-2.29.0-rc.1.linux-amd64.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;extract the tar file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tar xvfz prometheus-*.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;enter in the folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd prometheus-*

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;edit prometheus.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim prometheus.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;copy prometheus folder (not the root folder but the folder inside the root folder) in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp -rf prometheus /usr/local/bin/

sudo cp -rf promtool /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;set permission:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown prome:prome /usr/local/bin/prometheus

sudo chown prome:prome /usr/local/bin/promtool

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;copy files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp -rf consoles /etc/prometheus

sudo cp -rf console_libraries/ /etc/prometheus/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;set permissions in /etc&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown -R prome:prome /etc/prometheus/consoles

sudo chown -R prome:prome /etc/prometheus/console_libraries

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;copy prometheus.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp prometheus.yml /etc/prometheus/prometheus.yml 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;start prometheus&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./prometheus --config.file=prometheus.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create service file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo vim /etc/systemd/system/prometheus.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prome
Group=prome
Type=simple
ExecStart=/usr/local/bin/prometheus \
    --config.file /etc/prometheus/prometheus.yml \
    --storage.tsdb.path /var/lib/prometheus/ \
    --web.console.templates=/etc/prometheus/consoles \
    --web.console.libraries=/etc/prometheus/console_libraries

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;reload daemon&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;system command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start prometheus

sudo systemctl enable prometheus

sudo systemctl status prometheus



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;check:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://your-machine-ip:9090"&gt;http://your-machine-ip:9090&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  node exporter
&lt;/h3&gt;

&lt;p&gt;download node exportyet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://github.com/prometheus/node_exporter/releases/download/v1.2.2/node_exporter-1.2.2.linux-amd64.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;extract:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tar xvfz node_exporter-1.2.2.linux-amd64.tar.gz

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;enter in the extracted folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; cd node_exporter-1.2.2.linux-amd64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;run node exportyer&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./node_exporter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;check metrics on:&lt;br&gt;
&lt;a href="http://your-vps-ip:9100"&gt;http://your-vps-ip:9100&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;back to prometheus.yml and add ip and port node_exporter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; - job_name: "node exporter test"
    static_configs:
      - targets: ['localhost:9100']

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  node exporter as service
&lt;/h1&gt;

&lt;p&gt;create user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo useradd -rs /bin/false node_exporter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;copy node exporter in bin folder&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp -rf node_exporter-1.2.2.linux-amd64/node_exporter /usr/local/bin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create service file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim /etc/systemd/system/node_exporter.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=Node Exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;launch sevice commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl daemon-reload
sudo systemctl start node_exporter
sudo systemctl enable node_exporter
sudo systemctl status node_exporter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  grafana
&lt;/h3&gt;

&lt;p&gt;install dependency library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get install -y adduser libfontconfig1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;download deb&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://dl.grafana.com/oss/release/grafana_8.1.0_amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dpkg -i grafana_8.1.0_amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;check:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://your-vps-ip:3000/login"&gt;http://your-vps-ip:3000/login&lt;/a&gt;&lt;/p&gt;

</description>
      <category>grafana</category>
      <category>prometheus</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>Using NodeJS App with Apache</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Tue, 10 Nov 2020 13:13:15 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/using-nodejs-app-with-apache-19k7</link>
      <guid>https://forem.com/pierangelo1982/using-nodejs-app-with-apache-19k7</guid>
      <description>&lt;p&gt;How setting Apache2 using proxy for expose a NodeJS app.&lt;/p&gt;

&lt;p&gt;First install apache2:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt update&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt install apache2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;install nodejs e npm&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt install nodejs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt install npm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;copy your app in /var/www/demo&lt;/p&gt;

&lt;p&gt;here a repo to my demo app if you want use it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/pierangelo1982/nodejs-experiment/tree/master/06%20-%20show_hostname"&gt;https://github.com/pierangelo1982/nodejs-experiment/tree/master/06%20-%20show_hostname&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;install pm2&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install -g pm2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;we use pm2 for start a daemon of our app, and for enable an autostart in case of reboot of our machine.&lt;/p&gt;

&lt;p&gt;from your terminal go into the root folder of the app&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd /var/www/demo&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and launch the command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pm2 start app.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;after that we must config an automatic start in case of reboot:&lt;/p&gt;

&lt;p&gt;so launch this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pm2 startup systemd&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and copy the env that will be print and paste it in the terminal, in my case is this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u pierangelo — hp /home/pierangelo&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;now we go to settings apache2&lt;br&gt;
as first things we must enable two modules:&lt;/p&gt;

&lt;p&gt;proxy&lt;/p&gt;

&lt;p&gt;proxy_http&lt;/p&gt;

&lt;p&gt;so from terminal launch this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;a2enmod proxy&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;a2enmod proxy_http&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;after that go in /etc/sites/available and create a file named myapp.conf&lt;/p&gt;

&lt;p&gt;myapp.conf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
 ServerName node.mysite.it 
 ProxyPreserveHost on
 ProxyPass / http://localhost:3000/
 ProxyPassReverse / http://localhost:3000/
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;check carefully, in ProxyPass and ProxyPassReverse you mast show the localhost with the port that you use in your nodejs app.&lt;/p&gt;

&lt;p&gt;after that enable your virtualhost:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;a2ensite myapp.conf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and restart apache2&lt;/p&gt;

&lt;p&gt;&lt;code&gt;service apache2 restart&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;now you should see your app running on your domain address.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/mbR-4ILCeig"&gt;Vedi Tutorial Here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>apache</category>
      <category>server</category>
    </item>
    <item>
      <title>Dockerize an existing Laravel application with docker-compose</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Sun, 08 Nov 2020 07:04:04 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/dockerize-an-existing-laravel-application-with-docker-compose-3l5m</link>
      <guid>https://forem.com/pierangelo1982/dockerize-an-existing-laravel-application-with-docker-compose-3l5m</guid>
      <description>&lt;p&gt;in the main folder of your Laravel app, create a file named Dockerfile and insert this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM php:7
RUN apt-get update -y &amp;amp;&amp;amp; apt-get install -y openssl zip unzip git
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN docker-php-ext-install pdo pdo_mysql
WORKDIR /app
COPY . /app
RUN composer install
CMD php artisan serve --host=0.0.0.0 --port=8181
EXPOSE 8181
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the same main folder of Dockerfile, create a file named docker-compose.yml and insert this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '2'
services:
  app:
    build: .
    ports:
      - "8009:8000"
    volumes:
      - .:/app
    env_file: .env
    working_dir: /app
    command: bash -c 'php artisan migrate &amp;amp;&amp;amp; php artisan serve --host 0.0.0.0'
    depends_on:
      - db
    links:
      - db
  db:
    image: "mysql:5.7"
    environment:
      - MYSQL_ROOT_PASSWORD=yourpassword
      - MYSQL_DATABASE=yourdbname
      - MYSQL_USER=root
      - MYSQL_PASSWORD=yourpassword
    volumes:
      - ./data/:/var/lib/mysql
    ports:
      - "3306:3306"
  phpmyadmin:
    depends_on:
      - db
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 8090:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: yourpassword
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the terminal command line and go inside the laravel folder, and launch this commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker.compose build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;if have need to create and migrate the db, or use other commands, launch the Laravel commands in this way:&lt;br&gt;
&lt;code&gt;docker-compose run app php artisan&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The app will available at the address &lt;a href="http://0.0.0.0:8009"&gt;http://0.0.0.0:8009&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>docker</category>
      <category>devops</category>
      <category>php</category>
    </item>
    <item>
      <title>Dockerize an existing GOLANG web server</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Thu, 29 Oct 2020 10:59:03 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/dockerize-an-existing-golang-web-server-3hf5</link>
      <guid>https://forem.com/pierangelo1982/dockerize-an-existing-golang-web-server-3hf5</guid>
      <description>&lt;p&gt;in the golang project folder create a file named Dockerfile and a file named docker-compose.yml&lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerile
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM golang:latest
LABEL maintainer "Pierangelo Orizio &amp;lt;pierangelo1982@gmail.com&amp;gt;"
# for install go packages RUN go get /path
RUN go get github.com/go-sql-driver/mysql
# Copy the local package files to the container's workspace.
ADD . /go/src/github.com/pierangelo1982/myproject
# build executable
RUN go install github.com/pierangelo1982/myproject
# execute 
ENTRYPOINT /go/bin/myproject
# Document that the service listens on port 8080.
EXPOSE 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;N.B: in the paths you can substitute pierangelo1982 with your github username.&lt;/p&gt;

&lt;p&gt;For add other GO packages add in dockerfile this command (see line 5 in Dockerfile for see an example):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;RUN go get github.com/&amp;lt;nameofthepackages&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  docker-compose.yml
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '2'
services:
  app:
    build: .
    volumes:
      - .:/go/src/github.com/pierangelo1982/myproject
    expose:
      - "8080"
    ports:
      - 8080:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the terminal, from inside the project folder launch this commands:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;check with the browser if the app run at the address &lt;a href="http://0.0.0.0:8080"&gt;http://0.0.0.0:8080&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>go</category>
      <category>container</category>
    </item>
    <item>
      <title>Dockerize a Flask App</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Tue, 27 Oct 2020 11:25:15 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/dockerize-a-flask-app-4pe</link>
      <guid>https://forem.com/pierangelo1982/dockerize-a-flask-app-4pe</guid>
      <description>&lt;p&gt;How dockerize a Flask app…&lt;/p&gt;

&lt;p&gt;here my very basic app:&lt;br&gt;
main.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    return 'Hello, World!'
if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;N.B: above I have set public ip 0.0.0.0, beacuse with 127.0.0.1 it’s reachable only inside the container and not from the outside outside.&lt;br&gt;
create a file requirements.txt&lt;br&gt;
and insert all the pip libraries that your app require (in my case only Flask).&lt;/p&gt;

&lt;p&gt;requirements.txt&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flask
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a file named Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM ubuntu:18.04
LABEL maintainer “yor name &amp;lt;your@email.com&amp;gt;”
RUN apt-get update -y &amp;amp;&amp;amp; \
apt-get install -y python3-pip python3-dev
# We copy just the requirements.txt first to leverage Docker cache
COPY ./requirements.txt /app/requirements.txt
WORKDIR /app
RUN pip3 install -r requirements.txt
COPY . /app
ENTRYPOINT [ “python3” ]
CMD [ “main.py” ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;build the image launching from terminal the command:&lt;br&gt;
&lt;code&gt;docker build -t name_of_yuor_image:latest .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;run the container launching from terminal the command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run --name name_your_container -p 5000:5000 -d name_of_yuor_image:latest&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;connected to address: &lt;a href="http://0.0.0.0:5000"&gt;http://0.0.0.0:5000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Watch the video tutorial:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/Pjd4k4l8oV0"&gt;https://youtu.be/Pjd4k4l8oV0&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>flask</category>
      <category>python</category>
      <category>devops</category>
    </item>
    <item>
      <title>nodejs vs golang server web</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Sat, 24 Oct 2020 12:16:16 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/nodejs-vs-golang-server-web-21o4</link>
      <guid>https://forem.com/pierangelo1982/nodejs-vs-golang-server-web-21o4</guid>
      <description>&lt;p&gt;After the comparison &lt;a href="http://www.web-dev.info/docker/2018/10/25/golang-with-mongodb.html"&gt;between NodeJS and GO about how to use MongoDB&lt;/a&gt;, now will see how programming a very simple and basic web server with this two technologies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Golang:
&lt;/h3&gt;

&lt;p&gt;file main.go&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "net/http"

func homePage(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Welcome to my Home Page"))
}
func main() {
    http.HandleFunc("/", homePage)
    if err := http.ListenAndServe(":8080", nil); err != nil {
        panic(err)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go run main.go

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should be run on:&lt;br&gt;
&lt;a href="http://127.0.0.1:8080"&gt;http://127.0.0.1:8080&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  NodeJS
&lt;/h3&gt;

&lt;p&gt;file app.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const http = require('http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) =&amp;gt; {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/plain');
    res.end('Welcome to my Home Page');
});

server.listen(port, hostname, () =&amp;gt;  {
    console.log(`Server running at http://${hostname}:${port}/`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;run server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should be run on:&lt;br&gt;
&lt;a href="http://127.0.0.1:3000"&gt;http://127.0.0.1:3000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So as you see, with both you can get a running web server with few lines of code.&lt;/p&gt;

&lt;p&gt;Have a Nice Day!&lt;/p&gt;

&lt;h3&gt;
  
  
  Respository:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;NodeJS &lt;a href="https://github.com/pierangelo1982/nodejs-experiment/blob/master/01%20-%20first%20app/app.js"&gt;https://github.com/pierangelo1982/nodejs-experiment/blob/master/01%20-%20first%20app/app.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Golang &lt;a href="https://github.com/pierangelo1982/go-experiment/tree/master/server-web/02"&gt;https://github.com/pierangelo1982/go-experiment/tree/master/server-web/02&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Video Tutorial:
&lt;/h3&gt;

</description>
      <category>go</category>
      <category>node</category>
    </item>
    <item>
      <title>nodejs vs golang with MongoDB</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Mon, 19 Oct 2020 14:50:12 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/nodejs-vs-golang-with-mongodb-kee</link>
      <guid>https://forem.com/pierangelo1982/nodejs-vs-golang-with-mongodb-kee</guid>
      <description>&lt;p&gt;I'm trying to learn and use MongoDB, so i had try to connect a app in golang and an other in nodejs, below the two piece of code of both languages...&lt;br&gt;
They are very similar, probably in nodejs is a bit simple, but in both case MongoDB offer a very good documentations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Golang:
&lt;/h2&gt;

&lt;p&gt;As packages I had used the offical mongodb packages (&lt;a href="https://godoc.org/github.com/mongodb/mongo-go-driver/mongo"&gt;import "github.com/mongodb/mongo-go-driver/mongo"&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go get github.com/mongodb/mongo-go-driver/mongo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in my main.go&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "context"
    "fmt"
    "log"

    "github.com/mongodb/mongo-go-driver/bson"
    "github.com/mongodb/mongo-go-driver/mongo"
)

type agenda struct {
    Nome    string
    Cognome string
    Nazione string
}

func main() {
    client, err := mongo.NewClient("mongodb://127.0.0.1:27017")
    if err != nil {
        log.Fatal(err)
    }
    err = client.Connect(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    collection := client.Database("demo").Collection("agenda")
    fmt.Println(collection)
    cur, err := collection.Find(context.Background(), nil)
    if err != nil {
        log.Fatalln(err)
    }
    defer cur.Close(context.Background())
    fmt.Println("test", cur)

    for cur.Next(context.Background()) {
        elem := bson.NewDocument()
        if err = cur.Decode(elem); err != nil {
            fmt.Errorf("readTasks: couldn't make to-do item ready for display: %v", err)
        }
        fmt.Println(elem.Lookup("nome").StringValue())
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go run main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  NodeJS
&lt;/h2&gt;

&lt;p&gt;Also in nodejs I had used official mongodb library:&lt;br&gt;
&lt;a href="https://mongodb.github.io/node-mongodb-native/"&gt;https://mongodb.github.io/node-mongodb-native/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your app folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install mongodb --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;my package.json file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "nodejs-mongodb",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "mongodb": "^3.1.8"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;my app.js file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// mongodb
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');

// connection to mongodb url
const mongohost = 'mongodb://127.0.0.1:27017';

// create a new MongoClient
const client = new MongoClient(mongohost);

// database name
const dbName = 'demo';

// connect to the server
client.connect(function(err) {
    assert.equal(null, err);
    console.log("Connected succesfully to server db");

    // passo db
    const db = client.db(dbName);
    const collection = db.collection('agenda');
    collection.find({}).toArray(function(err, docs){
        assert.equal(err, null);
        console.log("trovati i seguenti record");
        console.log(docs);
        for (i = 0; i &amp;lt; docs.length; i++) {
            console.log(docs[i].nome + " " + docs[i].cognome + " " + docs[i].nazione);
        }
    });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Launch app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node app.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Have a nice day!&lt;/p&gt;

&lt;h3&gt;
  
  
  Repository:
&lt;/h3&gt;

&lt;p&gt;Golang: &lt;a href="https://github.com/pierangelo1982/go-experiment/tree/master/mongodb-golang/01"&gt;https://github.com/pierangelo1982/go-experiment/tree/master/mongodb-golang/01&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;NodeJS: &lt;a href="https://github.com/pierangelo1982/nodejs-experiment/tree/master/02%20-%20nodejs-mongodb"&gt;https://github.com/pierangelo1982/nodejs-experiment/tree/master/02%20-%20nodejs-mongodb&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>mongodb</category>
      <category>node</category>
      <category>database</category>
    </item>
    <item>
      <title>using superheroes for refresh my mind about Golang structs</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Sat, 17 Oct 2020 20:02:03 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/using-superheroes-for-refresh-my-mind-about-golang-structs-1958</link>
      <guid>https://forem.com/pierangelo1982/using-superheroes-for-refresh-my-mind-about-golang-structs-1958</guid>
      <description>&lt;p&gt;After have followed &lt;a href="https://greatercommons.com/learn/golang"&gt;an amazing course about golang&lt;/a&gt; one years ago, I had need to refresh my mind about the &lt;a href="https://golang.org/ref/spec"&gt;Struct&lt;/a&gt; in golang, and for do it I had used some superheroes:&lt;/p&gt;

&lt;h3&gt;
  
  
  First Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "fmt"

type skill struct {
    Power string
}

type hero struct {
    Name  string
    Alias string
    skill
}

func main() {
    h1 := hero{
        Name:  "Bruce Wayne",
        Alias: "Batman",
        skill: skill{
            Power: "a lot of gadgets",
        },
    }
    h2 := hero{
        Name:  "Tony Stark",
        Alias: "Iron",
        skill: skill{
            Power: "hi-tech armor",
        },
    }

    fmt.Printf("the best skill of %s is %s \n", h1.Alias, h1.skill.Power)
    fmt.Printf("the best skill of %s is %s \n", h2.Alias, h2.skill.Power)

    s1 := skill{
        Power: "velocity",
    }

    h3 := hero{
        Name:  "Barry Allen",
        Alias: "Flash",
        skill: skill{
            Power: s1.Power,
        },
    }

    fmt.Printf("the best skill of %s is %s \n", h3.Alias, h3.skill.Power)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Second Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "fmt"

type skill struct {
    Power string
}

type hero struct {
    Name  string
    Alias string
}

type heroSkill struct {
    hero
    skill
}

func main() {
    hs1 := heroSkill{
        hero: hero{
            Name:  "Clark Kent / Kal-El",
            Alias: "Superman",
        },
        skill: skill{
            Power: "a lot of cool superpowers",
        },
    }

    hs2 := heroSkill{
        hero: hero{
            Name:  "Steve Rogers",
            Alias: "Capitan America",
        },
        skill: skill{
            Power: "strong",
        },
    }

    fmt.Printf("the best skill of %s is %s \n", hs1.hero.Alias, hs1.skill.Power)
    // check the different way to call the struct, in this second Print, there no need to call the sub struct.
    fmt.Printf("the best skill of %s is %s \n", hs2.Alias, hs2.Power)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>go</category>
      <category>code</category>
      <category>programming</category>
    </item>
    <item>
      <title>Dockerize an existing Rails application</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Sat, 17 Oct 2020 07:46:13 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/dockerize-an-existing-rails-application-f5n</link>
      <guid>https://forem.com/pierangelo1982/dockerize-an-existing-rails-application-f5n</guid>
      <description>&lt;p&gt;crea un app in rails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails new demo -d mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a Dockerfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM ruby:2.5.1
RUN apt-get update -qq &amp;amp;&amp;amp; apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /usr/src/demo
WORKDIR /usr/src/demo
ADD Gemfile /usr/src/demo/Gemfile
ADD Gemfile.lock /usr/src/demo/Gemfile.lock
RUN bundle install
ADD . /usr/src/demo
RUN RAILS_ENV=production bundle exec rake assets:precompile --trace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create docker-compose.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '2'
services:
  app:
    build: .
    command: bundle exec puma -C config/puma.rb
    volumes:
      - .:/usr/src/demo
    expose:
      - "3000"
    environment:
      RACK_ENV: production
      RAILS_ENV: production
    ports:
        - 3000:3000
    depends_on:
      - db
    links:
      - db

  db:
    image: "mysql:5.7"
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=db
      - MYSQL_USER=root
      - MYSQL_PASSWORD=password
    ports:
      - "3306:3306"

  phpmyadmin:
    depends_on:
      - db
    image: phpmyadmin/phpmyadmin
    restart: always
    ports:
      - 8081:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>docker</category>
      <category>rails</category>
      <category>ruby</category>
      <category>container</category>
    </item>
    <item>
      <title>kong api gateways with docker</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Sat, 17 Oct 2020 07:44:40 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/kong-api-gateways-with-docker-nle</link>
      <guid>https://forem.com/pierangelo1982/kong-api-gateways-with-docker-nle</guid>
      <description>&lt;p&gt;&lt;a href="https://konghq.com/"&gt;KONG&lt;/a&gt; is a api gateway placed above the microservices aimed to managing the APIs and interactions external and internal with them in a more rational, efficient, safe and "easy" way, helping the developer in the separation between public and private APIs, improving their performance , facilitating monitoring etc ...&lt;/p&gt;

&lt;h3&gt;
  
  
  Some Characteristic:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Built on NGINX&lt;/li&gt;
&lt;li&gt;For the most part written in LUA&lt;/li&gt;
&lt;li&gt;Expandable via many Plugins&lt;/li&gt;
&lt;li&gt;It supports two types of Datastores, which can also be used simultaneously (Postgres, cassandra)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy management of APIs in a Microservice architecture&lt;/li&gt;
&lt;li&gt;helps in the separation between Public and Private APIs&lt;/li&gt;
&lt;li&gt;allows to measure and possibly limit the use of these APIs.&lt;/li&gt;
&lt;li&gt;Improves performance / through the use of caching etc ...)&lt;/li&gt;
&lt;li&gt;Expandable through many plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best way for move the fists step with KONG is using docker:&lt;/p&gt;

&lt;p&gt;first, create and internal network for the dockers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker network create kong-net
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a container for cassandra db:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --name kong-cassandra-database \
              --network=kong-net \
              -p 9042:9042 \
              cassandra:3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a postgre sql container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --name kong-postgres-database \
              --network=kong-net \
              -p 5432:5432 \
              -e "POSTGRES_USER=kong" \
              -e "POSTGRES_DB=kong" \
              postgres:9.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run --rm \
    --network=kong-net \
    -e "KONG_DATABASE=postgres" \
    -e "KONG_PG_HOST=kong-postgres-database" \
    -e "KONG_CASSANDRA_CONTACT_POINTS=kong-postgres-database" \
    kong:latest kong migrations up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a kong container connected to the postgres and cassandra databases throught the internal network kong-net:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --name kong \
    --network=kong-net \
    -e "KONG_DATABASE=postgres" \
    -e "KONG_PG_HOST=kong-postgres-database" \
    -e "KONG_CASSANDRA_CONTACT_POINTS=kong-cassandra-database" \
    -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
    -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
    -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
    -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
    -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
    -p 8000:8000 \
    -p 8443:8443 \
    -p 8001:8001 \
    -p 8444:8444 \
    kong:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;check on url &lt;a href="http://localhost:8001/"&gt;http://localhost:8001/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more info, go on official web site &lt;a href="https://konghq.com/"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>api</category>
      <category>microservices</category>
      <category>kong</category>
    </item>
    <item>
      <title>a basic NGINX cookbook chef</title>
      <dc:creator>Pierangelo</dc:creator>
      <pubDate>Sat, 17 Oct 2020 03:39:50 +0000</pubDate>
      <link>https://forem.com/pierangelo1982/a-basic-nginx-cookbook-chef-3218</link>
      <guid>https://forem.com/pierangelo1982/a-basic-nginx-cookbook-chef-3218</guid>
      <description>&lt;p&gt;Ok, this is how create a simple nginx cookbook for &lt;a href="https://www.chef.io/chef/"&gt;Chef&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this example I don’t use chef-server, but i work directly on the machine. In my case the machine is a Vagrant VM based on Ubuntu/xenial64, but i think that you can use a VPS or Cloud service and others Linux OS.&lt;/p&gt;

&lt;p&gt;As first thing to do, we must install ChefDK on our machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P chefdk -c stable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we have to create a folder called cookbooks where we will go to insert our cookbooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir cookbooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;inside the cookbooks folder we create our first cookbook named mynginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd cookbooks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chef generate cookbook mynginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the file default.rb in in mynginx/recipes/default.rb&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package 'git'
package 'tree'

package 'nginx' do
  action :install
end


service 'nginx' do
  action [ :enable, :start ]
end


cookbook_file "/var/www/html/index.html" do
  source "index.html"
  mode "0644"
end


template "/etc/nginx/nginx.conf" do   
  source "nginx.conf.erb"
  notifies :reload, "service[nginx]"
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;from inside the mynginx folder I must generate a file index.html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chef generate file index.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;edit the file index.html in files/default/index.html&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Hello there&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;This is a test&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Please work!&amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create a templates named nginx.conf:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chef generate template nginx.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;edit the file nginx.conf.erb in templates/nginx.conf.erb and insert your custom configuration of nginx.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable "msie6";

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}


#mail {
#   # See sample authentication script at:
#   # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#   # auth_http localhost/auth.php;
#   # pop3_capabilities "TOP" "USER";
#   # imap_capabilities "IMAP4rev1" "UIDPLUS";
# 
#   server {
#       listen     localhost:110;
#       protocol   pop3;
#       proxy      on;
#   }
# 
#   server {
#       listen     localhost:143;
#       protocol   imap;
#       proxy      on;
#   }
#}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now you can launch chef-client in local mode for install or update your machine:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sudo chef-client -z --runlist "mynginx"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>nginx</category>
      <category>devops</category>
      <category>server</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
