cargohold lets you distribute and receive files on your own terms. Create private links that let other people upload files to you, or send them a link that lets them download or view the files you want them to have.


Required dependencies

  • nginx
  • uwsgi
  • uwsgi-plugin-python3
  • sqlite3
  • python3
  • python3-jinja2
  • python3-passlib if using LocalBasicAuth

Basic infrastructure

  • Create a directory where cargohold will store the uploaded files
  • Set the directory's owner to the user you want uwsgi to run the application under
  • Edit backend/config.py to match your setup
  • Edit configs/nginx.config to match your setup
    • Note that the client_max_body_size directive will limit the maximum size of a single uploaded file
  • Install configs/nginx.config to /etc/nginx/sites-enabled/
  • Edit configs/uwsgi.ini to match your setup
    • Note that the limit-post option will limit the maximum size of a single uploaded file
  • Install configs/uwsgi.ini to /etc/uwsgi/apps-enabled/

Initial configuration

  • Create the cargohold database by running sqlite3 cargohold.db3 < backend/cargohold.sql
  • Update backend/config.py with the path to your database
  • If you want to use the web administration interface, select an authentication provider in backend/config.py. Some providers might need additional configuration. See the section on Authentication for more details. TBD: Extend this.


The database stores the the following data for each alias

  • Alias: The identifier to be appended to the base URL
  • User: The user the identifier belongs to, for administrative and storage accounting purposes
  • Real path: The on-disk directory name where, when prepended with both the fileroot and optionally, the userdir, the data is stored. Multiple aliases may point to the same real path.
  • Access level: The access level this alias permits to the real path. A string consisting of any of the characters c (Create / Upload), r (Retrieve / Read), u (Update), d (Delete) in any order.
  • Storage limit: Per-alias storage limit (applied when uploading)
  • Display mode: Parameter to the file-listing interface, customizing end-user layout.

The storage limit for each alias (applied when uploading files) is calculated as the minimum of the following parameters

  • Global disk free space
  • global_limit in backend/config.py
  • The per-user limit minus the disk size currently used by the user, if the per-user limit is not 0
  • The per-alias limit minus the disk size currently used by the files in the alias, if the per-alias limit is not 0 / NULL


cargohold integrates somewhat tightly with nginx using the X-Accel-Redirect mechanism. Other httpds may provide a similar mechanism, which will need to be called out to in the playout() routine in main.py.


This projects provides multiple methods to identify and authenticate users, including delegating authentication to external software. Implementing custom authentication methods is possible and patches contributing such are welcome.

The following authentication methods are currently available:

  • NoneAuth: The default. Does not support any logins. Use this if you want to manage cargohold exclusively via the command line or direct database interfaces
  • ExternalAuth: Delegate authentication to an external entity. Expects the authenticated user (if any) in the REMOTE_USER environment variable
  • LocalBasicAuth: Internal implementation of HTTP Basic Auth using htpasswd-style user databases
  • RemoteCookieAuth: Custom authentication scheme validating a domain-wide cookie against an external service