key: sftp
title: SFTP
icon: '/_assets/icons/ultraviolet-nas.svg'
banner: '/_assets/storage/ssh.jpg'
description: Store the wiki's content as ordinary files on a remote server over SSH. The same tree the local disk target writes, on a machine that is not this one. Meant as a copy rather than a source, so it cannot be chosen under Content Delivery.
assetDelivery:
  isDirectAccessSupported: false
  # -> A place to keep a copy of the site's content, not one to serve it from: every image on every
  #    page would be an SSH round trip. Written to, exported to and imported from as normal; simply
  #    never offered under Content Delivery.
  isDeliverySupported: false
contentTypes:
  defaultTypesEnabled: ['pages', 'images', 'documents', 'others', 'large']
props:
  host:
    type: String
    title: Host
    default: ''
    hint: Hostname or IP of the remote SSH server.
    icon: dns
    order: 1
  port:
    type: Number
    title: Port
    default: 22
    hint: SSH port of the remote server.
    icon: ethernet-off
    order: 2
  authMode:
    type: String
    title: Authentication Method
    default: 'privateKey'
    hint: Whether to use Private Key or Password-based authentication. A private key is highly recommended for best security.
    icon: grand-master-key
    enum:
      - privateKey|Private Key
      - password|Password
    enumDisplay: buttons
    order: 3
  username:
    type: String
    title: Username
    default: ''
    hint: Username for authentication.
    icon: test-account
    order: 4
  privateKey:
    type: String
    title: Private Key Contents
    default: ''
    hint: Contents of the private key, including the BEGIN and END lines.
    icon: key
    multiline: true
    sensitive: true
    order: 5
    if:
      - { key: 'authMode', eq: 'privateKey' }
  passphrase:
    type: String
    title: Private Key Passphrase
    default: ''
    hint: Passphrase if the private key is encrypted, leave empty otherwise.
    icon: password
    sensitive: true
    order: 6
    if:
      - { key: 'authMode', eq: 'privateKey' }
  password:
    type: String
    title: Password
    default: ''
    hint: Password for authentication.
    icon: password
    sensitive: true
    order: 6
    if:
      - { key: 'authMode', eq: 'password' }
  basePath:
    type: String
    title: Base Directory Path
    default: '/var/wiki'
    hint: Where this site's folder tree is written on the remote server. It must already exist and be writable by the user above. Give each site its own path unless you turn on Add Site ID Prefix under Configuration.
    icon: symlink-directory
    order: 7
actions:
  exportAll:
    label: Export Everything
    hint: Write a copy of every page and asset this target is configured to hold to the remote server, overwriting whatever is already there. Nothing in the database is changed and nothing is moved, so this is how content created before the target was enabled gets onto it.
    icon: this-way-up
  importAll:
    label: Import Everything
    hint: Take every page and asset on the remote server that the wiki does not have yet into the wiki. A file is imported as a page if its extension is one of the site's Page Extensions, or if it declares an editor in its front matter; everything else is imported as an asset. Anything already at the same path is left alone on both sides, so this is safe to run again.
    icon: database-daily-import
  importAllOverwrite:
    label: Import Everything and Overwrite
    hint: The same walk, with the remote server winning every collision. For a restore, or a tree edited on the server that is meant to be taken as the new truth.
    warn: This replaces what the wiki currently has wherever a remote file lands on it. An overwritten page keeps its previous version in its history, but a file has none - the bytes it replaces are gone from every storage target holding them.
    icon: database-restore
