From d38efa9a9d0aac0b966a128fe3b522d6741fc1dc Mon Sep 17 00:00:00 2001 From: Pablo Barton Date: Tue, 30 Mar 2021 09:28:13 -0400 Subject: [PATCH] Easier to deploy by avoiding merge conflicts in production --- .env.example => .env.dev.example | 13 +++++- .env.prod.example | 50 ++++++++++++++++++++ .gitignore | 3 ++ README.md | 40 ++++++++++------ bookwyrm/settings.py | 1 + certbot.sh | 19 ++++++++ docker-compose.yml | 2 + nginx/{default.conf => development} | 0 nginx/production | 72 +++++++++++++++++++++++++++++ 9 files changed, 186 insertions(+), 14 deletions(-) rename .env.example => .env.dev.example (75%) create mode 100644 .env.prod.example create mode 100644 certbot.sh rename nginx/{default.conf => development} (100%) create mode 100644 nginx/production diff --git a/.env.example b/.env.dev.example similarity index 75% rename from .env.example rename to .env.dev.example index 2397a5b1..5e605d74 100644 --- a/.env.example +++ b/.env.dev.example @@ -5,6 +5,7 @@ SECRET_KEY="7(2w1sedok=aznpq)ta1mc4i%4h=xx@hxwx*o57ctsuml0x%fr" DEBUG=true DOMAIN=your.domain.here +#EMAIL=your@email.here ## Leave unset to allow all hosts # ALLOWED_HOSTS="localhost,127.0.0.1,[::1]" @@ -26,14 +27,24 @@ POSTGRES_HOST=db MAX_STREAM_LENGTH=200 REDIS_ACTIVITY_HOST=redis_activity REDIS_ACTIVITY_PORT=6379 +#REDIS_ACTIVITY_PASSWORD=redispassword345 -# Celery config with redis broker +# Redis as celery broker +#REDIS_BROKER_PORT=6379 +#REDIS_BROKER_PASSWORD=redispassword123 CELERY_BROKER=redis://redis_broker:6379/0 CELERY_RESULT_BACKEND=redis://redis_broker:6379/0 +FLOWER_PORT=8888 +#FLOWER_USER=mouse +#FLOWER_PASSWORD=changeme + EMAIL_HOST="smtp.mailgun.org" EMAIL_PORT=587 EMAIL_HOST_USER=mail@your.domain.here EMAIL_HOST_PASSWORD=emailpassword123 EMAIL_USE_TLS=true EMAIL_USE_SSL=false + +# Set this to true when initializing certbot for domain, false when not +CERTBOT_INIT=false diff --git a/.env.prod.example b/.env.prod.example new file mode 100644 index 00000000..0013bf9d --- /dev/null +++ b/.env.prod.example @@ -0,0 +1,50 @@ +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY="7(2w1sedok=aznpq)ta1mc4i%4h=xx@hxwx*o57ctsuml0x%fr" + +# SECURITY WARNING: don't run with debug turned on in production! +DEBUG=false + +DOMAIN=your.domain.here +EMAIL=your@email.here + +## Leave unset to allow all hosts +# ALLOWED_HOSTS="localhost,127.0.0.1,[::1]" + +OL_URL=https://openlibrary.org + +## Database backend to use. +## Default is postgres, sqlite is for dev quickstart only (NOT production!!!) +BOOKWYRM_DATABASE_BACKEND=postgres + +MEDIA_ROOT=images/ + +POSTGRES_PASSWORD=securedbpassword123 +POSTGRES_USER=fedireads +POSTGRES_DB=fedireads +POSTGRES_HOST=db + +# Redis activity stream manager +MAX_STREAM_LENGTH=200 +REDIS_ACTIVITY_HOST=redis_activity +REDIS_ACTIVITY_PORT=6379 +REDIS_ACTIVITY_PASSWORD=redispassword345 + +# Redis as celery broker +REDIS_BROKER_PORT=6379 +REDIS_BROKER_PASSWORD=redispassword123 +CELERY_BROKER=redis://:${REDIS_BROKER_PASSWORD}@redis_broker:${REDIS_BROKER_PORT}/0 +CELERY_RESULT_BACKEND=redis://:${REDIS_BROKER_PASSWORD}@redis_broker:${REDIS_BROKER_PORT}/0 + +FLOWER_PORT=8888 +FLOWER_USER=mouse +FLOWER_PASSWORD=changeme + +EMAIL_HOST="smtp.mailgun.org" +EMAIL_PORT=587 +EMAIL_HOST_USER=mail@your.domain.here +EMAIL_HOST_PASSWORD=emailpassword123 +EMAIL_USE_TLS=true +EMAIL_USE_SSL=false + +# Set this to true when initializing certbot for domain, false when not +CERTBOT_INIT=false diff --git a/.gitignore b/.gitignore index 71fa61bf..cf88e987 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ #Node tools /node_modules/ + +#nginx +nginx/default.conf diff --git a/README.md b/README.md index 6dad4178..c11de3dc 100644 --- a/README.md +++ b/README.md @@ -91,10 +91,15 @@ Deployment ## Setting up the developer environment -Set up the environment file: +Set up the development environment file: ``` bash -cp .env.example .env +cp .env.dev.example .env +``` + +Set up nginx for development `nginx/default.conf`: +``` bash +cp nginx/development nginx/default.conf ``` For most testing, you'll want to use ngrok. Remember to set the DOMAIN in `.env` to your ngrok domain. @@ -108,7 +113,7 @@ docker-compose run --rm web python manage.py initdb docker-compose up ``` -Once the build is complete, you can access the instance at `localhost:1333` +Once the build is complete, you can access the instance at `http://localhost:1333` ### Editing static files If you edit the CSS or JavaScript, you will need to run Django's `collectstatic` command in order for your changes to have effect. You can do this by running: @@ -160,26 +165,35 @@ Instructions for running BookWyrm in production: - Get the application code: `git clone git@github.com:mouse-reeve/bookwyrm.git` -- Switch to the `production` branch +- Switch to the `production` branch: `git checkout production` -- Create your environment variables file - `cp .env.example .env` - - Add your domain, email address, SMTP credentials - - Set a secure redis password and secret key - - Set a secure database password for postgres +- Create your environment variables file, `cp .env.prod.example .env`, and update the following: + - `SECRET_KEY` | A difficult to guess, secret string of characers + - `DOMAIN` | Your web domain + - `EMAIL` | Email address to be used for certbot domain verification + - `POSTGRES_PASSWORD` | Set a secure password for the database + - `REDIS_ACTIVITY_PASSWORD` | Set a secure password for Redis Activity subsystem + - `REDIS_BROKER_PASSWORD` | Set a secure password for Redis queue broker subsystem + - `FLOWER_USER` | Your own username for accessing Flower queue monitor + - `FLOWER_PASSWORD` | Your own secure password for accessing Flower queue monitor - Update your nginx configuration in `nginx/default.conf` - Replace `your-domain.com` with your domain name - - If you aren't using the `www` subdomain, remove the www.your-domain.com version of the domain from the `server_name` in the first server block in `nginx/default.conf` and remove the `-d www.${DOMAIN}` flag at the end of the `certbot` command in `docker-compose.yml`. - - If you are running another web-server on your host machine, you will need to follow the [reverse-proxy instructions](#running-bookwyrm-behind-a-reverse-proxy) +- Configure nginx + - Make a copy of the production template config and set it for use in nginx `cp nginx/production nginx/default.conf` + - Update `nginx/default.conf`: + - Replace `your-domain.com` with your domain name + - If you aren't using the `www` subdomain, remove the www.your-domain.com version of the domain from the `server_name` in the first server block in `nginx/default.conf` and remove the `-d www.${DOMAIN}` flag at the end of the `certbot` command in `docker-compose.yml`. + - If you are running another web-server on your host machine, you will need to follow the [reverse-proxy instructions](#running-bookwyrm-behind-a-reverse-proxy) +- If you need to initialize your certbot for your domain, set `CERTBOT_INIT=true` in your `.env` file - Run the application (this should also set up a Certbot ssl cert for your domain) with `docker-compose up --build`, and make sure all the images build successfully - If you are running other services on your host machine, you may run into errors where services fail when attempting to bind to a port. See the [troubleshooting guide](#port-conflicts) for advice on resolving this. - When docker has built successfully, stop the process with `CTRL-C` -- Comment out the `command: certonly...` line in `docker-compose.yml`, and uncomment the following line (`command: renew ...`) so that the certificate will be automatically renewed. -- Uncomment the https redirect and `server` block in `nginx/default.conf` (lines 17-48). +- If you set `CERTBOT_INIT=true` earlier, set it now as `CERTBOT_INIT=false` so that certbot runs in renew mode - Run docker-compose in the background with: `docker-compose up -d` - Initialize the database with: `./bw-dev initdb` +- Set up schedule backups with cron that runs that `docker-compose exec db pg_dump -U ` and saves the backup to a safe location Congrats! You did it, go to your domain and enjoy the fruits of your labors. diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 146d4fff..ded119f8 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -98,6 +98,7 @@ WSGI_APPLICATION = "bookwyrm.wsgi.application" # redis/activity streams settings REDIS_ACTIVITY_HOST = env("REDIS_ACTIVITY_HOST", "localhost") REDIS_ACTIVITY_PORT = env("REDIS_ACTIVITY_PORT", 6379) +REDIS_ACTIVITY_PASSWORD = env("REDIS_ACTIVITY_PASSWORD", None) MAX_STREAM_LENGTH = int(env("MAX_STREAM_LENGTH", 200)) STREAMS = ["home", "local", "federated"] diff --git a/certbot.sh b/certbot.sh new file mode 100644 index 00000000..6d2c3cd9 --- /dev/null +++ b/certbot.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +source .env; + +if [ "$CERTBOT_INIT" = "true" ] +then + certonly \ + --webroot \ + --webroot-path=/var/www/certbot \ + --email ${EMAIL} \ + --agree-tos \ + --no-eff-email \ + -d ${DOMAIN} \ + -d www.${DOMAIN} +else + renew \ + --webroot \ + --webroot-path \ + /var/www/certbot +fi diff --git a/docker-compose.yml b/docker-compose.yml index 3ee9037f..60816cc0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,6 +20,8 @@ services: - pgdata:/var/lib/postgresql/data networks: - main + ports: + - 5432:5432 web: build: . env_file: .env diff --git a/nginx/default.conf b/nginx/development similarity index 100% rename from nginx/default.conf rename to nginx/development diff --git a/nginx/production b/nginx/production new file mode 100644 index 00000000..c5d83cbf --- /dev/null +++ b/nginx/production @@ -0,0 +1,72 @@ +upstream web { + server web:8000; +} + +server { + listen [::]:80; + listen 80; + + server_name your-domain.com www.your-domain.com; + + location ~ /.well-known/acme-challenge { + allow all; + root /var/www/certbot; + } + +# # redirect http to https +# return 301 https://your-domain.com$request_uri; +# } +# +# server { +# listen [::]:443 ssl http2; +# listen 443 ssl http2; +# +# server_name your-domain.com; +# +# # SSL code +# ssl_certificate /etc/nginx/ssl/live/your-domain.com/fullchain.pem; +# ssl_certificate_key /etc/nginx/ssl/live/your-domain.com/privkey.pem; +# +# location ~ /.well-known/acme-challenge { +# allow all; +# root /var/www/certbot; +# } +# +# location / { +# proxy_pass http://web; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header Host $host; +# proxy_redirect off; +# } +# +# location /images/ { +# alias /app/images/; +# } +# +# location /static/ { +# alias /app/static/; +# } +} + +# Reverse-Proxy server +# server { +# listen [::]:8001; +# listen 8001; + +# server_name your-domain.com www.your-domain.com; + +# location / { +# proxy_pass http://web; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header Host $host; +# proxy_redirect off; +# } + +# location /images/ { +# alias /app/images/; +# } + +# location /static/ { +# alias /app/static/; +# } +# }