Yacht is a web GUI to manage Docker containers and make deployments and management of all resources very easy [Link].

See also the post about Portainer [Link].

See also the post about CasaOS [Link].

Installation:

sudo apt update
sudo apt install docker.io
sudo docker volume create yacht-fs
sudo docker run -d --name yacht -p 8000:8000 -v /var/run/docker.sock:/var/run/docker.sock -v yacht-fs:/config selfhostedpro/yacht

Navigate on your browser to http://127.0.0.1:8000/ and enter the default credentials: [email protected] and pass.

Immediately change the default password and add the following template:

https://raw.githubusercontent.com/SelfhostedPro/selfhosted_templates/yacht/Template/template.json

This template will list many applications that can be deployed with a single click or customized.

It is highly recommended to use SSL/TLS if you are accessing Yacht over a local network and essential if remotely over the internet.

On a host machine running Ubuntu 20.04 install:

sudo apt install nginx
sudo apt install certbot
sudo apt-get install python3-certbot-nginx

For older version of Ubuntu:

sudo apt-get install python-certbot-nginx

It is always good to change or clean the default webpage located at /var/www/html/.

Edit the site configuration /etc/nginx/sites-available/default and type the domain address as shown below:

...
server_name example.com;
...

Test and restart NGINX and run the Certbot:

sudo nginx -t && sudo nginx -s reload
sudo certbot --nginx -d example.com

Respond to prompts and chose to Redirect any HTTP traffic to HTTPS.

Back to the browser change the address to https://example.com (of course replace the example).

Make sure the certificate will be renewed automatically by adding this line to the crontab -e of the root on the host machine:

0 0 * * * /usr/bin/certbot renew --quiet

The command above will try to renew once a week.

Remove the container and run it again, now mounting the certificate folder in it:

sudo docker stop yacht
sudo docker rm yacht
docker run -d --name yacht -p 8000:443 -v /var/run/docker.sock:/var/run/docker.sock -v /etc/letsencrypt/:/etc/letsencrypt/ -v yacht-fs:/config selfhostedpro/yacht

Any preview configuration was preserved in the volume created earlier.

Get a shell in the container by issuing:

sudo docker exec -it yacht /bin/bash

Edit the NGINX configuration file /etc/nginx/nginx.conf and add the following bolded lines replacing the domain.com:

worker_processes 1;

user abc abc;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    ### Set http options
    # fallback in case we can't determine a type
    default_type application/octet-stream;
    access_log /var/log/nginx/access.log combined;
    sendfile on;
    keepalive_timeout 5;

    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

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

    upstream api_server {
        server unix:/tmp/gunicorn.sock fail_timeout=0;
    }

    # Paths for Vue and FastAPI
    server {
        listen *:8000;

        # Vue
        location / {
            root /app;
            index index.html;
            try_files $uri $uri/ /index.html;
        }
        error_page 500 502 503 504 /50x.html;

        server_name dfttest.duckdns.org;

        listen [::]:443 ssl ipv6only=on;
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

   location = /50x.html {
            root /usr/share/nginx/html;
        }

        # FastAPI
        location /api/ {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_set_header Host $http_host;
            # Set this so that the app updates function doesn't timeout
            
            proxy_read_timeout 300s;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "Upgrade";

            client_body_temp_path /var/www/client_body_temp;
            proxy_temp_path /var/www/proxy_temp;
            # we don't want nginx trying to do something clever with
            # redirects, we set the Host: header above already.
            proxy_redirect off;
            proxy_pass http://api_server/;
        }
    }
}

Test the configuration and reload the service.

sudo nginx -t && sudo nginx -s reload

Teste accessing it again with your browser but using httpS://example.com:8000