Deploy your site

So far, you’ve been accessing your site locally. Now, it’s time to deploy it.

Deployment makes your site publicly accessible by moving it to a production server. Upon deployment, your site becomes accessible worldwide.

In this section of the tutorial, you’ll use two platforms to deploy your site. You’ll host your site on fly.io and serve your site’s images on Backblaze.

You can use fly.io to host your site and serve your images. However, storing your images on a platform other than the one hosting your site provides better performance, security, and reliability.

Note

In this tutorial, you’ll see “yourname” several times. Replace it with a name of your choice.

Setup Backblaze B2 Cloud Storage

To serve your images, set up a Backblaze B2 storage following these steps:

  1. Visit the Backblaze website in your browser.

  2. Click Products from the top navigation and then select B2 Cloud Storage from the dropdown.

  3. Sign up to Backblaze B2 Cloud Storage by following these steps:

    a. Enter your email address and password.
    b. Select the appropriate region.
    c. Click Sign Up Now.

  4. Verify your email by following these steps:

    a. Go to Account > My Settings in your side navigation.
    b. Click Verify Email in the Security section.
    c. Enter your sign-up email address and then click send Send Code.
    d. Check your email inbox or spam folder for the verification email.
    e. Click the verification link or use the verification code.

  5. Create a Bucket by going to B2 Cloud Storage > Bucket and clicking Create a Bucket.

  6. Go to B2 Cloud Storage > Bucket and then click Create a Bucket.

  7. Add your Bucket information as follows:

Bucket information

Instruction

Bucket Unique Name

Use a unique Bucket name. For example,yourname-wagtail-portfolio

Files in Bucket are

Select Public

Default Encryption

Select Disable

Object Lock

Select Disable

  1. Click Create a Bucket.

Set up Fly.io

Now that you’ve linked your site to your Blackblaze storage, it’s time to set up Fly.io to host your site.

To set up your Fly.io account, follow these steps:

  1. Visit Fly.io in your browser.

  2. Click Sign Up.

  3. Sign up using your GitHub account, Google account, or the email option.

  4. Check your email inbox for the verification link to verify your email.

Note

If your email verification fails, go to your Fly.io Dashboard and try again.

  1. Go to Dashboard > Billing and click Add credit card to add your credit card.

Note

Adding your credit card allows you to create a project in Fly.io. Fly.io won’t charge you after adding your credit card.

  1. Install flyctl by navigating to your project directory and then running the following command in your terminal:

On macOS:

# If you have the Homebrew package manager installed, run the following command:
brew install flyctl

# If you don't have the Homebrew package manager installed, run the following command:
curl -L https://fly.io/install.sh | sh

On Linux:

curl -L https://fly.io/install.sh | sh

On Windows, navigate to your project directory on PowerShell, activate your environment and run the following command:

pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"

Note

If you get an error on Windows saying the term pwsh is not recognized, install PowerShell MSI and then rerun the preceding Windows command.

  1. Sign in to your Fly.io by running the following command:

fly auth login

If you use Microsoft WSL, then run:

ln -s /usr/bin/wslview /usr/local/bin/xdg-open

Note

If you successfully install flyctl but get an error saying “fly is not recognized” or “flyctl: command not found error”, then you must add flyctl to your PATH. For more information, read Getting flyctl: command not found error post install.

  1. Create your Fly.io project by running fly launch and answering the resulting prompt questions as follows:

Question

Instruction

Choose an app name

Enter a name of your choice. For example, yourname-wagtail-portfolio

Choose a region for deployment

Select the region closest to the AWS_S3_REGION_NAME in your env.production file.

Overwrite “…/.dockerignore”?

Enter y

Overwrite “…/Dockerfile”?

Enter y

Would you like to set up a Postgresql database now?

Enter y

Select configuration

select Development - Single node, 1x shared CPU, 256MB RAM, 1GB disk if available. Otherwise, select the smallest configuration option

Scale single node pg to zero after one hour?

Enter y

Would you like to set up an Upstash Redis database now?

Enter n

The fly launch command creates two new files, Dockerfile and fly.toml, in your project directory.

