django部署的docker compose

It’s time to containerize that Django app! Upfront, let me warn you that like any solution to a problem, this one comes with its own hurdles. But once understood, this is a huge time saver and serious deployment option to consider.

现在是时候将Django应用容器化了! 首先,让我警告您,就像任何解决问题的方式一样,此方法也有其自己的障碍。 但是一旦了解,这是一个节省大量时间并考虑认真部署的选项。

For this walk-through, you just need a Django app, domain, and a host (we’re using DigitalOcean). If you haven’t started a project yet, consider this boilerplate repo by Philipp! We’ll reference it later in step 5 and 6.

对于本演练,您只需要一个Django应用程序,域和一个主机(我们正在使用DigitalOcean)。 如果您尚未启动项目,请考虑Philipp的样板仓库 ! 我们将在后面的第5步和第6步中引用它。

For you TL;DRers who like dessert first, you can peep the four complete files we’re about to configure below. Otherwise read on!

对于最先喜欢甜点的TL; DR,您可以浏览下面我们将要配置的四个完整文件。 否则请继续阅读!

docker-compose.yml (docker-compose.yml)

version: '3'services:
db:
image: postgres
environment:
- POSTGRES_DB=<FILL IN>
- POSTGRES_USER=<FILL IN>
- POSTGRES_PASSWORD=<FILL IN>
volumes:
- pgdata:/var/lib/posgresql/data
web:
build: .
command: gunicorn pp.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/code/static
expose:
- 8000
depends_on:
- db
nginx:
build: ./nginx
volumes:
- static_volume:/code/static
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
ports:
- 80:80
- 443:443
depends_on:
- web
certbot:
image: certbot/certbot:v0.36.0
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
volumes:
pgdata:
static_volume:

Docker文件 (Dockerfile)

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

Dockerfile(在/ nginx内部) (Dockerfile (inside /nginx))

FROM nginx:1.17.4-alpineRUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

nginx.conf(在/ nginx内部) (nginx.conf (inside /nginx))

upstream django_server {
server web:8000;
}server {
listen 80;
server_name <PASTE DOMAIN HERE>;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
} location / {
return 301 https://$host$request_uri;
} }server {
listen 443 ssl;
server_name <PASTE DOMAIN HERE>;
ssl_certificate /etc/letsencrypt/live/<PASTE DOMAIN HERE>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<PASTE DOMAIN HERE>/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / {
proxy_pass http://django_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
} location /static/ {
alias /code/static/;
}}

让我们开始! (Let’s begin!)

Setting up a generic host with Docker manually is pretty simple, but to stay in the theme of working “smarter not harder”, lets choose a host with some prebuilt images. I’m sure most hosting providers must offer something like this, but DigitalOcean is my favorite, and their marketplace has an official Ubuntu Docker image perfect for this. (Complete with docker-compose)

手动使用Docker设置通用主机非常简单,但是为了保持“更智能而不是更困难”的主题,我们选择带有一些预构建映像的主机。 我敢肯定,大多数托管服务提供商都必须提供类似的服务,但是DigitalOcean是我的最爱,他们的市场上有一个官方的Ubuntu Docker镜像非常适合此需求。 (完成docker-compose)

Once you get your repo cloned to your server, actually building and running with docker-compose is about a simple as typing it. BUT there is a check list you must run through before docker can do its thing.

将存储库克隆到服务器后,使用docker-compose进行构建和运行实际上就像键入它一样简单。 但是在Docker可以执行其操作之前,您必须运行一个检查列表。

  1. Specify static file location in Django settings.py

    在Django settings.py中指定静态文件位置
  2. Create a requirements.txt using pip freeze

    使用pip冻结创建requirements.txt
  3. Create a Dockerfile

    创建一个Dockerfile
  4. Create a docker-compose.yml

    创建一个docker-compose.yml
  5. Configure Nginx

    配置Nginx
  6. One-time Let’s Encrypt setup (Can’t not have TLS in 2020…)

    一次性让我们加密设置(2020年不能使用TLS…)

1Static files will need to be collected in order for nginx to serve them. In your app’s settings.py file add the following lines.

1将需要收集静态文件,以便Nginx为其提供服务。 在应用程序的settings.py文件中添加以下行。

STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, "static")

Whether you use Docker or not, collecting static files into a single directory for production should be habit if it’s not already. STATIC_ROOT tells Django the directory in which to collect and look for static the files. STATIC_URL will setup the routing.

