Closed MaybeThisIsRu closed 1 year ago
Oh I see it is a dependency...
https://github.com/jamesvandyne/tanzawa/blob/main/requirements.txt#L9
Perhaps the docs need updating?
I guess a better issue title is: separate docs for self-hosting Tanzawa on a VPS via Docker.
Yes - the readme just uses the development server.
I'm using Gunicorn myself for my blog, but I'm planning to move the project to uWSGI because it's more than just an application server, including things like queues, which will allow me to have async tasks without adding celery/redis etc...
There's some example configurations in the packer scripts...but it still needs some work as I figure out the best way to handle ENV files with docker-compose/django-environ and such.
Ah dang. I'd love to see this. I think I'm ready to jump back into IndieWeb with Tanzawa. As long as my budget VPS handles it fine...
I did try to set it up the day that I opened all these issues (3-4 days ago?) but was lost on what to do once the development/configuration side of things is sorted out.
Should this be closed in favour of #142 then?
Tanzawa should run on any budget VPS, I'd reckon. My site is using a $5 / month DO droplet. I feel like this is a separate issue than #142. This can be closed by some proper documentation / instructions for how to setup Tanzawa for production use. While the other one is more about automating all of it.
The main thing I need to figure out in order to write the docs is, I want both "bare metal" installs and Docker/Docker-compose installs to use the same .env
file in, ideally, same location...so I've got to do some fiddling with that all to make sure it works as expected.
Pasting some of my config files that I'm using with Ubuntu / Gunicorn / Apache. In the future, Tanzawa instructions will be assuming nginx and won't be using Apache. I am only using Apache now because this server was originally setup using a 1-click Wordpress Droplet.
Serves staticfiles and forwards requests to Gunicorn socket running at /run/jvd.sock
. Rewrite rules are from certbot.
/etc/apache2/sites-enabled/default.conf
is as below:
UseCanonicalName On
<VirtualHost *:80>
ServerAdmin james@jamesvandyne.com
ServerName jamesvandyne.com
ServerAlias www.jamesvandyne.com
ProxyPreserveHost On
ProxyTimeout 360
ProxyPass /static !
Alias /static "/var/www/jvd/tanzawa/staticfiles"
<Directory "/var/www/jvd/tanzawa/staticfiles">
Options -Indexes
Order deny,allow
Require all granted
Allow from all
</Directory>
RequestHeader set X-Forwarded-Proto expr=%{REQUEST_SCHEME}
RequestHeader set X-Forwarded-SSL expr=%{HTTPS}
ProxyPass / unix:/run/jvd.sock|http://127.0.0.1/ disablereuse=On connectiontimeout=360 timeout=360
ProxyPassReverse / unix:/run/jvd.sock|http://127.0.0.1/
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{SERVER_NAME} =jamesvandyne.com [OR]
RewriteCond %{SERVER_NAME} =www.jamesvandyne.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
These are the service
and socket
config files that I use on my server. It allows me to start / stop Tanzawa (jvd) on my droplet with commands like systemctl restart jvd.service
# /etc/systemd/system/jvd.socket
[Unit]
Description=jvda gunicorn socket
[Socket]
ListenStream=/run/jvd.sock
# Our service won't need permissions for the socket, since it
# inherits the file descriptor by socket activation
# only the nginx daemon will need access to the socket
SocketUser=www-data
# Optionally restrict the socket permissions even more.
# SocketMode=600
[Install]
WantedBy=sockets.target
The .service
file is what actually executes gunicorn / the app server with a fullpath to the venv
gunicorn binary. Minimum 4 workers is required (the -w 4
option), but should work fine with more.
# /etc/systemd/system/jvd.service
[Unit]
Description=jvd service
Requires=jvd.socket
After=network.target
[Service]
Type=notify
# the specific user that our service will run as
User=www-data
Group=www-data
# another option for an even more restricted service is
# DynamicUser=yes
# see http://0pointer.net/blog/dynamic-users-with-systemd.html
RuntimeDirectory=gunicorn
WorkingDirectory=/var/www/jvd/tanzawa/apps/
ExecStart=/var/www/jvd/tanzawa/venv/bin/gunicorn core.wsgi -w 4
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target
I'm running it with a nginx proxy in front (cloudron.io) so I'm wondering how I could use the non-development production HTTP server in my context (docker with nginx HTTP proxy sitting in front of every of my containers)
@rmdes Running a production should be a matter of:
manage.py runserver
to something like gunicorn --bind 0.0.0.0:8000 -w 4
(you'll want to double check if it should be 0.0.0.0
or 127.0.0.1
so as to not expose the gunicorn server to the internet. The gunicorn binary should be located in the virtualenv's bin
directory.staticfiles
location in Docker so nginx can access it.media
location in Docker so nginx can access it (this may already be on your local file system)packer/base_server/templates/
might serve as a good example?I'll put proper deployment docs as my next priority.
That looks very similar to what I'm doing with my project at work (and why wouldn't it -- literally the point of Django π).
It can definitely be made easier by supplying a docker compose config that includes the nginx static+media files proxy.
Yes - I've got a base docker-compose file in packer/base_server/templates/docker-compose.yml that sets up the media/staticfiles mounts and it worked last I used it.
In this base_server configuration, I decided to run nginx on the server, rather than via docker-compose because I remember it being difficult to get dockerized-nginx and let's encrypt playing nicely... it worked at one point, but I know there's more work required around handling environment variables to finish it up.
Is there an update on this? I'm itching to get started. :sweat_smile:
@MaybeThisIsRu Not quite yet. Been busy preparing for a work trip. Hoping to get some instructions written on the plane this weekend. I'll ping you in the PR for review, if that's ok? ππ»
Yes, thatβs absolutely fine!
Started on the running with Docker instructions in #227 . I think the "current" Docker image needs to be rebuilt before they're ready for testing out.
@MaybeThisIsRu I've got some base instructions for setting up an Unbuntu server with Docker and Tanzawa running via docker / docker-compose. When you have a minute, can you try running through the install instructions here and let me know if they work for you? π
Thank you!! I'll get to those during the week now. Quite busy the rest of the weekend.
I've written instructions for how to deploy Tanzawa using Fly.io, which is much easier / faster than using a VPS that you need to manage yourself. The README now indicates that the runserver is used for development. Closing this issue as the main request has been resolved :-)
So the readme just uses the development web server. I am not sure if that's what is supposed to be used on production as well since it is after all the docs for setup...
gunicorn
is what I use for our Django project @ work and I suppose that's the de-facto WGSI web server in Python-land?