If you use a third-party app terminal like the Visual Studio Code terminal, you may get an error creating your Postgres database. To rectify this error, follow these steps:

  1. Delete fly.toml file from your project directory.

  2. Go to your Fly.io account in your browser and click Dashboard.

  3. Click the created app in your Apps list.

  4. Click Settings in your side navigation.

  5. Click Delete app.

  6. Enter the name your app.

  7. Click Yes delete it.

  8. Repeat steps 3, 4, 5, 6, and 7 for all apps in your Apps list.

  9. Run the fly launch command in your built-in terminal or PowerShell MSI on Windows.

Customize your site to use Fly.io

Now, you must configure your portfolio site for the final deployment.

The fly launch command creates two new files, Dockerfile and fly.toml, in your project directory.

Add the following to your .gitignore file to make Git ignore your environment files:

.env*

Also, add the following to your .dockerignore file to make Docker ignore your environment and media files:

.env*
media

Configure your Fly.io to use 1 worker. This allows your site to work better with Fly.io’s low memory allowance. To do this, modify the last line of your Dockerfile as follows:

CMD ["gunicorn", "--bind", ":8000", "--workers", "1", "mysite.wsgi"]

Also, check if your fly.toml file has the following:

[deploy]
  release_command = "python manage.py migrate"

Your fly.toml file should look as follows:

app = "yourname-wagtail-portfolio"
primary_region = "lhr"
console_command = "/code/manage.py shell"

[build]

# add the deploy command:
[deploy]
  release_command = "python manage.py migrate"

[env]
  PORT = "8000"

[http_service]
  internal_port = 8000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ["app"]

[[statics]]
  guest_path = "/code/static"
  url_prefix = "/static/"

Now add your production dependencies by replacing the content of your requirements.txt file with the following:

Django>=4.2,<4.3
wagtail==5.1.1
gunicorn>=21.2.0,<22.0.0
psycopg[binary]>=3.1.10,<3.2.0
dj-database-url>=2.1.0,<3.0.0
whitenoise>=5.0,<5.1
django-storages[s3]>=1.14.0,<2.0.0

The preceding dependencies ensure that the necessary tools and libraries are in place to run your site successfully on the production server. The following are the explanations for the dependencies you may be unaware of:

  1. gunicorn is a web server that runs your site in Docker.

  2. psycopg is a PostgreSQL adapter that connects your site to a PostgreSQL database.

  3. dj-database-url is a package that simplifies your database configurations and connects to your site to a PostgreSQL database.

  4. whitenoise is a Django package that serves static files.

  5. django-storages is a Django library that handles your file storage and connects to your Backblaze B2 storage.

Replace the content of your mysite/settings/production.py file with the following:

import os
import random
import string
import dj_database_url

from .base import *

DEBUG = False

DATABASES = {
    "default": dj_database_url.config(
        conn_max_age=600,
        conn_health_checks=True
    )
}

SECRET_KEY = os.environ["SECRET_KEY"]

SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")

SECURE_SSL_REDIRECT = True

ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "*").split(",")

CSRF_TRUSTED_ORIGINS = os.getenv("DJANGO_CSRF_TRUSTED_ORIGINS", "").split(",")

EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

MIDDLEWARE.append("whitenoise.middleware.WhiteNoiseMiddleware")
STORAGES["staticfiles"]["BACKEND"] = "whitenoise.storage.CompressedManifestStaticFilesStorage"

if "AWS_STORAGE_BUCKET_NAME" in os.environ:
    AWS_STORAGE_BUCKET_NAME = os.getenv("AWS_STORAGE_BUCKET_NAME")
    AWS_S3_REGION_NAME = os.getenv("AWS_S3_REGION_NAME")
    AWS_S3_ENDPOINT_URL = os.getenv("AWS_S3_ENDPOINT_URL")
    AWS_S3_ACCESS_KEY_ID = os.getenv("AWS_S3_ACCESS_KEY_ID")
    AWS_S3_SECRET_ACCESS_KEY = os.getenv("AWS_S3_SECRET_ACCESS_KEY")

    INSTALLED_APPS.append("storages")

    STORAGES["default"]["BACKEND"] = "storages.backends.s3boto3.S3Boto3Storage"

    AWS_S3_OBJECT_PARAMETERS = {
        'CacheControl': 'max-age=86400',
    }

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
        },
    },
    "loggers": {
        "django": {
            "handlers": ["console"],
            "level": os.getenv("DJANGO_LOG_LEVEL", "INFO"),
        },
    },
}