无论是否使用Docker,如果尚未将静态文件收集到一个目录中进行生产,则应该习惯于这样做。 STATIC_ROOT告诉Django收集目录并查找静态文件。 STATIC_URL将设置路由。

2 Docker compose will not only build containers for our app, and its services, it will setup their environments, and install our dependencies. In order to do so, it will need a requirements.txt file.

2 Docker compose不仅将为我们的应用程序及其服务构建容器,还将设置其环境并安装我们的依赖项。 为此,它将需要一个requirements.txt文件。

pip freeze > requirements.txt

Run the above command from your project’s root directory (the one with your manage.py file in it).

从项目的根目录(其中包含manage.py文件的根目录)运行以上命令。

3 Alright, now for the actual Docker stuff. Create a Dockerfile in your project root directory

3好,现在是实际的Docker东西。 在项目根目录中创建一个Dockerfile

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

Feel free to copy-paste as-is.

随时按原样复制粘贴。

这里有一些细分: (Here’s a little break down:)

“FROM” will assign a base image, and in this case we’re using the official python3 image. “ENV” sets an environment variable inside of the container, here we’re telling python not to buffer its output. “RUN” executes commands inside the container, and we can use it to make a directory for our code, after which we’ll move into it with “WORKDIR”. Next we use “COPY” to take our local requirements.txt and create a duplicate inside of our containers code folder. Finally we install our python requirements we saved, and move everything else into our containers code directory.

“ FROM”将分配一个基本映像,在这种情况下,我们使用的是官方的python3映像。 “ ENV”在容器内部设置一个环境变量,这里我们告诉python不要缓冲其输出。 “ RUN”在容器内执行命令,我们可以使用它为我们的代码创建目录,然后使用“ WORKDIR”将其移入其中。 接下来,我们使用“复制” 使用我们的本地requirements.txt并在我们的容器代码文件夹中创建一个副本。 最后,我们安装保存的python需求,然后将其他所有内容移到我们的容器代码目录中。

4 YAML time! Describing the docker-compose.yml is the meat and potatoes of this entire process. Below is just a break down of the complete YAML file that I shared up at the top of this walk through.

4 YAML时间! 描述docker-compose.yml是整个过程的实质。 以下只是本演练顶部共享的完整YAML文件的分解。

version: '3'services:
db:
image: postgres
environment:
- POSTGRES_DB=<FILL IN>
- POSTGRES_USER=<FILL IN>
- POSTGRES_PASSWORD=<FILL IN>
volumes:
- pgdata:/var/lib/posgresql/data
volumes:
pgdata:

At the top we have the version of compose being used. Below that we can orchestrate multiple containers, and treat them as services in our app. Postgres is the goto database in Django, so we start out by setting up our db service with the appropriate image and environment variables. Similar to how we used “FROM” in our Dockerfile to choose a base image, here we assign it with the field name “image”. “Environment”, again does a similar thing as “ENV” in our Dockerfile, and sets an environment variable. Here it’s used to establish credentials for Postgres. Lastly for our db service we set a volumes field and location for the data, then outside of services we describe our pgdata volume.

在顶部,我们使用了compose的版本。 在此之下,我们可以编排多个容器,并将其作为应用程序中的服务。 Postgres是Django中的goto数据库,因此我们首先使用适当的图像和环境变量设置数据库服务。 类似于我们在Dockerfile中使用“ FROM”来选择基本映像的方式,这里我们为它分配了字段名称“ image” 。 在我们的Dockerfile中, “ Environment”再次执行与“ ENV”类似的操作,并设置一个环境变量。 在这里,它用于建立Postgres的凭证。 最后,为数据库服务设置数据的字段和位置,然后在服务之外描述pgdata卷。

web:
build: .
command: gunicorn pp.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/code/static
expose:
- 8000
depends_on:
- db

Our web service is pretty straight forward. We’re building from the Dockerfile, and exposing it to the other docker services on port 8000. The depends_on field lets you lists services that need to finish initializing before that service is spun up. In our case, the web service is reliant on our db service.

我们的Web服务非常简单。 我们从Dockerfile进行构建,并将其公开给端口8000上的其他depends_on服务depends_on字段可让您列出在启动该服务之前需要完成初始化的服务。 在我们的例子中,Web服务依赖于我们的数据库服务。

