Skip to content

Instantly share code, notes, and snippets.

@simonw
Last active December 4, 2019 17:47
Show Gist options
  • Select an option

  • Save simonw/63797bb10bb74e615695edd8f850844f to your computer and use it in GitHub Desktop.

Select an option

Save simonw/63797bb10bb74e615695edd8f850844f to your computer and use it in GitHub Desktop.
Files I use to run Datasette under systemd, inspired by https://github.com/simonw/datasette/issues/514#issuecomment-504662904
# This file lives in /etc/systemd/system/datasette.service
[Unit]
Description=Datasette
After=network.target
[Service]
Type=simple
User=ubuntu
Environment=GITHUB_CLIENT_ID=...
Environment=GITHUB_CLIENT_SECRET=...
WorkingDirectory=/home/ubuntu
ExecStart=/home/ubuntu/datasette-venv/bin/datasette serve -h 127.0.0.1 -p 8000 -m metadata.json \
--config sql_time_limit_ms:10000 \
--config facet_time_limit_ms:5000 \
twitter.db healthkit.db github.db
Restart=on-failure
[Install]
WantedBy=multi-user.target

Notes

I run everything as the ubuntu user (I should probably have a dedicated datasette user instead).

I created a virtual environment like this:

cd /home/ubuntu
python3 -mvenv datasette-venv

Then I installed Datasette like so:

/home/ubuntu/datasette-venv/bin/pip install datasette

My database files (twitter.db, healthkit.db, github.db) all live in the /home/ubuntu directory. So does a metadata.json file.

When I need to restart Datasette (due to changes to the service file or metadata) i run this:

sudo systemctl daemon-reload
sudo systemctl restart datasette.service
# This file lives in /etc/nginx/sites-available/subdomain.mydomain.com
server {
root /var/www/subdomain.mydomain.com/html;
index index.html;
server_name subdomain.mydomain.com;
location / {
if ($ssl_client_verify != SUCCESS) {
return 403;
}
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $host;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/subdomain.mydomain.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/subdomain.mydomain.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = subdomain.mydomain.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name subdomain.mydomain.com;
return 404; # managed by Certbot
}
@ipmb

ipmb commented Dec 4, 2019

Copy link
Copy Markdown

If you're on a recent version of Ubuntu, you can do something like this to avoid running as the ubuntu user without the hassle of setting up a new user:

DynamicUser = true
StateDirectory = datasette

This will create an ephemeral user for the service and create a writable directory in /var/lib/datasette that you can use to store state.

https://www.freedesktop.org/software/systemd/man/systemd.exec.html#DynamicUser=
https://www.freedesktop.org/software/systemd/man/systemd.exec.html#RuntimeDirectory=

There's a few extra settings you can use for easy security wins. I wrote about them here.

I also usually add these which gives you some extra info on resource usage:

CPUAccounting = true
MemoryAccounting = true
IPAccounting = true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment