As an avid personal photographer, I’m always looking for good ways to display my photos. I’d prefer not to host my photos on Instagram, Flicker or one of the commercial sites.

The primary reason for this is most of them its almost impossible to get your photos off these sites.

So looking around at the self hosted arena after trying a few options I came out with Chevereto

Chevereto Image Hosting script – Self-hosted image hosting
An image hosting script that allows you to get your own image hosting website. It’s your hosting and your rules, say goodbye to the closures and restrictions.

Chevereto is a modern web app, it scales on devices has a solid upload interface for multiple images. Its quick and its deployable via script.

There is a free version, however i’ve gone for the personal version which has a cost involved.

What do I have setup?

The setup is pretty basic, the config however was a pain on the nginx side. The usual problems of getting https to https reverse proxy working and having all the css and images flow through as well.

The site is accessed using which uses external facing DNS ( and LetsEncrypt for SSL certificates.

This hits an NGINX reverse proxy (with some firewalls, double nat and other systems not listed here). Which forwards the traffic to my self hosted Chevereto Server which runs on top of Nginx which is listening on port 443 using a locally bound self served certificate. (so internally the server runs on SSL as well.)

The Chevereto server needs a DB to back out to, and I  have a separate MariaDB server which Chevereto uses to store data.

This post I’ll show my configs (IP’s changed to protect the innocent) and how I set this up.


Sure, pick holes, its what the internet does, I’m putting this up here because it might help someone. I can’t spell, my grammar is terrible and I may not have made the perfect setup like you. Just remember. Not everyone is as perfect as you, and as such this is how we learn..

Before you start

You will need a public DNS entry setup pointing to a public IP on the server you’re going to set this up on. Mine is I’m not going to cover how to do that here.

External Facing Reverse Proxy

The External facing NginX reverse proxy has the routers, firewalls and DNS setup accordingly,

The configs are held on my system under /etc/nginx/sites-available/ and symlinked to /etc/nginx/sites-enabled

I’ve used certbot to generate the necessary LetsEncrypt certs looks like this

server {large_client_header_buffers 4 16k;server_name;# The internal IP of the VM that hosts your Apache configset $upstream; location / { proxy_pass_header Authorization; proxy_pass https://$upstream; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Connection “”; proxy_buffering off; client_max_body_size 20000; proxy_read_timeout 36000s;}listen 443 ssl; # managed by Certbotssl_certificate /etc/letsencrypt/live/; # managed by Certbotssl_certificate_key /etc/letsencrypt/live/; # managed by Certbotinclude /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbotssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot}server {    if ($host = {        return 301 https://$host$request_uri;} # managed by Certbotserver_name;     listen 80;     return 404; # managed by Certbot}

This config both passes the html and more importantly the CSS and images from the internal server to the internet.

Internal NginX server

Hosting the Chevereto server on prior to running. There is a good install guide to get PHP and NGINX running on Ubuntu 20.04 here

How To Install Linux, Nginx, MySQL, PHP (LEMP stack) on Ubuntu 20.04 | DigitalOcean
The LEMP software stack is a group of software that can be used to serve dynamic web pages and web applications written in PHP. This is an acronym that describes a Linux operating system, with an Nginx (pronounced like “Engine-X”) web server. The backend data is stored in a MySQL database, and dynam…

The /etc/nginx/nginx.conf looks as follows

user www-data;worker_processes auto;pid /run/;include /etc/nginx/modules-enabled/*.conf; 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;    include /etc/nginx/mime.types;    default_type application/octet-stream;    ##    # SSL Settings    ##    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # 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;    ##    # Virtual Host Configs    ##    include /etc/nginx/conf.d/*.conf;    include /etc/nginx/sites-enabled/*;}

The recommended setting for me here was

 events {    worker_connections 768;    # multi_accept on; }

Which fixed some errors  shown in the /var/log/nginx/error.log

The default NGINX Server listens on Port 443

# Default server configuration#server {    listen 443 ssl;    listen [::]:443 ssl;    include snippets/self-signed.conf;    include snippets/ssl-params.conf;    server_name _;    root /var/www/html;    index index.php index.html index.htm index.nginx-debian.html;location ~ \.php$ {    include snippets/fastcgi-php.conf;    fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;# Context limitsclient_max_body_size 20M;# CORS header (avoids font rendering issues)location ~* /.*\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js)$ {  add_header Access-Control-Allow-Origin "*";}# Pretty URLs location / {  index index.php;  try_files $uri /index.php$is_args$query_string;}}

The SSL Config is held in the snippets lines

    include snippets/self-signed.conf;    include snippets/ssl-params.conf;

snippets/self-signed.conf contain the self signed certificates created using SSL

How To Create a Self-Signed SSL Cert for Nginx in Ubuntu 18.04 | DigitalOcean
In this guide, we will show you how to set up a self-signed SSL certificate for use with an Nginx web server on an Ubuntu 18.04 server.

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

The general ss-params are contained in


ssl_protocols TLSv1.2;ssl_prefer_server_ciphers on;ssl_dhparam /etc/ssl/certs/dhparam.pem;ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0ssl_session_timeout  10m;ssl_session_cache shared:SSL:10m;ssl_session_tickets off; # Requires nginx >= 1.5.9ssl_stapling on; # Requires nginx >= 1.3.7ssl_stapling_verify on; # Requires nginx => 1.3.7resolver valid=300s;resolver_timeout 5s;add_header X-Frame-Options DENY;add_header X-Content-Type-Options nosniff;add_header X-XSS-Protection "1; mode=block";

This should get NGINX working on the Chevereto server and you’re ready to deploy the software.

Installing Chevereto

Upload the installer

  • to your target destination (usually the public_html folder).
  • Open your website at /installer.php and follow the process.

The installer will prompt with steps to install the software, after that it will download the software, extract it and it will post to /install the data previously provided.

Edit the app/settings.php

The settings for the the server are held in the aptly named settings.php

NOTE: When editing there is no trailing /?> at the end of the php file

vi app/settings.php

<?php $settings['db_host'] = '';$settings['db_port'] = '3306'; $settings['db_name'] = 'chevereto'; $settings['db_user'] = 'chevereto'; $settings['db_pass'] = 'yourpaswordhere';$settings['db_table_prefix'] = 'chv_';$settings['db_driver'] = 'mysql';$settings['db_pdo_attrs'] = [];$settings['debug_level'] = 1;$settings['https'] = TRUE;// Use X-Forwarded-For HTTP Header to Get Visitor's Real IP Addressif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {    $http_x_headers = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );    $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];}

I added the lines below

$settings['https'] = TRUE;// Use X-Forwarded-For HTTP Header to Get Visitor's Real IP Addressif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {    $http_x_headers = explode( ',', $_SERVER['HTTP_X_FORWARDED_FOR'] );    $_SERVER['REMOTE_ADDR'] = $http_x_headers[0];}

At this point I was able to login internally and externally

By davidfield

Tech Entusiast