Yacht is a web GUI to manage Docker containers, making deployment and management of resources 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 to http://127.0.0.1:8000/ in your browser and log in with 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 lists many applications that can be deployed with a single click or customized.

Using SSL/TLS is highly recommended when accessing Yacht over a local network, and essential when accessing it 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 versions of Ubuntu:

sudo apt-get install python-certbot-nginx

It is good practice to replace or clear the default webpage located at /var/www/html/.

Edit the site configuration at /etc/nginx/sites-available/default and set the domain name as shown below:

...
server_name example.com;
...

Test and restart NGINX, then run Certbot:

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

Follow the prompts and choose to redirect all HTTP traffic to HTTPS.

Back in the browser, navigate to https://example.com (replace with your actual domain).

To ensure the certificate renews automatically, add the following line to the root crontab -e on the host machine:

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

This command will attempt renewal once a week.

Stop and remove the container, then run it again with the certificate folder mounted:

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 previous configuration is preserved in the volume created earlier.

Open a shell inside the container:

sudo docker exec -it yacht /bin/bash

Edit the NGINX configuration file at /etc/nginx/nginx.conf and add the following bolded lines, replacing example.com with your domain:

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

Test access again in your browser using httpS://example.com:8000