WAGTAIL_REDIRECTS_FILE_STORAGE = "cache"

try:
    from .local import *
except ImportError:
    pass

The explanation of some of the code in your mysite/settings/production.py file is as follows:

  1. DEBUG = False turns off debugging for the production environment. It’s important for security and performance.

  2. SECRET_KEY = os.environ["SECRET_KEY"] retrieves the project’s secret key from your environment variable.

  3. SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") ensures that Django can detect a secure HTTPS connection if you deploy your site behind a reverse proxy like Heroku.

  4. SECURE_SSL_REDIRECT = True enforces HTTPS redirect. This ensures that all connections to the site are secure.

  5. ALLOWED_HOSTS = os.getenv("DJANGO_ALLOWED_HOSTS", "*").split(",") defines the hostnames that can access your site. It retrieves its values from the DJANGO_ALLOWED_HOSTS environment variable. If no specific hosts are defined, it defaults to allowing all hosts.

  6. EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" configures your site to use the console email backend. You can configure this to use a proper email backend for sending emails.

  7. WAGTAIL_REDIRECTS_FILE_STORAGE = "cache" configures the file storage for Wagtail’s redirects. Here, you set it to use cache.

Now, complete the configuration of your environment variables by modifying your .env.production file as follows:

Environment variable

Instruction

DJANGO_ALLOWED_HOSTS

This must match your fly.io project name. For example, yourname-wagtail-portfolio.fly.dev

DJANGO_CSRF_TRUSTED_ORIGINS

This must match your project’s domain name. For example, https://yourname-wagtail-portfolio.fly.dev

The content of your .env.production file should now look like this:

AWS_STORAGE_BUCKET_NAME=yourname-wagtail-portfolio
AWS_S3_ENDPOINT_URL=https://s3.us-east-005.backblazeb2.com
AWS_S3_REGION_NAME=us-east-005
AWS_S3_ACCESS_KEY_ID=your Backblaze keyID
AWS_S3_SECRET_ACCESS_KEY=your Backblaze applicationKey
DJANGO_ALLOWED_HOSTS=yourname-wagtail-portfolio.fly.dev
DJANGO_CSRF_TRUSTED_ORIGINS=https://yourname-wagtail-portfolio.fly.dev
DJANGO_SETTINGS_MODULE=mysite.settings.production

Set the secrets for Fly.io to use by running:

flyctl secrets import < .env.production

On Windows, run the following command in your PowerShell MSI:

Get-Content .env.production | flyctl secrets import

Finally, deploy your site to Fly.io by running the following command:

fly deploy --ha=false

Note

Running “fly deploy” creates two machines for your app. Using the “–ha=false” flag creates one machine for your app.

Congratulations! Your site is now live. However, you must add content to it. Start by creating an admin user for your live site. Run the following command:

flyctl ssh console

Then run:

DJANGO_SUPERUSER_USERNAME=username DJANGO_SUPERUSER_EMAIL=mail@example.com DJANGO_SUPERUSER_PASSWORD=password python manage.py createsuperuser --noinput

Note

Ensure you replace username, mail@example.com, and password with a username, email address, and password of your choice.

For more information on how to set up your Django project on Fly.io, read Django on Fly.io.

Add content to your live site

All this while, you’ve been adding content to your site in the local environment. Now that your site is live on a server, you must add content to the live site. To add content to your live site, go to https://yourname-wagtail-portfolio.fly.dev/admin/ in your browser and follow the steps in the following sub-sections of the tutorial:

Note

If you encounter errors while trying to access your live site in your browser, check your application logs in your Fly.io Dashboard. To check your application logs, click Dashboard > Apps > yourname-wagtail-portfolio > Monitoring

Congratulations! You made it to the end.

Where next