nginx:
build: ./nginx
volumes:
- static_volume:/code/static
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
ports:
- 80:80
- 443:443
depends_on:
- webvolumes:
pgdata:
static_volume: <----- dont forget this

5 Again the snippet above probably speaks for itself, but our Nginx service needs a little more configuring than we can put in our compose file. Note that we added static_volume to the volumes field below pgdata.

5上面的代码片段也可以说明一切,但是我们的Nginx服务需要的配置要比我们在compose文件中可以添加的更多。 请注意,我们在static_volume下面的pgdata字段中添加了pgdata

We need to make a new directory in the project root called nginx. Inside of our nginx folder lets create two files: Dockerfile, and nginx.conf. Below are what these need to look like.

我们需要在项目根目录中创建一个名为nginx的新目录。 在我们的nginx文件夹中,我们可以创建两个文件: Dockerfilenginx.conf 。 以下是这些需要的外观。

Dockerfile(在/ nginx内部) (Dockerfile (inside /nginx))

FROM nginx:1.17.4-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

Dockerfile, just copy-paste.

Dockerfile,只需复制粘贴即可。

nginx.conf (在/ nginx内部) (nginx.conf (inside /nginx))

upstream django_server {
server web:8000;
}
server {
listen 80;
server_name <PASTE DOMAIN HERE>;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name <PASTE DOMAIN HERE>;
ssl_certificate /etc/letsencrypt/live/<PASTE DOMAIN HERE>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<PASTE DOMAIN HERE>/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://django_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
}
location /static/ {
alias /code/static/;
}
}

Be sure to insert your domain where I noted, sans the brackets.

除括号外,请务必将您的域插入我指出的位置。

6 Final step… Okay I was a little stuck trying to figure out a setup for certbot within docker! What made things come together for me was this great boilerplate repo and article from Philipp.

6最后一步……好吧,我有点想尝试在docker中为certbot设置一个设置! 是什么让事情走到一起,对我来说是这个伟大的样板回购文章菲利普

The nginx.conf file and docker-compose.yml both have code referenced from their repo. Below is the last bit that gets put in our docker-compose.yml file.

nginx.conf文件和docker-compose.yml都从其存储库中引用了代码。 以下是放置在我们的docker-compose.yml文件中的最后一部分。

certbot:
image: certbot/certbot:v0.36.0
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot

这部分很重要! (This parts important!)

The best part of Philipp’s repo is this script. Nginx won’t run without a cert installed the way we have it configured, and we nginx to run in order for us to complete a handshake with Let’s Encrypt to get our cert! This script handles creating a fake cert to fool nginx, and installs that cert for you!

Philipp回购协议中最好的部分就是这个脚本 。 如果不按照我们配置的方式安装证书,Nginx将无法运行,而我们要运行nginx以便与“加密”来完成握手以获取证书! 该脚本处理创建一个伪造的证书来欺骗nginx,并为您安装该证书!

curl https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh

Add the script to your project root and run the following commands.

将脚本添加到项目根目录,然后运行以下命令。

chmod +x init-letsencrypt.sh add execute permission

chmod +x init-letsencrypt.sh添加执行权限

sudo ./init-letsencrypt.sh run script as root

sudo ./init-letsencrypt.sh以root sudo ./init-letsencrypt.sh运行脚本

建立 (Build)

If the script completed and you have a cert, congrats!

如果脚本完成并且您有证书,那么恭喜!

docker-compose up -d : Start docker compose detached

docker-compose up -d :启动docker compose分离

Now do what you would do with any Django project on a new machine! Compose uses the exec flag with a services name to run commands in that running container.

现在,在新机器上执行与任何Django项目一样的工作! Compose使用带有服务名称的exec标志在该正在运行的容器中运行命令。

docker-compose exec web python manage.py collectstatic : Collect static files

docker-compose exec web python manage.py collectstatic :收集静态文件

docker-compose exec web python manage.py migrate : Migrate models into db

docker-compose exec web python manage.py migrate :将模型迁移到数据库

docker-compose exec web python manage.py createsuperuser : Create a superuser.

docker-compose exec web python manage.py createsuperuser :创建一个超级用户。

Remember, if you need to set your own environment variables or do any other custom configuration, you have a good idea how to do so!

请记住,如果您需要设置自己的环境变量或进行任何其他自定义配置,那么您将有一个很好的主意!

翻译自: https://medium.com/swlh/django-deployed-docker-compose-1446909a0df9

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值