Skip to content

Instantly share code, notes, and snippets.

@lucakiebel
Last active April 2, 2022 14:18
Show Gist options
  • Save lucakiebel/88fa65df592be0d853f9354e5e2621d3 to your computer and use it in GitHub Desktop.
Save lucakiebel/88fa65df592be0d853f9354e5e2621d3 to your computer and use it in GitHub Desktop.

Docker, Nginx and Let's Encrypt Setup for Ubuntu 20.04

Docker

For more up-to-date information, visit https://docs.docker.com/engine/install/ubuntu/ and https://docs.docker.com/compose/install/ respectively)

To start off, remove all old versions of the docker suite:

sudo apt-get remove docker docker-engine docker.io containerd runc

Update the apt-cache and install the needed software to add the sources list for dockers repo:

sudo apt-get update
sudo apt-get install ca-certificates curl gnupg lsb-release

Add dockers GPG Key and the the sources list to your apt sources:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Finally, update the apt-cache once more and install docker-ce, the docker-ce-cli and containerd.io:

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

Now onto Docker-Compose.

While docker wants you to use docker compose, it's not yet feature-complete and thus, both installations are needed. Thankfully, this is going to be a fast one:

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Notice that this will install 1.92.2 which may or may not be the newest supported version of compose 1.

Change the permissions to make the docker-compose script executable:

sudo chmod +x /usr/local/bin/docker-compose

Create a symbolic link from the installation location to /usr/bin:

sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

Now you can run the project you want with either docker or docker-compose. Make note of the port it exposes to the outside, as we need this in the next section.

Nginx

(For more up-to-date information, visit https://nginx.org/en/linux_packages.html#Ubuntu)

Nginx needs a few dependencies, most of which were already required previously, and on most systems they should come pre-installed:

sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring

Next, install Nginx's keyring files and use them to add the sources list to your apt-sources:

curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list

Then just update and install:

sudo apt update
sudo apt install nginx

To get started with exposing your server, a new config file in /etc/nginx/sites-available/:

sudo mkdir -p /etc/nginx/sites-available/ /etc/nginx/sites-enabled/
sudo touch /etc/nginx/sites-available/$YOUR_DOMAIN_NAME.TLD

Edit this file using your favorite editor, nano is an easy choice:

sudo nano /etc/nginx/sites-available/$YOUR_DOMAIN_NAME.TLD

Here is a template for the Nginx Configuration, the $CAPS_LOCK_VARIABLES (so $YOUR_DOMAIN_NAME.TLD and $YOUR_APPLICATION_PORT (from docker earlier)) are what you need to change:

server{
    listen 80;
    server_name $YOUR_DOMAIN_NAME.TLD;
    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:$YOUR_APPLICATION_PORT;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

Next, symlink the file to the sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/$YOUR_DOMAIN_NAME.TLD /etc/nginx/sites-enabled/$YOUR_DOMAIN_NAME.TLD

To load the configuration in Nginx, you need to edit the /etc/nginx/nginx.conf file.

At the bottom of the http block, under include /etc/nginx/conf.d/*.conf;, add the line

include /etc/nginx/sites-enabled/*;

So the wohle http block looks like this:

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

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

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

Once that is done, test the configuration with sudo nginx -t, which should tell you that there aren't any errors. Finally, restart the Nginx process:

sudo systemctl restart nginx

Let's Encrypt

(For more up-to-date information, visit https://certbot.eff.org/instructions?ws=nginx&os=ubuntufocal)

Now that the server is set up to receive connections over HTTP on Port 80, the next step is to allow HTTPS to Nginx and automatically supply it with up-to-date SSL certs from Let's Encrypt.

First off, certbot needs to be installed. For our setup here, run the following commands:

sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot

After this is done, run certbot with the --nginx flag to automatically adjust Nginx's config files for your domain:

sudo certbot --nginx

Simply answer the questions, select the domain, make sure it can be reached over HTTP/:80 and certbot will change the Nginx configuration to redirect HTTP traffic to HTTPS and include the certificates.

Lastly, you just need to make sure certbot can renew certificates automatically, by issuing the following command:

sudo certbot renew --dry-run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment