Setting up a paste service with Vim, rsync, and nginx
This page guides you through setting up a paste service with Vim,
rsync, and nginx. This guide uses Vim’s :TOhtml
command to
convert source code to HTML with syntax highlighting.
Page overview
- Reasoning for this guide
- Page conventions
- Assumptions
- Requirements on your local machine
- Preparing your server
- Preparing your local machine
- Using the paste service
Reasoning for this guide
I’m writing this guide, not only because it’s a really basic way to show code to friends, but also because I love writing my own little tools and learning about web servers and network infrastructure.
Page conventions
- Note: Signifies additional information
- Tip: Signifies an alternative procedure for completing a step
- Warning: Signifies that damage, such as data loss, may occur
- Example: Shows how a procedure would be performed in a real scenario
Inline code and code blocks
: Signify package names, filenames, file contents, or commandsexample.com
: Replace this with your domain name.
Assumptions
This guide assumes:
- You are using a Ubuntu server on a DigitalOcean droplet
- You are using nginx to serve your web content
- You manage your SSL/TLS certificates with certbot
- You have your domain name setup with DigitalOcean’s name servers
- You have your SSH keys setup with your server
- You have root access to your server
Requirements on your local machine
- rsync
- vim
Preparing your server
You need to create a directory for the files you paste, a landing
page in case users decide to navigate to your paste.
subdomain, configure nginx to serve the paste directory, and setup
SSL/TLS for your domain.
This section consists of the following topics:
- Setting up DNS records on DigitalOcean
- Creating a new domain directory
- Creating a landing page for the paste service
- Configuring nginx
- Setting up your paste service domain with certbot
Setting up DNS records on DigitalOcean
Setting up DNS records for paste.example.com
allows
DigitalOcean to know about your new subdomain.
To setup DNS records on DigitalOcean
- Add an A record for
paste.example.com
to your DigitalOcean droplet - Add an AAAA record for
paste.example.com
to your DigitalOcean droplet
Note: You may need to wait a few minutes for the DNS records to update.
Creating a new domain directory
To share the files you have pasted, you need to create a directory for your files to reside in.
To create a new domain directory
- SSH into your server
- Run
sudo mkdir -p /var/www/paste.example.com
- Run
sudo chown -R $USER:$USER /var/www/paste.example.com
- Run
sudo chmod -R 755 /var/www/paste.example.com
Configuring nginx
You need to setup a subdomain for your domain in nginx. In this
guide, we use the domain, example.com
, and the subdomain,
paste.
. The full URL for our pasting service is
paste.example.com
.
Ensure you replace example.com
with your own domain when
following this guide.
To configure nginx
Add the following in
/etc/nginx/sites-available/paste.example.com
as root:server { server_name paste.example.com; root /var/www/paste.example.com; index index.txt; location / { try_files $uri $uri/ =404; } }
Run the following command:
sudo ln -s /etc/nginx/sites-available/paste.example.com /etc/nginx/sites-enabled/paste.example.com
Run
sudo systemctl restart nginx
Setting up your paste service domain with certbot
Setting up SSL/TLS with certbot stops browsers from telling the user they are on an insecure connection.
To setup your paste service domain with certbot
- Run
sudo certbot
- Follow the prompts
- Run
sudo systemctl restart nginx
Preparing your local machine
You need to create a local paste directory, and add a function and
command to your ~/.vimrc
file.
This section consists of the following topics:
- Creating a paste directory
- Creating a landing page for the paste service
- Setting up a generic file-pasting script
- Setting up a generic file-pasting script for plaintext files
- Setting up a generic file-synchronizing script
- Setting up Vim
Creating a paste directory
The paste directory allows you to keep a collection of files locally. The local paste directory synchronizes with your remote paste directory using rsync.
To create a paste directory
- Run
mkdir -p ~/dev/paste
Creating a landing page for the paste service
Users may get curious and wander away from
paste.example.com/some-file.py
. One of the places they may
go is paste.example.com
, so creating a landing page for
this URL is nicer than getting a 404 error.
To create a landing page for the paste service
Run the following command:
echo "Hey there! It looks like you found my paste service! Unfortunately, there isn't much here!" > ~/dev/paste/index.txt
Warning: If you delete the
~/dev/paste/index.txt
file, the your landing page disappears the next time you synchronize your~/dev/paste
directory.
Setting up a generic file-pasting script
This script not only supports code snippets with syntax highlight, but it also supports generic file pasting, such as the pasting of images, gifs, videos, etc.
To setup a generic file-pasting script
Add the following to a file called
pupload
:#!/bin/sh file="$@" domain="https://paste.example.com/" cp $file ~/dev/paste/$file cd ~/dev/paste rsync -a --delete ./$file user@example.com:/var/www/paste.example.com/ echo "Paste URL: $domain$file"
Run
chmod u+x pupload
Move the
pupload
to a directory on your$PATH
Setting up a generic file-pasting script for plaintext files
This script appends a .txt
to the end of the filename,
so other people can view the file in their browser without downloading
the file.
To setup up a generic file-pasting script for plaintext files
Add the following to a file called
ptxt
:file="$@" filetxt=$file.txt domain="https://paste.example.com/" cp $file ~/dev/paste/$filetxt cd ~/dev/paste rsync -a --delete ./$filetxt user@example.com:/var/www/paste.example.com/ echo "Paste URL: $domain$filetxt"
Run
chmod u+x ptxt
Move the
ptxt
to a directory on your$PATH
Setting up a generic file-synchronizing script
When removing or modifying files in your ~/dev/paste/
directory, you must synchronize after, so all files on your server
update.
To setup a generic file-synchronizing script
Add the following to a file called
psync
:#!/bin/sh cd ~/dev/paste rsync -a --delete ./ user@example.com:/var/www/paste.example.com/ echo "Files synchronized"
Run
chmod u+x psync
Move the
psync
to a directory on your$PATH
Setting up Vim
Vim commands make uploading and synchronizing your paste directory to your remote server convenient. They remove the need to exit Vim to run shell scripts.
To setup Vim
Add the following contents to your
~/.vimrc
:function! PasteSync() call system('psync') endfunction function! PasteUpload() TOhtml let filename = expand("%:t") silent! execute 'write!' '~/dev/paste/' . filename call PasteSync() q! echo 'Paste link: https://paste.example.com/' . filename endfunction command PasteSync call PasteSync() command PasteUpload call PasteUpload()
Note: You need to replace
user
in thePasteSync()
function with your own SSH username.
Using the paste service
You can use the two commands from the previous section to upload and synchronize files to your remote paste directory.
This section consists of the following topics:
- Uploading a code snippet from Vim
- Uploading a generic file
- Uploading a generic file in plaintext format
- Removing a file
Uploading a code snippet from Vim
The Vim configuration from the previous section allows us to upload Vim buffers as code snippets.
To uploading a code snippet
- Open a file in Vim
- Run
:PasteUpload
- Share the URL generated at the bottom of the screen
Uploading a generic file
The pupload
script from the Setting up a generic
file-pasting script section allows you to paste any file to your
server.
To upload a generic file
- Run
pupload your-file
Uploading a generic file in plaintext format
Sometimes, you want to view the contents of a file in your browser.
Adding “.txt
” at the end of a filename allows your browser
to render the contents of the file if it is in a plaintext format.
To upload a generic file in plaintext format
- Run
ptxt your-file
Note: This appends a .txt
to your file.
So, if your file is named code.py
, the file is renamed to
code.py.txt
. When you click the link that is generated, you
can view the contents of the file in your browser, instead of being
prompted to download the file.
Removing a file
rsync removes the need to SSH into your server to remove a directory
by synchronizing a directory’s state using the --delete
flag.
To remove a file
cd ~/dev/paste
rm file-you-want-to-remove.py
- Run
psync