{"id":50034,"date":"2023-12-06T17:45:51","date_gmt":"2023-10-25T01:35:31","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/"},"modified":"2024-05-04T12:24:27","modified_gmt":"2024-05-04T04:24:27","slug":"%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/","title":{"rendered":"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5"},"content":{"rendered":"<h1>\u9996\u5148<\/h1>\n<p>\u8fd9\u662f\u6211\u5728\u4e2a\u4eba\u5f00\u53d1\u7684\u4e24\u5e74\u4e2d\uff0c\u5b66\u4e60Docker\u7684\u6700\u540e\u9636\u6bb5\u65f6\u53c2\u8003\u4e86\u300eDockerizing Django with Postgres, Gunicorn, and Nginx\u300f\u8fd9\u4e2a\u793a\u8303\u7f51\u7ad9\u7684\u8bb0\u5f55\u3002\u5982\u679c\u4e0d\u662f\u975e\u5e38\u5f3a\u7684\u4eba\u4e5f\u53ef\u4ee5\u4ece\u8fd9\u4e2a\u7f51\u7ad9\u4e2d\u627e\u5230\u81ea\u5df1\u5361\u5728\u54ea\u91cc\uff0c\u5e76\u83b7\u5f97\u4e00\u4e9b\u53c2\u8003\u3002<\/p>\n<h1>\u76ee\u6807\u8bfb\u8005<\/h1>\n<p>\u672c\u8bfe\u7a0b\u9488\u5bf9Django\u7528\u6237\u548cDocker\u521d\u5b66\u8005\u3002\u5e0c\u671b\u53ef\u4ee5\u5e2e\u52a9\u4e2a\u4eba\u5f00\u53d1\u8005\u5feb\u901f\u638c\u63e1Docker\u7684\u4f7f\u7528\u6280\u5de7\u3002<\/p>\n<h1>\u5f00\u53d1\u73af\u5883<\/h1>\n<p>Windows11Pro\uff08\uff12\u53f0\uff01\uff09<\/p>\n<p>Home\u3067\u306f\u8a66\u3057\u3066\u3044\u307e\u305b\u3093\u304c\u3001\u305f\u3076\u3093\u554f\u984c\u306a\u3044\u3067\u3059\u3002<br \/>\n\u554f\u984c\u89e3\u6c7a\u80fd\u529b\u304c\u4f4e\u3044\u521d\u5fc3\u8005\u306e\u6642\u3053\u305d\u3001PC\u8907\u6570\u53f0\u6301\u3064\u3053\u3068\u3092\u304a\u30b9\u30b9\u30e1\u3057\u307e\u3059\u3002\u30b3\u30b9\u30d1\u91cd\u8996\u3001\u4e2d\u53e4\u3067OK\u3067\u3059\u3002\u3044\u3064\u3067\u3082OS\u30af\u30ea\u30fc\u30f3\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u69cb\u308f\u306a\u3044\u30de\u30b7\u30f3\u304c\u3042\u308b\u3068\u5fc3\u5f37\u3044\u3067\u3059\u3002<br \/>\n\u3053\u306e\u8a18\u4e8b\u306f\u4e00\u5ea6\u3067\u4f5c\u696d\u5b8c\u4e86\u3057\u3066\u3044\u308b\u3088\u3046\u306b\u66f8\u3044\u3066\u3044\u307e\u3059\u304c\u3001\u5b9f\u969b\u306f\u305f\u304f\u3055\u3093\u30cf\u30de\u3063\u3066\u3044\u307e\u3059\u3002\u82f1\u8a9e\u30b5\u30a4\u30c8\u3092\u30b0\u30b0\u3063\u3066\u8272\u3005\u8a66\u3057\u3066\u3082\u89e3\u6c7a\u306b\u81f3\u3089\u306a\u3044\u30b1\u30fc\u30b9\u3067\u306f\u3001\u5225\u306ePC\u306b\u540c\u3058\u65b9\u6cd5\u3067\u74b0\u5883\u8a2d\u5b9a\u3057\u3066\u3001\u540c\u3058\u4f5c\u696d\u3092\u5b9f\u65bd\u3057\u305f\u3068\u3053\u308d\u6b63\u5e38\u52d5\u4f5c\u3055\u305b\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3057\u305f\u3002\u3082\u3046\u306a\u3093\u306a\u306e<\/p>\n<p>WSL2 Ubuntu<\/p>\n<p>\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u624b\u9806\u306f\u8272\u3005\u3042\u308a\u305d\u3046\u3067\u3059\u304c\u3001\u3069\u308c\u3067\u3082\u5927\u4e08\u592b\u3060\u3068\u601d\u3044\u307e\u3059\u3002<\/p>\n<p>VScode<\/p>\n<p>VScode\u30bf\u30fc\u30df\u30ca\u30eb\u3067 WSL2 Ubuntu bash\u3092\u64cd\u4f5c\u3067\u304d\u308b\u72b6\u614b\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002\u74b0\u5883\u8a2d\u5b9a\u306f\u30b0\u30b0\u3063\u3066\u308f\u304b\u308a\u3084\u3059\u3044\u30b5\u30a4\u30c8\u3092\u63a2\u3057\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n<p>Python<\/p>\n<p>WSL2 Ubuntu \u306b\u59cb\u3081\u304b\u3089\u5165\u3063\u3066\u3044\u308bPython\u306f\u4f7f\u308f\u305a\u3001\u65b0\u3057\u3044\u30d0\u30fc\u30b8\u30e7\u30f3\u306ePython\u3092\u8ffd\u52a0\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u3066\u305d\u3061\u3089\u3092\u4f7f\u3046\u3088\u3046\u306b\u3057\u3066\u304f\u3060\u3055\u3044\u3002<br \/>\n\u79c1\u306f\u304a\u624b\u672c\u3068\u540c\u3058Ver.3.9.6\u3092\u5165\u308c\u307e\u3057\u305f\u3002<\/p>\n<h1>\u901a\u8fc7\u4eb2\u8eab\u7ecf\u5386\u4ece\u96f6\u5f00\u59cb\u6784\u5efa\u7684\u5de5\u4f5c<\/h1>\n<p>\u300e\u4f7f\u7528Docker\u5c06Django\u4e0ePostgres\u3001Gunicorn\u548cNginx\u5bb9\u5668\u5316\u300f\uff08\u4ee5\u4e0b\u7b80\u79f0\u793a\u4f8b\u7f51\u7ad9\uff09\u4ece\u521b\u5efa\u9879\u76ee\u76ee\u5f55\u5f00\u59cb\uff0c\u4e00\u76f4\u5230\u6700\u540e\uff0c\u90fd\u4f1a\u4e00\u76f4\u8ddf\u7740\u4f60\uff0c\u6ca1\u6709\u8df3\u8dc3\u5185\u5bb9\u3002\u592a\u68d2\u4e86\u3002<br \/>\n\u5f53\u6211\u5b66\u4e60\u65f6\uff0c\u6211\u8bb0\u5f55\u4e86\u4e0e\u793a\u4f8b\u7f51\u7ad9\u4e0d\u540c\u7684\u64cd\u4f5c\u3001\u7591\u95ee\u3001\u95ee\u9898\u89e3\u51b3\u7b49\uff0c\u6309\u7167\u793a\u4f8b\u7f51\u7ad9\u7684\u8fdb\u5ea6\u8fdb\u884c\u8bb0\u5f55\u3002\u6807\u9898\u53d8\u4e3a\u76f8\u5e94\u9879\u76ee\u7684\u94fe\u63a5\u3002<br \/>\n\u7531\u4e8e\u8fd9\u91cc\u6ca1\u6709\u91cd\u590d\u89e3\u91ca\u8be6\u7ec6\u7684\u90e8\u5206\uff0c\u8bf7\u5148\u67e5\u770b\u94fe\u63a5\u5230\u793a\u4f8b\u7f51\u7ad9\u7684\u9875\u9762\u3002<br \/>\n\u867d\u7136\u6709\u5f88\u591a\u5730\u65b9\u662f\u76f4\u63a5\u7167\u642c\u793a\u4f8b\u7f51\u7ad9\uff0c\u8fd9\u662f\u4e3a\u4e86\u4e0d\u6765\u56de\u8df3\u8f6c\uff0c\u4ee5\u4fbf\u638c\u63e1\u5de5\u4f5c\u6d41\u7a0b\u3002\uff08\u4e5f\u662f\u4e3a\u4e86\u81ea\u5df1\u7684\u5de5\u4f5c\u6d41\u7a0b\u7b14\u8bb0\u8d77\u8349\u3002\u3002\uff09<\/p>\n<p>\u5728\u9605\u8bfb\u82f1\u6587\u7f51\u7ad9\u65f6\uff0c\u6211\u63a8\u8350\u4f7f\u7528DeepL\u7684\u5e94\u7528\u7248\u672c\u3002\u5728\u9009\u62e9\u6587\u5b57\u540e\uff0c\u6309\u4e0bCtrl\u952e\u5e76\u8fde\u7eed\u6309\u4e24\u6b21C\u952e\uff0c\u5b83\u4f1a\u7acb\u5373\u4e3a\u4f60\u7ffb\u8bd1\u3002\u8fd9\u662f\u4e00\u4e2a\u5f88\u4e86\u4e0d\u8d77\u7684\u65f6\u4ee3\u3002\u5982\u679c\u6709\u9700\u8981\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5c1d\u8bd5\u4f7f\u7528Google\u7ffb\u8bd1\u8fd9\u4e2a\u793a\u4f8b\u7f51\u7ad9\uff0c\u5b83\u4e5f\u5f88\u5bb9\u6613\u7406\u89e3\u3002<\/p>\n<h2>\u9879\u76ee\u5efa\u7acb<\/h2>\n<p>\u5728\u4e3b\u76ee\u5f55\u4e2d\u51c6\u5907\u4e00\u4e2a\u5de5\u4f5c\u573a\u6240\uff08\u5e76\u5c06\u5176\u547d\u540d\u4e3a&#8221;works&#8221;\uff09\u3002<\/p>\n<pre class=\"post-pre\"><code>~<span class=\"nv\">$ <\/span><span class=\"nb\">mkdir <\/span>works\r\n~<span class=\"nv\">$ <\/span><span class=\"nb\">cd <\/span>works\r\n<\/code><\/pre>\n<p>\u51c6\u5907\u9879\u76ee\u76ee\u5f55\uff08\u547d\u540d\u4e3ahoge-on-docker\uff09\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/works$ mkdir hoge-on-docker\r\n~\/works$ cd hoge-on-docker\r\n~\/works\/hoge-on-docker$ \r\n<\/code><\/pre>\n<p>\u7531\u4e8e\u8def\u5f84\u5f88\u957f\uff0c\u6240\u4ee5\u5728\u6b64\u4e4b\u540e\u7684\u8bf4\u660e\u4e2d<\/p>\n<pre class=\"post-pre\"><code>~\/*$\r\n<\/code><\/pre>\n<p>\u8868\u793a\u3002<\/p>\n<p>\u51c6\u5907\u4e00\u4e2aapp\u76ee\u5f55\u6765\u5b58\u653eDjango\u5e94\u7528\u7a0b\u5e8f\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/*$ mkdir app\r\n~\/*$ cd app\r\n<\/code><\/pre>\n<p>Python\u7684\u865a\u62df\u5316<\/p>\n<pre class=\"post-pre\"><code>~\/*\/app$ python3 -m venv .\r\n~\/*\/app$ . .venv\/bin\/activate\r\n<\/code><\/pre>\n<div>\u5728\u6062\u590d\u5de5\u4f5c\u65f6\u865a\u62df\u5316<br \/>\n\u53ef\u80fd\u4f1a\u5728~\/*$\u7684\u72b6\u6001\u4e0b\u91cd\u65b0\u5f00\u59cb\u5de5\u4f5c\uff0c\u56e0\u6b64\u865a\u62df\u5316\u547d\u4ee4\u662f . .\/app\/.venv\/bin\/activate\u3002\u5f53\u7136\uff0c\u6309\u7167\u53c2\u8003\u7f51\u7ad9\u4e0a\u7684\u5199\u6cd5\uff0csource .\/app\/.venv\/bin\/activate\u4e5f\u53ef\u4ee5\u3002\u53ea\u662f\u60f3\u8bb0\u5f55\u4e0b\u6709\u4e24\u79cd\u5199\u6cd5\u3002<\/div>\n<h4>\u5b89\u88c5Django<\/h4>\n<p>\u7531\u4e8e\u7f3a\u4e4f\u4e13\u4e1a\u7684\u5b89\u5168\u77e5\u8bc6\uff0c\u6211\u51b3\u5b9a\u5c06Django\u7248\u672c\u66f4\u65b0\u5230\u6700\u65b0\u7684\u7248\u672c\u3002\u6211\u81f3\u5c11\u60f3\u4f7f\u7528\u6700\u65b0\u7248\u672c\u7684\u6846\u67b6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"o\">(<\/span>.venv<span class=\"o\">)<\/span>~\/<span class=\"k\">*<\/span>\/app<span class=\"nv\">$ <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">--upgrade<\/span> pip\r\n<span class=\"o\">(<\/span>.venv<span class=\"o\">)<\/span>~\/<span class=\"k\">*<\/span>\/app<span class=\"nv\">$ <\/span>pip <span class=\"nb\">install <\/span><span class=\"nv\">django<\/span><span class=\"o\">==<\/span>4.1\r\n<span class=\"o\">(<\/span>.venv<span class=\"o\">)<\/span>~\/<span class=\"k\">*<\/span>\/app<span class=\"nv\">$ <\/span>django-admin startproject config <span class=\"nb\">.<\/span>\r\n<span class=\"o\">(<\/span>.venv<span class=\"o\">)<\/span>~\/<span class=\"k\">*<\/span>\/app<span class=\"nv\">$ <\/span>python manage.py migrate\r\n<span class=\"o\">(<\/span>.venv<span class=\"o\">)<\/span>~\/<span class=\"k\">*<\/span>\/app<span class=\"nv\">$ <\/span>python manage.py runserver\r\n<\/code><\/pre>\n<p>\u8bf7\u5728\u6d4f\u89c8\u5668\u4e2d\u8bbf\u95ee http:\/\/localhost:8000\/\u3002\u5982\u679c\u663e\u793a\u706b\u7bad\uff0c\u5c31\u4ee3\u8868\u6b63\u5e38\u3002\u8981\u505c\u6b62\u8bf7\u6309\u4e0b ctrl + c\u3002<\/p>\n<div>\u5173\u4e8e\u76ee\u5f55\u540d<br \/>\n\u5728\u6b64\u4e4b\u524d\uff0c\u6839\u636e\u300aDjango for Beginners\u300b\u7684\u601d\u60f3\uff0c\u6211\u4eec\u5c06\u5b58\u50a8settings.py\u7b49\u6587\u4ef6\u7684\u6587\u4ef6\u5939\u547d\u540d\u4e3aconfig\u3002<br \/>\n\u5728\u5207\u6362\u5230Docker\u5f00\u53d1\u65f6\uff0c\u6211\u4eec\u4e5f\u8003\u8651\u5c06\u9879\u76ee\u540d\u79f0\uff08\u672c\u4f8b\u4e2d\u4e3ahoge\uff09\u4f5c\u4e3a\u6587\u4ef6\u5939\u540d\u79f0\uff0c\u4f46\u6700\u7ec8\u8fd8\u662f\u51b3\u5b9a\u4f7f\u7528config\u3002\u53e6\u5916\uff0c\u5b58\u50a8Django\u5e94\u7528\u7a0b\u5e8f\u7684\u6587\u4ef6\u5939\u540d\u79f0\u6211\u4eec\u9009\u62e9\u6309\u7167\u793a\u4f8b\u7684app\u547d\u540d\u3002\u539f\u56e0\u5982\u4e0b\uff1a\u5c06\u76ee\u5f55\u547d\u540d\u4e3aapp\u548cconfig\u7684\u7406\u7531\uff1a<\/p>\n<p>\u5728Docker\u5f00\u53d1\u4e2d\uff0c\u9879\u76ee\u7684\u6839\u76ee\u5f55\u4e0b\u4f1a\u6709\u5f88\u591adocker-compose.yml\u7b49\u6587\u4ef6\u3002\u5c06\u201c\u5c06Django\u5e94\u7528\u7a0b\u5e8f\u653e\u5728app\u6587\u4ef6\u5939\u4e0b\u201d\u4f5c\u4e3a\u81ea\u5df1\u7684\u89c4\u5219\uff0c\u53ef\u4ee5\u66f4\u5bb9\u6613\u627e\u5230\u3002<br \/>\n\u53ef\u4ee5\u7edf\u4e00docker-compose.yml\u7b49\u6587\u4ef6\u7684\u63cf\u8ff0\u3002<br \/>\n\u5982\u679c\u5c06app\u6587\u4ef6\u5939\u7684\u4e0b\u4e00\u5c42\u547d\u540d\u4e3aconfig\uff0c\u53ef\u80fd\u4e0d\u592a\u5bb9\u6613\u7406\u89e3\u8fd9\u4e2aDjango\u5e94\u7528\u7a0b\u5e8f\u662f\u4ec0\u4e48\uff0c\u4f46\u662f\u901a\u8fc7\u67e5\u770b\u9879\u76ee\u7684\u76ee\u5f55\u540d\u5c31\u53ef\u4ee5\u660e\u767d\uff0c\u6240\u4ee5\u9009\u62e9\u4e86\u8fd9\u6837\u505a\u3002<br \/>\n\u901a\u8fc7\u7edf\u4e00\u4f7f\u7528config\uff0c\u540e\u9762\u51fa\u73b0\u7684nginx.conf\u7684\u63cf\u8ff0\u4e5f\u53ef\u4ee5\u56fa\u5b9a\u3002<\/p>\n<\/div>\n<p>\u5728\u5e94\u7528\u7a0b\u5e8f\u7684\u9876\u5c42\u76ee\u5f55\u4e0b\u51c6\u5907\u4e00\u4e2arequirements.txt\u6587\u4ef6\uff0c\u5e76\u5728\u5176\u4e2d\u5199\u5165django==4.1\u3002<\/p>\n<div>\u4e0d\u7528 pip freeze &gt; requirements.txt \u5417\uff1f<br \/>\n\u7531\u4e8e\u4f7f\u7528\u4e86\u57fa\u4e8ePython Alpine\u955c\u50cf\u7684Docker\u955c\u50cf\u6784\u5efa\u8fc7\u7a0b\u4e2d\u4f1a\u5b89\u88c5Django\u7684\u73af\u5883\uff0c\u6240\u4ee5\u4e0d\u60f3\u5c06\u591a\u4f59\u7684\u5305\u4fe1\u606f\u5305\u542b\u5728requirements.txt\u4e2d\u3002\u6240\u9700\u8981\u7684\u662f\u5b89\u88c5\u6307\u4ee4\u7684\u6e05\u5355\uff0c\u800c\u4e0d\u662f\u5df2\u5b89\u88c5\u7684\u5305\u6e05\u5355\u3002<\/div>\n<p>\u7531\u4e8e\u6211\u4eec\u4f7f\u7528Postgres\u4f5c\u4e3a\u6570\u636e\u5e93\uff0c\u56e0\u6b64\u9700\u8981\u5220\u9664db.sqlite3\u6587\u4ef6\u3002\u5728\u6784\u5efa\u6620\u50cf\u65f6\uff0c\u5c06\u590d\u5236\u5e94\u7528\u7a0b\u5e8f\u4e2d\u7684\u5185\u5bb9\uff0c\u56e0\u6b64\u9700\u8981\u9884\u5148\u5220\u9664\u4e0d\u5fc5\u8981\u7684\u5185\u5bb9\u3002\u867d\u7136\u5728\u540e\u7eed\u7684\u64cd\u4f5c\u4e2d\u53ef\u80fd\u4f1a\u91cd\u65b0\u521b\u5efa\uff0c\u4f46\u5982\u679c\u9700\u8981\u7684\u8bdd\u53ef\u4ee5\u518d\u6b21\u5220\u9664\u3002\u53ef\u80fd\u503c\u5f97\u8003\u8651\u67e5\u9605.dockerignore\u6587\u4ef6\u7684\u4f7f\u7528\u65b9\u6cd5\u5e76\u5c06\u5176\u6574\u5408\u8fdb\u6765\u3002\u4f60\u8bf4\u4f60\u4e0d\u53bb\u505a\u7684\u8bdd\u4f1a\u5f88\u61ca\u6094\u3002<\/p>\n<h2>Docker \u662f\u4e00\u79cd\u5bb9\u5668\u5316\u5e73\u53f0\u3002<\/h2>\n<p>\u5728\u5e94\u7528\u7a0b\u5e8f\u7684\u6839\u76ee\u5f55\u4e0b\u521b\u5efa\u4e00\u4e2a Dockerfile\u3002\uff08\u8bf7\u67e5\u770b\u53c2\u8003\u7f51\u7ad9\u4ee5\u4e86\u89e3\u8be6\u7ec6\u4fe1\u606f\u3002\uff09<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># pull official base image<\/span>\r\n<span class=\"k\">FROM<\/span><span class=\"s\"> python:3.9.6-alpine<\/span>\r\n\r\n<span class=\"c\"># set work directory<\/span>\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> \/usr\/src\/app<\/span>\r\n\r\n<span class=\"c\"># set environment variables<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONDONTWRITEBYTECODE 1<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONUNBUFFERED 1<\/span>\r\n\r\n<span class=\"c\"># install dependencies<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">--upgrade<\/span> pip\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> .\/requirements.txt .<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">-r<\/span> requirements.txt\r\n\r\n<span class=\"c\"># copy project<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> . .<\/span>\r\n<\/code><\/pre>\n<div>\u8bf7\u6ce8\u610f\u6587\u4ef6\u540d\u7684\u9519\u8bef\u62fc\u5199\u3002<br \/>\n\u56e0\u4e3a\u6587\u4ef6\u540d\u5199\u6210\u4e86 dcokerfile \u6240\u4ee5\u5361\u4f4f\u4e86\u3002\u5982\u679c\u662f\u5728VScode\u4e0a\uff0c\u53ea\u8981\u6587\u4ef6\u540d\u6b63\u786e\uff0c\u56fe\u6807\u5c31\u4f1a\u53d8\u6210\u9cb8\u9c7c\u7684\u6837\u5b50\u3002\u5982\u679c\u4e0d\u4ed4\u7ec6\u770b\u7684\u8bdd&#8230;<\/div>\n<div>\u4f7f\u7528\u6700\u65b0\u7248\u672c\u7684\u6620\u50cf\u65f6\uff0c\u7ed1\u5b9a\u6302\u8f7d\uff08\u4e3b\u673a\u548c\u5bb9\u5668\u7684\u8054\u52a8\uff09\u65e0\u6cd5\u6b63\u5e38\u5de5\u4f5c\uff0c\u56e0\u6b64\u6309\u7167\u793a\u4f8b\u8fdb\u884c\u4e86\u91cd\u65b0\u5c1d\u8bd5\u3002\u53ea\u662f\u91cd\u65b0\u5c1d\u8bd5\u6210\u529f\uff0c\u5e76\u4e14\u6211\u8ba4\u4e3a\u539f\u56e0\u53ef\u80fd\u662f\u5176\u4ed6\u65b9\u9762\u7684\u95ee\u9898\u3002\u6211\u6ca1\u6709\u8fdb\u884c\u9a8c\u8bc1\u3002<\/div>\n<p>\u5728\u9879\u76ee\u6839\u76ee\u5f55\uff08hoge-on-docker\u7684\u76f4\u63a5\u5b50\u76ee\u5f55\uff09\u4e0b\u521b\u5efadocker-compose.yml\u6587\u4ef6\uff08\u4e0eapp\u4f4d\u4e8e\u540c\u4e00\u5c42\u7ea7\uff09\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">version<\/span><span class=\"pi\">:<\/span> <span class=\"s1\">'<\/span><span class=\"s\">3.8'<\/span>\r\n\r\n<span class=\"na\">services<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">build<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/app<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s\">python manage.py runserver 0.0.0.0:8000<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/app\/:\/usr\/src\/app\/<\/span>\r\n    <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">8000:8000<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.dev<\/span>\r\n<\/code><\/pre>\n<p>\u968f\u540e\uff0c\u5728\u9879\u76ee\u6839\u76ee\u5f55\u521b\u5efa.env.dev\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code>DEBUG=1\r\nSECRET_KEY=\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\r\nDJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]\r\n<\/code><\/pre>\n<p>\u5c06\u4e0b\u9762\u7684\u5185\u5bb9\u63d2\u5165\u5230 SECRET_KEY \u7684\u53f3\u8fb9, \u5185\u5bb9\u662f\u4f4d\u4e8e app\/config \u76ee\u5f55\u4e0b\u7684 settings.py \u6587\u4ef6\u4e2d SECRET_KEY \u7684\u5b57\u7b26\u4e32, \u8be5\u5b57\u7b26\u4e32\u7528\u5355\u5f15\u53f7 &#8216; &#8216; \u62ec\u8d77\u6765\uff08\u4e0d\u5305\u62ec\u4e24\u7aef\u7684\u5f15\u53f7\uff09\u3002<\/p>\n<p>\u5728settings.py\u6587\u4ef6\u4e2d\u6dfb\u52a0\u6216\u4fee\u6539<\/p>\n<pre class=\"post-pre\"><code><span class=\"c1\"># \u5192\u982d\u306b\u8ffd\u8a18\r\n<\/span><span class=\"kn\">import<\/span> <span class=\"n\">os<\/span>\r\n\r\n<span class=\"c1\"># \u4e0b\u8a183\u9805\u76ee\u306e\u53f3\u8fba\u3092\u5909\u66f4\r\n<\/span><span class=\"n\">SECRET_KEY<\/span> <span class=\"o\">=<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SECRET_KEY<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n<span class=\"n\">DEBUG<\/span> <span class=\"o\">=<\/span> <span class=\"nf\">int<\/span><span class=\"p\">(<\/span><span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">DEBUG<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">default<\/span><span class=\"o\">=<\/span><span class=\"mi\">0<\/span><span class=\"p\">))<\/span>\r\n<span class=\"n\">ALLOWED_HOSTS<\/span> <span class=\"o\">=<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">DJANGO_ALLOWED_HOSTS<\/span><span class=\"sh\">\"<\/span><span class=\"p\">).<\/span><span class=\"nf\">split<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span> <span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<p>\u6784\u5efa\u5f62\u8c61<\/p>\n<p>\u79fb\u52a8\u5230\u9879\u76ee\u7684\u6839\u76ee\u5f55\u4e0b\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span>\/app<span class=\"nv\">$ <\/span><span class=\"nb\">cd<\/span> ..\r\n<\/code><\/pre>\n<p>\u4f7f\u7528docker-compose.yml\u6587\u4ef6\u6765\u6784\u5efa\u955c\u50cf<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose build\r\n<\/code><\/pre>\n<p>\u751f\u6210\u5bb9\u5668\uff0c\u540e\u53f0\u8fd0\u884c\uff08\u5b88\u62a4\u8fdb\u7a0b\uff09<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose up <span class=\"nt\">-d<\/span>\r\n<\/code><\/pre>\n<p>\u8bbf\u95ee http:\/\/localhost:8000\/\u3002<\/p>\n<div>\u5982\u679c\u706b\u7bad\u753b\u9762\u6ca1\u6709\u663e\u793a\uff0c\u8bf7\u68c0\u67e5\u65e5\u5fd7\u3002<br \/>\n~\/*$ docker-compose logs -f<\/div>\n<h2>Postgres \u6570\u636e\u5e93<\/h2>\n<p>\u5728\u672c\u5730\u5b89\u88ddPostgres\u3002\u5728docker-compose.yml\u6a94\u6848\u4e2d\u65b0\u589e\u6578\u64da\u5eab\u8cc7\u8a0a\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">version<\/span><span class=\"pi\">:<\/span> <span class=\"s1\">'<\/span><span class=\"s\">3.8'<\/span>\r\n\r\n<span class=\"na\">services<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">build<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/app<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s\">python manage.py runserver 0.0.0.0:8000<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/app\/:\/usr\/src\/app\/<\/span>\r\n    <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">8000:8000<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.dev<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n  <span class=\"na\">db<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">postgres:13.0-alpine<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">postgres_data:\/var\/lib\/postgresql\/data\/<\/span>\r\n    <span class=\"na\">environment<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">POSTGRES_USER=hello_django<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">POSTGRES_PASSWORD=hello_django<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">POSTGRES_DB=hello_django_dev<\/span>\r\n\r\n<span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">postgres_data<\/span><span class=\"pi\">:<\/span>\r\n<\/code><\/pre>\n<div>\u6570\u636e\u5e93\u7528\u6237\u540d\u7b49\u4fe1\u606f\u3002<br \/>\n\u6309\u7167\u793a\u4f8b\u4fdd\u6301\u4e3a hello_django\uff0c\u4f46\u6682\u65f6\u4fdd\u7559\u6b64\u8bbe\u7f6e\u3002\u5982\u679c\u5c06\u6765\u51fa\u73b0\u95ee\u9898\uff0c\u53ef\u4ee5\u5728\u90a3\u65f6\u66f4\u6539\u3002<\/div>\n<p>\u5728.env.dev\u6587\u4ef6\u4e2d\u8fdb\u884c\u8865\u5145<\/p>\n<pre class=\"post-pre\"><code>DEBUG=1\r\nSECRET_KEY=\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\r\nDJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]\r\nSQL_ENGINE=django.db.backends.postgresql\r\nSQL_DATABASE=hello_django_dev\r\nSQL_USER=hello_django\r\nSQL_PASSWORD=hello_django\r\nSQL_HOST=db\r\nSQL_PORT=5432\r\n<\/code><\/pre>\n<p>settings.py \u7684\u66f4\u6539<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">DATABASES<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"sh\">\"<\/span><span class=\"s\">default<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"sh\">\"<\/span><span class=\"s\">ENGINE<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SQL_ENGINE<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">django.db.backends.sqlite3<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\r\n        <span class=\"sh\">\"<\/span><span class=\"s\">NAME<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SQL_DATABASE<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">BASE_DIR<\/span> <span class=\"o\">\/<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">db.sqlite3<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\r\n        <span class=\"sh\">\"<\/span><span class=\"s\">USER<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SQL_USER<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">user<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\r\n        <span class=\"sh\">\"<\/span><span class=\"s\">PASSWORD<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SQL_PASSWORD<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">password<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\r\n        <span class=\"sh\">\"<\/span><span class=\"s\">HOST<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SQL_HOST<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">localhost<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\r\n        <span class=\"sh\">\"<\/span><span class=\"s\">PORT<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">.<\/span><span class=\"nf\">get<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">SQL_PORT<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">5432<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>Dockerfile\u7684\u66f4\u6539<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># pull official base image<\/span>\r\n<span class=\"k\">FROM<\/span><span class=\"s\"> python:3.9.6-alpine<\/span>\r\n\r\n<span class=\"c\"># set work directory<\/span>\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> \/usr\/src\/app<\/span>\r\n\r\n<span class=\"c\"># set environment variables<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONDONTWRITEBYTECODE 1<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONUNBUFFERED 1<\/span>\r\n\r\n<span class=\"c\"># install psycopg2 dependencies<\/span>\r\n<span class=\"k\">RUN <\/span>apk update <span class=\"se\">\\\r\n<\/span>    <span class=\"o\">&amp;&amp;<\/span> apk add postgresql-dev gcc python3-dev musl-dev\r\n\r\n<span class=\"c\"># install dependencies<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">--upgrade<\/span> pip\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> .\/requirements.txt .<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">-r<\/span> requirements.txt\r\n\r\n<span class=\"c\"># copy project<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> . .<\/span>\r\n<\/code><\/pre>\n<div>\u4e3a\u4e86\u5b89\u88c5psycopg2\uff0c\u9700\u8981\u8fdb\u884c\u4ee5\u4e0b\u64cd\u4f5c\uff1a<br \/>\nRUN apk update \\ &amp;&amp; apk add postgresql-dev gcc python3-dev musl-dev<br \/>\n\u539f\u56e0\u662f\u4f7f\u7528\u4e86\u57fa\u4e8ealpine\u7684\u955c\u50cf\u3002\u6839\u636e\u6211\u7684\u8bb0\u5fc6\uff0c\u5f53\u521d\u5c1d\u8bd5\u4f7f\u7528\u201cslim\u201d\u955c\u50cf\u4f5c\u4e3a\u57fa\u7840\u65f6\u4f3c\u4e4e\u4e0d\u9700\u8981\u8fd9\u6837\u7684\u64cd\u4f5c\u3002\uff08\u6211\u7684\u8bb0\u5fc6\u53ef\u80fd\u6709\u8bef\uff09<br \/>\n\u56e0\u4e3a\u5982\u679c\u4e0d\u5c0f\u5fc3\u505a\u4e86\u4e00\u4e9b\u591a\u4f59\u7684\u64cd\u4f5c\u4f1a\u9047\u5230\u95ee\u9898\uff0c\u6240\u4ee5\u5bf9\u4e8e\u4e0d\u719f\u6089\u7684\u4eba\u6765\u8bf4\uff0c\u6700\u597d\u6309\u7167\u793a\u4f8b\u4f7f\u7528alpine\u8fdb\u884c\u64cd\u4f5c\u3002<\/div>\n<p>\u5c06\u4ee5\u4e0b\u5185\u5bb9\u8ffd\u52a0\u5230 requirements.txt \u6587\u4ef6\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code>django==4.1\r\npsycopg2-binary==2.9.1\r\n<\/code><\/pre>\n<p>\u540c\u65f6\u6267\u884c\u955c\u50cf\u6784\u5efa\u548c\u5bb9\u5668\u542f\u52a8\u7684\u5199\u6cd5\u5982\u4e0b\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<p>\u8fc1\u79fb<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nb\">exec <\/span>web python manage.py migrate <span class=\"nt\">--noinput<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u5728\u8fd9\u91cc\u51fa\u73b0\u9519\u8bef\uff0c\u53ef\u4ee5\u53c2\u8003\u793a\u8303\u7f51\u7ad9\u8fdb\u884c\u68c0\u67e5\u3002<\/p>\n<p>\u5982\u679cPostgres\u6b63\u5728\u8fd0\u884c\uff0c\u5219\u5e94\u8be5\u80fd\u591f\u786e\u8ba4\u9ed8\u8ba4\u7684Django\u8868\u5df2\u88ab\u521b\u5efa\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nb\">exec <\/span>db psql <span class=\"nt\">--username<\/span><span class=\"o\">=<\/span>hello_django <span class=\"nt\">--dbname<\/span><span class=\"o\">=<\/span>hello_django_dev\r\n<\/code><\/pre>\n<p>\u4ee5\u4e0b\u662f\u5c06=#\u53f3\u8fb9\u7684\u8f93\u5165\u547d\u4ee4\u3002<\/p>\n<pre class=\"post-pre\"><code>psql <span class=\"o\">(<\/span>13.0<span class=\"o\">)<\/span>\r\nType <span class=\"s2\">\"help\"<\/span> <span class=\"k\">for <\/span>help.\r\n\r\n<span class=\"nv\">hello_django_dev<\/span><span class=\"o\">=<\/span><span class=\"c\"># \\l<\/span>\r\n                                          List of databases\r\n       Name       |    Owner     | Encoding |  Collate   |   Ctype    |       Access privileges\r\n<span class=\"nt\">------------------<\/span>+--------------+----------+------------+------------+-------------------------------\r\n hello_django_dev | hello_django | UTF8     | en_US.utf8 | en_US.utf8 |\r\n postgres         | hello_django | UTF8     | en_US.utf8 | en_US.utf8 |\r\n template0        | hello_django | UTF8     | en_US.utf8 | en_US.utf8 | <span class=\"o\">=<\/span>c\/hello_django              +\r\n                  |              |          |            |            | <span class=\"nv\">hello_django<\/span><span class=\"o\">=<\/span>CTc\/hello_django\r\n template1        | hello_django | UTF8     | en_US.utf8 | en_US.utf8 | <span class=\"o\">=<\/span>c\/hello_django              +\r\n                  |              |          |            |            | <span class=\"nv\">hello_django<\/span><span class=\"o\">=<\/span>CTc\/hello_django\r\n<span class=\"o\">(<\/span>4 rows<span class=\"o\">)<\/span>\r\n\r\n<span class=\"nv\">hello_django_dev<\/span><span class=\"o\">=<\/span><span class=\"c\"># \\c hello_django_dev<\/span>\r\nYou are now connected to database <span class=\"s2\">\"hello_django_dev\"<\/span> as user <span class=\"s2\">\"hello_django\"<\/span><span class=\"nb\">.<\/span>\r\n\r\n<span class=\"nv\">hello_django_dev<\/span><span class=\"o\">=<\/span><span class=\"c\"># \\dt<\/span>\r\n                     List of relations\r\n Schema |            Name            | Type  |    Owner\r\n<span class=\"nt\">--------<\/span>+----------------------------+-------+--------------\r\n public | auth_group                 | table | hello_django\r\n public | auth_group_permissions     | table | hello_django\r\n public | auth_permission            | table | hello_django\r\n public | auth_user                  | table | hello_django\r\n public | auth_user_groups           | table | hello_django\r\n public | auth_user_user_permissions | table | hello_django\r\n public | django_admin_log           | table | hello_django\r\n public | django_content_type        | table | hello_django\r\n public | django_migrations          | table | hello_django\r\n public | django_session             | table | hello_django\r\n<span class=\"o\">(<\/span>10 rows<span class=\"o\">)<\/span>\r\n\r\n<span class=\"nv\">hello_django_dev<\/span><span class=\"o\">=<\/span><span class=\"c\"># \\q<\/span>\r\n<\/code><\/pre>\n<p>\u770b\u770b\u97f3\u91cf\u7684\u8be6\u7ec6\u8d44\u6599\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker volume inspect hoge-on-docker_postgres_data\r\n\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u2191 _postgres_data\u306e\u524d\u306f\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u540d\u3002\u81ea\u5206\u306e\u74b0\u5883\u306b\u5408\u308f\u305b\u308b\u3002\r\n<\/code><\/pre>\n<p>\u53ea\u8981\u5305\u542b\u4ee5\u4e0b\u663e\u793a\u5c31\u53ef\u4ee5<\/p>\n<pre class=\"post-pre\"><code><span class=\"o\">[<\/span>\r\n    <span class=\"o\">{<\/span>\r\n        <span class=\"s2\">\"CreatedAt\"<\/span>: <span class=\"s2\">\"2021-08-23T15:49:08Z\"<\/span>,\r\n        <span class=\"s2\">\"Driver\"<\/span>: <span class=\"s2\">\"local\"<\/span>,\r\n        <span class=\"s2\">\"Labels\"<\/span>: <span class=\"o\">{<\/span>\r\n            <span class=\"s2\">\"com.docker.compose.project\"<\/span>: <span class=\"s2\">\"hoge-on-docker\"<\/span>,\r\n            <span class=\"s2\">\"com.docker.compose.version\"<\/span>: <span class=\"s2\">\"1.29.2\"<\/span>,\r\n            <span class=\"s2\">\"com.docker.compose.volume\"<\/span>: <span class=\"s2\">\"postgres_data\"<\/span>\r\n        <span class=\"o\">}<\/span>,\r\n        <span class=\"s2\">\"Mountpoint\"<\/span>: <span class=\"s2\">\"\/var\/lib\/docker\/volumes\/hoge-on-docker_postgres_data\/_data\"<\/span>,\r\n        <span class=\"s2\">\"Name\"<\/span>: <span class=\"s2\">\"hoge-on-docker_postgres_data\"<\/span>,\r\n        <span class=\"s2\">\"Options\"<\/span>: null,\r\n        <span class=\"s2\">\"Scope\"<\/span>: <span class=\"s2\">\"local\"<\/span>\r\n    <span class=\"o\">}<\/span>\r\n<span class=\"o\">]<\/span>\r\n<\/code><\/pre>\n<p>\u5728app\u76ee\u5f55\u7684\u6839\u76ee\u5f55\u4e0b\u6dfb\u52a0entrypoint.sh\u811a\u672c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">#!\/bin\/sh<\/span>\r\n\r\n<span class=\"k\">if<\/span> <span class=\"o\">[<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$DATABASE<\/span><span class=\"s2\">\"<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"postgres\"<\/span> <span class=\"o\">]<\/span>\r\n<span class=\"k\">then\r\n    <\/span><span class=\"nb\">echo<\/span> <span class=\"s2\">\"Waiting for postgres...\"<\/span>\r\n\r\n    <span class=\"k\">while<\/span> <span class=\"o\">!<\/span> nc <span class=\"nt\">-z<\/span> <span class=\"nv\">$SQL_HOST<\/span> <span class=\"nv\">$SQL_PORT<\/span><span class=\"p\">;<\/span> <span class=\"k\">do\r\n      <\/span><span class=\"nb\">sleep <\/span>0.1\r\n    <span class=\"k\">done\r\n\r\n    <\/span><span class=\"nb\">echo<\/span> <span class=\"s2\">\"PostgreSQL started\"<\/span>\r\n<span class=\"k\">fi\r\n\r\n<\/span>python manage.py flush <span class=\"nt\">--no-input<\/span>\r\npython manage.py migrate\r\n\r\n<span class=\"nb\">exec<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$@<\/span><span class=\"s2\">\"<\/span>\r\n<\/code><\/pre>\n<p>\u7acb\u5373\u4fee\u6539 entrypoint.sh \u6587\u4ef6\u7684\u6267\u884c\u6743\u9650\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span><span class=\"nb\">chmod<\/span> +x app\/entrypoint.sh\r\n<\/code><\/pre>\n<p>Dockerfile\u7684\u4fee\u6539<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\"># pull official base image<\/span>\r\n<span class=\"k\">FROM<\/span><span class=\"s\"> python:3.9.6-alpine<\/span>\r\n\r\n<span class=\"c\"># set work directory<\/span>\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> \/usr\/src\/app<\/span>\r\n\r\n<span class=\"c\"># set environment variables<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONDONTWRITEBYTECODE 1<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONUNBUFFERED 1<\/span>\r\n\r\n<span class=\"c\"># install psycopg2 dependencies<\/span>\r\n<span class=\"k\">RUN <\/span>apk update <span class=\"se\">\\\r\n<\/span>    <span class=\"o\">&amp;&amp;<\/span> apk add postgresql-dev gcc python3-dev musl-dev\r\n\r\n<span class=\"c\"># install dependencies<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">--upgrade<\/span> pip\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> .\/requirements.txt .<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">-r<\/span> requirements.txt\r\n\r\n<span class=\"c\"># copy entrypoint.sh<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> .\/entrypoint.sh .<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">sed<\/span> <span class=\"nt\">-i<\/span> <span class=\"s1\">'s\/\\r$\/\/g'<\/span> \/usr\/src\/app\/entrypoint.sh\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">chmod<\/span> +x \/usr\/src\/app\/entrypoint.sh\r\n\r\n<span class=\"c\"># copy project<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> . .<\/span>\r\n\r\n<span class=\"c\"># run entrypoint.sh<\/span>\r\n<span class=\"k\">ENTRYPOINT<\/span><span class=\"s\"> [\"\/usr\/src\/app\/entrypoint.sh\"]<\/span>\r\n<\/code><\/pre>\n<p>\u5c06\u5185\u5bb9\u6dfb\u52a0\u5230.env.dev\u6587\u4ef6\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code>DEBUG=1\r\nSECRET_KEY=\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\r\nDJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]\r\nSQL_ENGINE=django.db.backends.postgresql\r\nSQL_DATABASE=hello_django_dev\r\nSQL_USER=hello_django\r\nSQL_PASSWORD=hello_django\r\nSQL_HOST=db\r\nSQL_PORT=5432\r\nDATABASE=postgres\r\n<\/code><\/pre>\n<p>\u5efa\u7acb\u6620\u50cf\u4e26\u555f\u52d5\u5bb9\u5668\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<p>\u53ea\u9700\u7528\u6d4f\u89c8\u5668\u8bbf\u95ee http:\/\/localhost:8000\/ \uff0c\u5982\u679c\u663e\u793a\u4e86\u706b\u7bad\u5219\u8868\u793aOK\u3002<\/p>\n<div>\u5173\u4e8ePostgres Notes\u7684\u5907\u5fd8\u5f55<br \/>\n\u5b83\u4ecb\u7ecd\u4e86\u5982\u4f55\u4ec5\u4f7f\u7528Django\u6765\u751f\u6210\u548c\u542f\u52a8\u5bb9\u5668\u3002\u53ea\u9700\u5728\u6784\u5efa\u65f6\u4e0d\u8bbe\u7f6e\u73af\u5883\u53d8\u91cfDATABASE=postgres\u5373\u53ef\u5b9e\u73b0\u3002\u547d\u4ee4\u7684\u4e66\u5199\u65b9\u5f0f\u53ef\u4ee5\u53c2\u8003\u793a\u4f8b\u7f51\u7ad9\u3002\u786e\u5b9e\uff0c\u901a\u8fc7\u8fd9\u79cd\u65b9\u5f0f\u6267\u884c\u65f6\uff0csettings.py\u5c06\u4f1a\u4e3asqlite3\u8fdb\u884c\u914d\u7f6e\u3002<br \/>\n\u662f\u5426\u6709\u5fc5\u8981\u91c7\u7528\u8fd9\u79cd\u542f\u52a8\u65b9\u5f0f\u5462\uff1f\u76ee\u524d\u8fd8\u60f3\u4e0d\u5230\u3002\u4e5f\u8bb8\u5728\u4ece\u5934\u5f00\u59cb\u5f00\u53d1\u65f6\u4f1a\u9047\u5230\u8fd9\u79cd\u60c5\u51b5\u5427\uff1f\u73b0\u5728\u4e0d\u7ba1\u5b83\uff0c\u7ee7\u7eed\u524d\u8fdb\u5427\u3002<\/div>\n<h2>\u72ec\u89d2\u517d<\/h2>\n<p>\u5728\u5c06Nginx\u548cDjango\u8fde\u63a5\u8d77\u6765\u65f6\uff0c\u4f7f\u7528Gunicorn\u4f5c\u4e3a\u4e2d\u95f4\u901a\u4fe1\u5de5\u5177\u3002\u9700\u8981\u5728requirements.txt\u6587\u4ef6\u4e2d\u8fdb\u884c\u8ffd\u52a0\u3002<\/p>\n<pre class=\"post-pre\"><code>django==4.1\r\ngunicorn==20.1.0\r\npsycopg2-binary==2.9.1\r\n<\/code><\/pre>\n<p>\u5c3d\u7ba1\u6b63\u5f0f\u670d\u52a1\u5668\u4f7f\u7528\u7684\u662f nginx\uff0c\u4f46\u5728\u5f00\u53d1\u9636\u6bb5\u6211\u60f3\u8981\u4f7f\u7528 Django \u5185\u7f6e\u670d\u52a1\u5668\u3002\u6211\u60f3\u8981\u5728\u5f00\u53d1\u548c\u6b63\u5f0f\u90e8\u7f72\u4e2d\u4f7f\u7528\u4e0d\u540c\u7684 docker-compose\u3002<\/p>\n<p>\u672c\u756a\u7528\u306e docker-compose.prod.yml \u3092\u4f5c\u6210\u3002docker-compose.yml \u3092\u8907\u88fd\u30fb\u5909\u66f4\u3057\u3066\u4f5c\u308b<\/p>\n<p>\u672c\u756a\u3067\u306f\u3001runserver\u3067\u306f\u306a\u304fgunicorn\u3092\u8d77\u52d5<br \/>\n\u672c\u756a\u3067\u306f\u3001web\u30b3\u30f3\u30c6\u30ca\u3067\u30db\u30b9\u30c8\u3068\u30b3\u30f3\u30c6\u30ca\u306e\u9023\u52d5\uff08\u30d0\u30a4\u30f3\u30c9\u30de\u30a6\u30f3\u30c8\uff09\u306f\u4e0d\u8981\u306a\u306e\u3067\u524a\u9664<\/p>\n<p>\u672c\u756a\u7528\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb .env.prod \u3092\u7528\u610f\u3002\u958b\u767a\u7528\u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb.env.dev \u3092\u8907\u88fd\u30fb\u5909\u66f4\u3057\u3066\u4f5c\u308b<\/p>\n<p>DEBUG \u3092 1 \u304b\u3089 0 \u306b\u5909\u66f4<br \/>\nSQL_DATABASE \u3092 hello_django_dev \u304b\u3089 hello_django_prod \u306b\u5909\u66f4<\/p>\n<p>\u672c\u756a db\u7528\u306e\u8a2d\u5b9a\u30d5\u30a1\u30a4\u30eb .env.prod.db \u3092\u7528\u610f<\/p>\n<p>docker-compose.yml \u8907\u88fd\u76f4\u5f8c\u306e docker-compose.prod.yml \u306b\u542b\u307e\u308c\u3066\u3044\u308b\u3001db \u30a4\u30e1\u30fc\u30b8\u751f\u6210\u306b\u5fc5\u8981\u306aPOSTGRES\u74b0\u5883\u5909\u6570\u3092\u3001\u3053\u306e .env.prod.db \u306b\u79fb\u884c\u3059\u308b\u3002\uff08_dev \u2192 _prod \u306e\u66f8\u66ff\u3048\u3092\u5fd8\u308c\u305a\u306b\uff09<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">version<\/span><span class=\"pi\">:<\/span> <span class=\"s1\">'<\/span><span class=\"s\">3.8'<\/span>\r\n\r\n<span class=\"na\">services<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">build<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/app<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s\">gunicorn config.wsgi:application --bind 0.0.0.0:8000<\/span>\r\n    <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">8000:8000<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n  <span class=\"na\">db<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">postgres:13.0-alpine<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">postgres_data:\/var\/lib\/postgresql\/data\/<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod.db<\/span>\r\n\r\n<span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">postgres_data<\/span><span class=\"pi\">:<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>DEBUG=0\r\nSECRET_KEY=\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\u3007\r\nDJANGO_ALLOWED_HOSTS=localhost 127.0.0.1 [::1]\r\nSQL_ENGINE=django.db.backends.postgresql\r\nSQL_DATABASE=hello_django_prod\r\nSQL_USER=hello_django\r\nSQL_PASSWORD=hello_django\r\nSQL_HOST=db\r\nSQL_PORT=5432\r\nDATABASE=postgres\r\n<\/code><\/pre>\n<p>.env.prod.db\u7684\u6570\u636e\u5e93\u540d\u79f0\u4e0d\u662f_dev\u800c\u662f_prod\u3002\u5728\u4f7f\u7528\u590d\u5236\u548c\u7c98\u8d34\u65f6\u8bf7\u6ce8\u610f\u3002<\/p>\n<pre class=\"post-pre\"><code>POSTGRES_USER=hello_django\r\nPOSTGRES_PASSWORD=hello_django\r\nPOSTGRES_DB=hello_django_prod\r\n<\/code><\/pre>\n<p>\u5220\u9664\u5bb9\u5668\uff08\u4f7f\u7528-v\u53c2\u6570\u4e5f\u5c06\u5220\u9664\u76f8\u5173\u5377\uff09\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose down <span class=\"nt\">-v<\/span>\r\n<\/code><\/pre>\n<p>\u6784\u5efa\u672c\u5730\u955c\u50cf\u5e76\u542f\u52a8\u5bb9\u5668\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<p>\u4f7f\u7528\u6d4f\u89c8\u5668\u6253\u5f00 http:\/\/localhost:8000\/admin\uff0c\u5982\u679c\u663e\u793a\u7ba1\u7406\u5458\u767b\u5f55\u9875\u9762\uff0c\u5219\u8868\u793a\u6b63\u5e38\u3002\u73b0\u5728\u6ca1\u6709CSS\u6837\u5f0f\u4e5f\u53ef\u4ee5\u3002\u4e00\u65e6\u5b8c\u6210staticfile\u7684\u8bbe\u7f6e\uff0c\u95ee\u9898\u5c06\u5f97\u5230\u89e3\u51b3\u3002<\/p>\n<p>\u5982\u679c\u51fa\u73b0\u5f02\u5e38\uff0c\u68c0\u67e5\u65e5\u5fd7\u3002\u8bf7\u6ce8\u610f\uff0c\u5982\u679c\u4e0d\u6307\u5b9a\u6587\u4ef6\u540d\uff0c\u9ed8\u8ba4\u4f1a\u8bfb\u53d6 docker-compose.yml\u3002\u5982\u679c\u60f3\u8981\u67e5\u770b\u751f\u4ea7\u73af\u5883\u5bb9\u5668\u7684\u8be6\u7ec6\u4fe1\u606f\uff0c\u8bf7\u4e0d\u8981\u5fd8\u8bb0\u6307\u5b9a\u6587\u4ef6\u540d -f docker-compose.prod.yml\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml logs <span class=\"nt\">-f<\/span>\r\n<\/code><\/pre>\n<h2>\u751f\u4ea7Dockerfile<\/h2>\n<p>\u9700\u8981\u51c6\u5907\u9002\u7528\u4e8e\u751f\u4ea7\u7684Dockerfile\u3002<br \/>\n\u5728\u5f53\u524d\u7684Dockerfile\u548centrypoint.sh\u7684\u7ec4\u5408\u4e2d\uff0c\u6bcf\u6b21\u542f\u52a8\u5bb9\u5668\u90fd\u9700\u8981\u8fdb\u884c\u4e00\u6b21\u6784\u5efa\uff0c<\/p>\n<pre class=\"post-pre\"><code>python manage.py flush <span class=\"nt\">--no-input<\/span>\u3000\u3000\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u306e\u30af\u30ea\u30a2\r\npython manage.py migrate\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u30de\u30a4\u30b0\u30ec\u30fc\u30c8\r\n<\/code><\/pre>\n<p>\u5728\u672c\u5730\u73af\u5883\u4e2d\u6267\u884c\u8fd9\u4e2a\u6ca1\u6709\u95ee\u9898\uff0c\u4f46\u662f\u5728\u751f\u4ea7\u73af\u5883\u4e2d\u88ab\u6267\u884c\u8fd9\u4e2a\u5c31\u4e0d\u597d\u4e86\u3002\u6570\u636e\u5e93\u8fc1\u79fb\u53ef\u4ee5\u7528\u300e\u6ca1\u6709\u53d8\u66f4\u6240\u4ee5\u4e0d\u9700\u8981\u300f\u6765\u89e3\u51b3\uff0c\u4f46\u662f\u6e05\u7a7a\u6570\u636e\u5e93\u5219\u662f\u4e2a\u5927\u95ee\u9898\u3002<\/p>\n<p>\u5728\u5e94\u7528\u7a0b\u5e8f\u7684\u6839\u76ee\u5f55\u4e0b\u51c6\u5907 entrypoint.prod.sh \u8fd9\u4e2a\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">#!\/bin\/sh<\/span>\r\n\r\n<span class=\"k\">if<\/span> <span class=\"o\">[<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$DATABASE<\/span><span class=\"s2\">\"<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"postgres\"<\/span> <span class=\"o\">]<\/span>\r\n<span class=\"k\">then\r\n    <\/span><span class=\"nb\">echo<\/span> <span class=\"s2\">\"Waiting for postgres...\"<\/span>\r\n\r\n    <span class=\"k\">while<\/span> <span class=\"o\">!<\/span> nc <span class=\"nt\">-z<\/span> <span class=\"nv\">$SQL_HOST<\/span> <span class=\"nv\">$SQL_PORT<\/span><span class=\"p\">;<\/span> <span class=\"k\">do\r\n      <\/span><span class=\"nb\">sleep <\/span>0.1\r\n    <span class=\"k\">done\r\n\r\n    <\/span><span class=\"nb\">echo<\/span> <span class=\"s2\">\"PostgreSQL started\"<\/span>\r\n<span class=\"k\">fi\r\n\r\n<\/span><span class=\"nb\">exec<\/span> <span class=\"s2\">\"<\/span><span class=\"nv\">$@<\/span><span class=\"s2\">\"<\/span>\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u6539\u53d8\u6587\u4ef6\u7684\u6267\u884c\u6743\u9650\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span><span class=\"nb\">chmod<\/span> +x app\/entrypoint.prod.sh\r\n<\/code><\/pre>\n<h4>\u51c6\u5907 Dockerfile.prod<\/h4>\n<p>\u4e3a\u4e86\u51cf\u5c11\u5b9e\u9645\u56fe\u50cf\u7684\u5bb9\u91cf\uff0c\u4f7f\u7528\u4e86Builder\u548cFinal\u4e24\u4e2a\u6b65\u9aa4\u7684\u7ed3\u6784\u3002\u91c7\u7528\u4e86Multi-stage Build\u7684\u65b9\u6cd5\u3002<\/p>\n<p>Builder<\/p>\n<p>psycopg2\u3092\u52d5\u304b\u3059\u306e\u306b\u5fc5\u8981\u306a\u30a2\u30d7\u30ea\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3002<br \/>\nflake8(lint)\u3092\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3057\u5b9f\u884c\u3057\u3066Django\u306eapp\u5185\u306e\u30b3\u30fc\u30c9\u306b\u554f\u984c\u304c\u7121\u3044\u304b\u30c1\u30a7\u30c3\u30af\u3002<br \/>\npip wheel ***** \u3067 requirements.txt\u306e\u30d1\u30c3\u30b1\u30fc\u30b8\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u306b\u5fc5\u8981\u306a wheel\u7fa4\u3092\u69cb\u7bc9\u3002wheel\u69cb\u7bc9\u306e\u5229\u70b9\u3084\u30aa\u30d7\u30b7\u30e7\u30f3\u306e\u89e3\u8aac\u306f\u3001https:\/\/kurozumi.github.io\/pip\/reference\/pip_wheel.html \u3092\u53c2\u7167\u3002<\/p>\n<p>Final<\/p>\n<p>libpq(PostgreSQL\u306eC\u8a00\u8a9e\u30a4\u30f3\u30bf\u30d5\u30a7\u30fc\u30b9)\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3002<br \/>\nBuilder\u3067\u4f7f\u3063\u305frequirements.txt\u3068\u3001Builder \u3067\u69cb\u7bc9\u3057\u305fwheel\u7fa4\u306e\u53d6\u308a\u8fbc\u307f\u3002\u3053\u308c\u3092\u4f7f\u3063\u3066\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u3002<br \/>\nentrypoint.prod.sh\u306e\u30b3\u30d4\u30fc\u306a\u3069<\/p>\n<pre class=\"post-pre\"><code><span class=\"c\">###########<\/span>\r\n<span class=\"c\"># BUILDER #<\/span>\r\n<span class=\"c\">###########<\/span>\r\n\r\n<span class=\"c\"># pull official base image<\/span>\r\n<span class=\"k\">FROM<\/span> <span class=\"s\">python:3.9.6-alpine<\/span> <span class=\"k\">as<\/span> <span class=\"s\">builder<\/span>\r\n\r\n<span class=\"c\"># set work directory<\/span>\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> \/usr\/src\/app<\/span>\r\n\r\n<span class=\"c\"># set environment variables<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONDONTWRITEBYTECODE 1<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> PYTHONUNBUFFERED 1<\/span>\r\n\r\n<span class=\"c\"># install psycopg2 dependencies<\/span>\r\n<span class=\"k\">RUN <\/span>apk update <span class=\"se\">\\\r\n<\/span>    <span class=\"o\">&amp;&amp;<\/span> apk add postgresql-dev gcc python3-dev musl-dev\r\n\r\n<span class=\"c\"># lint<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">--upgrade<\/span> pip\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install <\/span><span class=\"nv\">flake8<\/span><span class=\"o\">==<\/span>3.9.2\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> . .<\/span>\r\n<span class=\"k\">RUN <\/span>flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .\r\n\r\n<span class=\"c\"># install dependencies<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> .\/requirements.txt .<\/span>\r\n<span class=\"k\">RUN <\/span>pip wheel <span class=\"nt\">--no-cache-dir<\/span> <span class=\"nt\">--no-deps<\/span> <span class=\"nt\">--wheel-dir<\/span> \/usr\/src\/app\/wheels <span class=\"nt\">-r<\/span> requirements.txt\r\n\r\n\r\n<span class=\"c\">#########<\/span>\r\n<span class=\"c\"># FINAL #<\/span>\r\n<span class=\"c\">#########<\/span>\r\n\r\n<span class=\"c\"># pull official base image<\/span>\r\n<span class=\"k\">FROM<\/span><span class=\"s\"> python:3.9.6-alpine<\/span>\r\n\r\n<span class=\"c\"># create directory for the app user<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">mkdir<\/span> <span class=\"nt\">-p<\/span> \/home\/app\r\n\r\n<span class=\"c\"># create the app user<\/span>\r\n<span class=\"k\">RUN <\/span>addgroup <span class=\"nt\">-S<\/span> app <span class=\"o\">&amp;&amp;<\/span> adduser <span class=\"nt\">-S<\/span> app <span class=\"nt\">-G<\/span> app\r\n\r\n<span class=\"c\"># create the appropriate directories<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> HOME=\/home\/app<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> APP_HOME=\/home\/app\/web<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">mkdir<\/span> <span class=\"nv\">$APP_HOME<\/span>\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> $APP_HOME<\/span>\r\n\r\n<span class=\"c\"># install dependencies<\/span>\r\n<span class=\"k\">RUN <\/span>apk update <span class=\"o\">&amp;&amp;<\/span> apk add libpq\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> --from=builder \/usr\/src\/app\/wheels \/wheels<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> --from=builder \/usr\/src\/app\/requirements.txt .<\/span>\r\n<span class=\"k\">RUN <\/span>pip <span class=\"nb\">install<\/span> <span class=\"nt\">--no-cache<\/span> \/wheels\/<span class=\"k\">*<\/span>\r\n\r\n<span class=\"c\"># copy entrypoint.prod.sh<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> .\/entrypoint.prod.sh .<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">sed<\/span> <span class=\"nt\">-i<\/span> <span class=\"s1\">'s\/\\r$\/\/g'<\/span>  <span class=\"nv\">$APP_HOME<\/span>\/entrypoint.prod.sh\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">chmod<\/span> +x  <span class=\"nv\">$APP_HOME<\/span>\/entrypoint.prod.sh\r\n\r\n<span class=\"c\"># copy project<\/span>\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> . $APP_HOME<\/span>\r\n\r\n<span class=\"c\"># chown all the files to the app user<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">chown<\/span> <span class=\"nt\">-R<\/span> app:app <span class=\"nv\">$APP_HOME<\/span>\r\n\r\n<span class=\"c\"># change to the app user<\/span>\r\n<span class=\"k\">USER<\/span><span class=\"s\"> app<\/span>\r\n\r\n<span class=\"c\"># run entrypoint.prod.sh<\/span>\r\n<span class=\"k\">ENTRYPOINT<\/span><span class=\"s\"> [\"\/home\/app\/web\/entrypoint.prod.sh\"]<\/span>\r\n<\/code><\/pre>\n<div>\u4f7f\u7528sed\u547d\u4ee4\u8fdb\u884c\u7684\u64cd\u4f5c\uff08\u5b9e\u9645\u4e0a\u8fd8\u6ca1\u6709\u5b8c\u5168\u7406\u89e3\u3002\u53ea\u662f\u7559\u4e0b\u5907\u5fd8\u5f55\u7684\u611f\u89c9&#8230;\uff09<br \/>\nsed\u547d\u4ee4\u662f\u201c\u6d41\u7f16\u8f91\u5668\u201d\u7684\u7f29\u5199\u3002\u6839\u636e\u6307\u5b9a\u7684\u547d\u4ee4\u5bf9\u6307\u5b9a\u7684\u6587\u4ef6\u8fdb\u884c\u5904\u7406\u3002\u6309\u884c\u8bfb\u53d6\u8f93\u5165\uff0c\u8fdb\u884c\u6587\u672c\u8f6c\u6362\u548c\u7f16\u8f91\uff0c\u7136\u540e\u6309\u884c\u8f93\u51fa\u3002\u652f\u6301\u6b63\u5219\u8868\u8fbe\u5f0f\u3002<br \/>\n\u3010\u53c2\u8003\u3011\u66f4\u6539\u6362\u884c\u7b26<br \/>\n\u7531\u4e8e\u8fd9\u6b21\u60f3\u8981\u76f4\u63a5\u8986\u76d6\u6587\u4ef6\uff0c\u6240\u4ee5\u4f7f\u7528-i\u9009\u9879<br \/>\n\u8fd0\u884c sed -i &#8216;s\/\\r$\/\/g&#8217; $APP_HOME\/entrypoint.prod.sh<br \/>\n\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u90e8\u5206\u8fd8\u4e0d\u591f\u719f\u7ec3\uff0c\u9700\u8981\u8fdb\u4e00\u6b65\u5b66\u4e60\u3002<\/div>\n<p>\u8bf7\u5c06\u5f53\u524d\u7684 docker-compose.prod.yml \u6587\u4ef6\u4e2d\u7684 web \u9879\u4fee\u6539\u4e3a\u8bfb\u53d6 Dockerfile.prod \u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">build<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">context<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/app<\/span>\r\n    <span class=\"na\">dockerfile<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Dockerfile.prod<\/span>\r\n  <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s\">gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000<\/span>\r\n  <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">8000:8000<\/span>\r\n  <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod<\/span>\r\n  <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n<\/code><\/pre>\n<p>\u51c6\u5907\u597d\u4e86\u5c31\u8bd5\u4e00\u4e0b\u3002\u5148\u6e05\u7a7a\u5e76\u6784\u5efa\uff0c\u7136\u540e\u6267\u884c\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml down <span class=\"nt\">-v<\/span>\r\n~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<p>\u6211\u8ba4\u4e3a\u4f1a\u51fa\u73b0\u8fd9\u79cd\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>executor failed running <span class=\"o\">[<\/span>\/bin\/sh <span class=\"nt\">-c<\/span> flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .]: <span class=\"nb\">exit <\/span>code: 1\r\nERROR: Service <span class=\"s1\">'web'<\/span> failed to build : Build failed\r\n<\/code><\/pre>\n<p>flake8\u662f\u4e00\u4e2a\u4ee3\u7801\u68c0\u67e5\u5de5\u5177\u3002\u4f3c\u4e4e\u4e5f\u4f1a\u6d89\u53ca\u5230Django\u81ea\u52a8\u751f\u6210\u7684\u90e8\u5206\u3002\u786e\u5b9e\uff0c\u6211\u5bf9\u6b64\u4e0d\u592a\u4e86\u89e3\uff0c\u6240\u4ee5\u53ea\u5c06config\u5185\u7684\u5185\u5bb9\u4f5c\u4e3a\u68c0\u67e5\u5bf9\u8c61\u3002<br \/>\n\u5728Dockerfile.prod\u4e2d\uff0c<br \/>\n\u5c06<br \/>\nRUN flake8 &#8211;ignore=E501,F401 .<br \/>\n\u66f4\u6539\u4e3a<br \/>\nRUN flake8 &#8211;ignore=E501,F401 .\/config\u3002<br \/>\n\u4ee5\u540e\uff0c\u5982\u679c\u6dfb\u52a0\u4e86Django\u5e94\u7528\u7a0b\u5e8f\uff0c\u5219\u5e94\u8be5\u68c0\u67e5\u8fd9\u4e9b\u76ee\u5f55\uff0c\u4f46\u5728\u611f\u5230\u9700\u8981\u4e4b\u524d\uff0c\u53ea\u5bf9config\u8fdb\u884c\u68c0\u67e5\u5373\u53ef\uff0c\u7136\u540e\u7ee7\u7eed\u3002\uff08\u8bf7\u4e0d\u8981\u6a21\u4eff\u8fd9\u79cd\u968f\u610f\u7684\u6001\u5ea6\uff09<\/p>\n<p>\u518d\u7f16\u8bd1\u5e76\u8fc1\u79fb\u3002\u9700\u8981\u8d85\u8fc710\u5206\u949f\u3002\u592a\u957f\u4e86\u3002\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml <span class=\"nb\">exec <\/span>web python manage.py migrate <span class=\"nt\">--noinput<\/span>\r\n<\/code><\/pre>\n<p>\u53ea\u9700\u8981\u4e00\u4e2a\u9009\u9879\uff0c\u7528\u4e2d\u6587\u5c06\u4ee5\u4e0b\u5185\u5bb9\u91cd\u65b0\u8868\u8ff0\uff1a<br \/>\n\u5728\u6d4f\u89c8\u5668\u4e2d\u8bbf\u95ee http:\/\/localhost:8000\/admin \u5e76\u663e\u793a\u5373\u53ef\uff0c\u65e0\u9700CSS\u6837\u5f0f\u3002\uff08\u5c1a\u672a\u6dfb\u52a0CSS\u6837\u5f0f\uff09<br \/>\n\u591a\u9636\u6bb5\u6784\u5efa\u4f7f\u56fe\u50cf\u6570\u636e\u7684\u5bb9\u91cf\u5e94\u8be5\u5927\u5927\u51cf\u5c0f\u3002\uff08\u5fd8\u8bb0\u8bb0\u5f55\u524d\u4e00\u4e2a\u72b6\u6001\u3002\uff09<\/p>\n<h2>Nginx ( \u6216\u8bd1\u4e3a&#8221;\u6069\u589e&#8221; )<\/h2>\n<p>\u5c06Nginx\u5f15\u5165\u7cfb\u7edf\u4e2d<br \/>\n\u5728docker-compose.prod.yml\u6587\u4ef6\u4e2d\u8fdb\u884c\u8865\u5145\u8bf4\u660e<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">nginx<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">build<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/nginx<\/span>\r\n  <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">1337:80<\/span>\r\n  <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">web<\/span>\r\n<\/code><\/pre>\n<p>\u5728\u9879\u76ee\u6839\u76ee\u5f55\uff08\u5373hoge-on-docker\/\uff09\u4e0b\u521b\u5efanginx\u6587\u4ef6\u5939\uff0c\u5e76\u5728\u6b64\u6587\u4ef6\u5939\u4e0b\u521b\u5efaDockerfile\u548cnginx.conf\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">FROM<\/span><span class=\"s\"> nginx:1.21-alpine<\/span>\r\n\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">rm<\/span> \/etc\/nginx\/conf.d\/default.conf\r\n<span class=\"k\">COPY<\/span><span class=\"s\"> nginx.conf \/etc\/nginx\/conf.d<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"k\">upstream<\/span> <span class=\"s\">config<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kn\">server<\/span> <span class=\"nf\">web<\/span><span class=\"p\">:<\/span><span class=\"mi\">8000<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">server<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kn\">listen<\/span> <span class=\"mi\">80<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"kn\">location<\/span> <span class=\"n\">\/<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kn\">proxy_pass<\/span> <span class=\"s\">http:\/\/config<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_set_header<\/span> <span class=\"s\">X-Forwarded-For<\/span> <span class=\"nv\">$proxy_add_x_forwarded_for<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_set_header<\/span> <span class=\"s\">Host<\/span> <span class=\"nv\">$host<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_redirect<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u4fee\u6539docker-compose.prod.yml\u6587\u4ef6\u4e2dweb\u7aef\u53e3\u7684\u914d\u7f6e\u3002\u539f\u5148\u4f7f\u7528ports\u53c2\u6570\u5c06\u5176\u8fde\u63a5\u5230\u5916\u90e8\uff0c\u4f46\u662f\u901a\u8fc7nginx\u4ee3\u7406\u540e\uff0c\u53ea\u6709\u5bb9\u5668\u80fd\u591f\u8fde\u63a5\u5230web\uff0c\u6240\u4ee5\u9700\u8981\u6539\u4e3aexpose\u53c2\u6570\u3002<br \/>\n\u5efa\u8bae\u5728\u67d0\u4e2a\u65f6\u95f4\u70b9\u786e\u8ba4\u65e0\u6cd5\u76f4\u63a5\u8bbf\u95eehttp:\/\/localhost:8000\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">build<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">context<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/app<\/span>\r\n    <span class=\"na\">dockerfile<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Dockerfile.prod<\/span>\r\n  <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s\">gunicorn hello_django.wsgi:application --bind 0.0.0.0:8000<\/span>\r\n  <span class=\"na\">expose<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"m\">8000<\/span>\r\n  <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod<\/span>\r\n  <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n<\/code><\/pre>\n<p>\u786e\u8ba4\u52a8\u4f5c<\/p>\n<pre class=\"post-pre\"><code>~\/*$ docker-compose -f docker-compose.prod.yml down -v\r\n~\/*$ docker-compose -f docker-compose.prod.yml up -d --build\r\n~\/*$ docker-compose -f docker-compose.prod.yml exec web python manage.py migrate --noinput\r\n<\/code><\/pre>\n<p>\u4f7f\u7528\u6d4f\u89c8\u5668\u8bbf\u95ee http:\/\/localhost:1337\/<\/p>\n<pre class=\"post-pre\"><code>Not Found\r\nThe requested resource was not found on this server.\r\n<\/code><\/pre>\n<p>\u5982\u679c\u663e\u793a\u4e3aOK\uff0c\u90a3\u5c31\u53ef\u4ee5\u4e86\u3002\u5982\u679c\u662f http:\/\/localhost:1337\/admin\uff0c\u5c31\u4f1a\u663e\u793a\u65e0\u6837\u5f0f\u7684\u7ba1\u7406\u9875\u9762\u767b\u5f55\u3002<\/p>\n<p>\u8ba9\u6211\u4eec\u5173\u95ed\u5bb9\u5668\u5427 (Let&#8217;s shut down the container)<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml down <span class=\"nt\">-v<\/span>\r\n<\/code><\/pre>\n<h2>\u9759\u6001\u6587\u4ef6<\/h2>\n<p>\u8bbe\u7f6e\u9759\u6001\u6587\u4ef6<\/p>\n<p>\u5728\u8fdb\u5165\u672c\u9898\u4e4b\u524d\uff0c\u8bf7\u5728\u4e0d\u5fd8\u8bb0\u7684\u60c5\u51b5\u4e0b\u66f4\u6539settings.py\u4e2d\u7684\u533a\u57df\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">LANGUAGE_CODE<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">ja<\/span><span class=\"sh\">'<\/span>\r\n<span class=\"n\">TIME_ZONE<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">'<\/span><span class=\"s\">Asia\/Tokyo<\/span><span class=\"sh\">'<\/span>\r\n<\/code><\/pre>\n<p>\u63a5\u4e0b\u6765\uff0c\u5728 settings.py \u6587\u4ef6\u4e2d\u5bf9\u4e8e\u9759\u6001\u6587\u4ef6\u7684\u4fee\u6539\u548c\u8ffd\u52a0\u8fdb\u884c\u5904\u7406\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">STATIC_URL<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">\/static\/<\/span><span class=\"sh\">\"<\/span>\r\n<span class=\"n\">STATIC_ROOT<\/span> <span class=\"o\">=<\/span> <span class=\"n\">BASE_DIR<\/span> <span class=\"o\">\/<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">staticfiles<\/span><span class=\"sh\">\"<\/span>\r\n<\/code><\/pre>\n<p>\u53ea\u6709\u5728\u5f00\u53d1\u6a21\u5f0f\u4e0b\uff08\u5373\u5f53 DEBUG=1 \u65f6\uff09\uff0c\u8bbf\u95ee http:\/\/localhost:8000\/static\/* \u65f6\uff0c\u4f1a\u53bb\u67e5\u627e app\/staticfiles\/*\u3002\u867d\u7136\u5c1a\u672a\u51c6\u5907 staticfiles \u76ee\u5f55\u3002\u3002Django \u5185\u7f6e\u670d\u52a1\u5668\u5728\u4f7f\u7528 python manage.py runserver \u547d\u4ee4\u542f\u52a8\u65f6\uff0c\u4f1a\u81ea\u52a8\u5b9e\u73b0\u8fd9\u4e2a\u529f\u80fd\u3002<br \/>\n\u7136\u800c\uff0c\u5728\u751f\u4ea7\u670d\u52a1\u5668\u4e2d\u4f7f\u7528\u7684 nginx \u9700\u8981\u624b\u52a8\u8bbe\u7f6e\u5404\u79cd\u914d\u7f6e\u3002<br \/>\n\u6309\u987a\u5e8f\u8fdb\u884c\u751f\u4ea7\u73af\u5883\u7684\u8bbe\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">version<\/span><span class=\"pi\">:<\/span> <span class=\"s1\">'<\/span><span class=\"s\">3.8'<\/span>\r\n\r\n<span class=\"na\">services<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">build<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">context<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/app<\/span>\r\n      <span class=\"na\">dockerfile<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Dockerfile.prod<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s\">gunicorn config.wsgi:application --bind 0.0.0.0:8000<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">static_volume:\/home\/app\/web\/staticfiles<\/span>\r\n    <span class=\"na\">expose<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"m\">8000<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n  <span class=\"na\">db<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">postgres:13.0-alpine<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">postgres_data:\/var\/lib\/postgresql\/data\/<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod.db<\/span>\r\n  <span class=\"na\">nginx<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">build<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/nginx<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">static_volume:\/home\/app\/web\/staticfiles<\/span>\r\n    <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">1337:80<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">web<\/span>\r\n\r\n<span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">postgres_data<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">static_volume<\/span><span class=\"pi\">:<\/span>\r\n<\/code><\/pre>\n<div>\u7406\u89e3\u4e0d\u8db3\u7684\u5907\u5fd8\u5f55<br \/>\n\u8bf4\u5b9e\u8bdd\uff0c\u6211\u5bf9\u793a\u4f8b\u7f51\u7ad9\u4e2d\u4ee5\u4e0b\u7684\u6587\u5b57\u7406\u89e3\u4e0d\u4e86\u3002\u5982\u679c\u80fd\u8bfb\u61c2\u6765\u6e90\u94fe\u63a5\u4e2d\u7684FAQ\uff0c\u53ef\u80fd\u5c31\u80fd\u6e05\u695a\u660e\u767d\u3002\u4f46\u6211\u73b0\u5728\u6ca1\u6709\u8fd9\u4e48\u5927\u7684\u80fd\u529b\uff0c\u6682\u65f6\u4fdd\u7559\u3002<br \/>\n\u4e3a\u4ec0\u4e48\u8fd9\u5f88\u5fc5\u8981\uff1f<br \/>\nDocker Compose\u901a\u5e38\u5c06\u547d\u540d\u5377\u4f5c\u4e3aroot\u6302\u8f7d\u3002\u800c\u4e14\u7531\u4e8e\u6211\u4eec\u4f7f\u7528\u7684\u662f\u975eroot\u7528\u6237\uff0c\u5982\u679c\u76ee\u5f55\u4e0d\u5b58\u5728\uff0c\u5728\u8fd0\u884ccollectstatic\u547d\u4ee4\u65f6\u4f1a\u51fa\u73b0\u6743\u9650\u88ab\u62d2\u7edd\u7684\u9519\u8bef\u3002<br \/>\n\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u4f60\u53ef\u4ee5\u9009\u62e9\uff1a\u5728Dockerfile\u4e2d\u521b\u5efa\u8be5\u6587\u4ef6\u5939\uff08\u6765\u6e90\uff09<\/p>\n<p>\u5728\u76ee\u5f55\u6302\u8f7d\u540e\u66f4\u6539\u5176\u6743\u9650\uff08\u6765\u6e90\uff09<br \/>\n\u6211\u4eec\u9009\u62e9\u4e86\u524d\u8005\u3002<\/p>\n<\/div>\n<div>\u5bf9\u4e8eweb\u548cnginx\u4e24\u4e2a\u5bb9\u5668\u4e2d\u90fd\u5b58\u5728\u4ee5\u4e0b\u5185\u5bb9\u7684`volumes`\u914d\u7f6e\uff1a<br \/>\n&#8220;`yaml<br \/>\n&#8211; static_volume:\/home\/app\/web\/staticfiles<br \/>\n&#8220;`<br \/>\n\u76ee\u524d\u65e0\u6cd5\u81ea\u4fe1\u5730\u7406\u89e3\u5176\u539f\u56e0\u3002\u3002\u73b0\u5728\u8bb0\u5f55\u4e0b\u81ea\u5df1\u7684\u7406\u89e3\u3002`collectstatic`\u547d\u4ee4\u88ab\u7528\u6765\u6536\u96c6\u548c\u5b58\u50a8\u9759\u6001\u6587\u4ef6\u7684\u4f4d\u7f6e\u662f\u5728web\u5bb9\u5668\u7684`\/home\/app\/web\/staticfiles`\u76ee\u5f55\u4e0b\u3002<\/p>\n<p>web\u5bb9\u5668\u901a\u8fc7`volumes`\u914d\u7f6e\u5c06\u9759\u6001\u6587\u4ef6\u4fdd\u7559\u5728\u4e0eDocker\u76f8\u5173\u7684\u7ba1\u7406\u533a\u57df\u7684`static_volume`\u4e2d\u3002<\/p>\n<p>nginx\u901a\u8fc7\uff08\u7a0d\u540e\u5c06\u5728nginx.conf\u4e2d\u6dfb\u52a0\uff09nginx.conf\u6587\u4ef6\uff0c\u5f53\u6536\u5230\u5bf9`http:\/\/\u3007\u3007\u3007\u3007\u3007\/static\/*`\u7684\u8bbf\u95ee\u8bf7\u6c42\u65f6\uff0c\u4f1a\u53bbnginx\u5bb9\u5668\u7684`\/home\/app\/web\/staticfiles`\u76ee\u5f55\u4e2d\u67e5\u627e\u5bf9\u5e94\u6587\u4ef6\u3002<\/p>\n<p>\u901a\u8fc7nginx\u7684`volumes`\u914d\u7f6e\u5c06`static_volume:\/home\/app\/web\/staticfiles`\u8fdb\u884c\u5173\u8054\uff0c\u56e0\u6b64web\u7aef\u5b58\u50a8\u5728static_volume\u4e2d\u7684\u9759\u6001\u6587\u4ef6\u4e5f\u4f1a\u88ab\u590d\u5236\u5230nginx\u7aef\u7684`\/home\/app\/web\/staticfiles`\u76ee\u5f55\u4e2d\u3002<br \/>\n\u6700\u7ec8\uff0cnginx\u80fd\u591f\u663e\u793a\u51fa`\/home\/app\/web\/staticfiles`\u4e2d\u5b58\u5728\u7684\u9759\u6001\u6587\u4ef6\u3002<\/p>\n<p>\u4ee5\u4e0a\u5e8f\u5217\u662f\u5426\u51c6\u786e\u65e0\u8bef\uff1f<\/p>\n<\/div>\n<p>\u867d\u7136\u6709\u4e9b\u4e0d\u660e\u767d\u7684\u5730\u65b9\uff0c\u4f46\u662f\u76f8\u4fe1\u6837\u672c\uff0c\u7ee7\u7eed\u524d\u8fdb\u5427\uff01<\/p>\n<p>\u5728Dockerfile.prod\u4e2d\u6dfb\u52a0\u4e00\u884c\u4ee3\u7801\u6765\u521b\u5efastaticfiles\u76ee\u5f55\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">ENV<\/span><span class=\"s\"> HOME=\/home\/app<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> APP_HOME=\/home\/app\/web<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">mkdir<\/span> <span class=\"nv\">$APP_HOME<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">mkdir<\/span> <span class=\"nv\">$APP_HOME<\/span>\/staticfiles\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> $APP_HOME<\/span>\r\n<\/code><\/pre>\n<p>nginx\u5c06\u8def\u7531\u5230staticfiles\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"k\">upstream<\/span> <span class=\"s\">config<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kn\">server<\/span> <span class=\"nf\">web<\/span><span class=\"p\">:<\/span><span class=\"mi\">8000<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">server<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kn\">listen<\/span> <span class=\"mi\">80<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"kn\">location<\/span> <span class=\"n\">\/<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kn\">proxy_pass<\/span> <span class=\"s\">http:\/\/config<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_set_header<\/span> <span class=\"s\">X-Forwarded-For<\/span> <span class=\"nv\">$proxy_add_x_forwarded_for<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_set_header<\/span> <span class=\"s\">Host<\/span> <span class=\"nv\">$host<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_redirect<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"kn\">location<\/span> <span class=\"n\">\/static\/<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kn\">alias<\/span> <span class=\"n\">\/home\/app\/web\/staticfiles\/<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u958b\u59cb\u9032\u884c\u52d5\u4f5c\u78ba\u8a8d<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<h4>\u8bf7\u5927\u5bb6\u5148\u7ee7\u7eed\u524d\u8fdb\uff0c\u56e0\u4e3a\u6211\u8ba4\u4e3a\u4e0d\u4f1a\u53d1\u751f\u30dd\u30ab\u30df\u30b9\u5bfc\u81f4\u7684\u9519\u8bef\u3002<\/h4>\n<p>\u51fa\u73b0\u4e86\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>\u30fb\u30fb\u30fb\u30fb\u30fb\u30fb\r\n <span class=\"o\">=&gt;<\/span> CACHED <span class=\"o\">[<\/span>builder 5\/9] RUN pip <span class=\"nb\">install <\/span><span class=\"nv\">flake8<\/span><span class=\"o\">==<\/span>3.9.2      0.0s\r\n <span class=\"o\">=&gt;<\/span> CANCELED <span class=\"o\">[<\/span>builder 6\/9] COPY <span class=\"nb\">.<\/span> .\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u30002.5s\r\n<span class=\"nt\">------<\/span>\r\n <span class=\"o\">&gt;<\/span> <span class=\"o\">[<\/span>stage-1  4\/15] RUN <span class=\"nb\">mkdir<\/span> \/home\/app\/web\/staticfiles:\r\n<span class=\"c\">#7 1.632 mkdir: can't create directory '\/home\/app\/web\/staticfiles': No such file or directory<\/span>\r\n<span class=\"nt\">------<\/span>\r\nexecutor failed running <span class=\"o\">[<\/span>\/bin\/sh <span class=\"nt\">-c<\/span> <span class=\"nb\">mkdir<\/span> <span class=\"nv\">$APP_HOME<\/span>\/staticfiles]: <span class=\"nb\">exit <\/span>code: 1\r\nERROR: Service <span class=\"s1\">'web'<\/span> failed to build : Build failed\r\n<\/code><\/pre>\n<p>\u5728\u7f16\u8f91docker-compose.prod.yml\u65f6\uff0c\u6211\u9519\u8bef\u5730\u7c98\u8d34\u4e86\u4f4d\u7f6e\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"s\">RUN mkdir $APP_HOME\/staticfiles<\/span>\r\n<span class=\"s\">RUN mkdir $APP_HOME<\/span>\r\n<\/code><\/pre>\n<p>\u6309\u7167\u4ee5\u4e0b\u987a\u5e8f\u8fdb\u884c\u4e86\u5904\u7406\uff0c\u5c06\u5176\u4e0a\u4e0b\u5bf9\u6362\u540e\uff0c\u6210\u529f\u8fdb\u884c\u4e86\u6784\u5efa\u3002<br \/>\n\u9519\u8bef\u5904\u7406\u5b8c\u6bd5\u3002<\/p>\n<p>\u7ee7\u7eed\u8fc1\u79fb<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml <span class=\"nb\">exec <\/span>web python manage.py migrate <span class=\"nt\">--noinput<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u6267\u884ccollectstatic\u64cd\u4f5c\uff0c\u5b83\u5c06\u628a\u591a\u4e2astatic\u76ee\u5f55\u4e2d\u7684\u4fe1\u606f\u6c47\u603b\uff08\u590d\u5236\uff09\u5230staticfiles\u76ee\u5f55\u4e2d\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml <span class=\"nb\">exec <\/span>web python manage.py collectstatic <span class=\"nt\">--no-input<\/span> <span class=\"nt\">--clear<\/span>\r\n<\/code><\/pre>\n<p>\u8ba9\u6211\u4eec\u68c0\u67e5\u7ba1\u7406\u5458\u7ba1\u7406\u9875\u9762\u3002\u5982\u679c\u4f60\u80fd\u8bbf\u95eehttp:\/\/localhost:1337\/admin \u5e76\u4e14\u770b\u5230\u4e86\u7f8e\u89c2\u7684CSS\u88c5\u9970\uff0c\u90a3\u5c31\u8868\u793a\u6210\u529f\u4e86\uff01<\/p>\n<p>\u8ba9\u5bb9\u5668\u505c\u6b62\u8fd0\u884c\u5427<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml down <span class=\"nt\">-v<\/span>\r\n<\/code><\/pre>\n<h2>\u5a92\u4f53\u6587\u4ef6<\/h2>\n<p>\u4e3a\u4e86\u5bf9Media Files\u8fdb\u884c\u529f\u80fd\u9a8c\u8bc1\uff0c\u9700\u8981\u5b9e\u9645\u4e0a\u4f20\u56fe\u50cf\u5e76\u51c6\u5907\u4e00\u4e2a\u5e94\u7528\u7a0b\u5e8f\u6765\u663e\u793a\u8fd9\u4e9b\u56fe\u50cf\u3002<br \/>\n\u4e3a\u4e86\u5c06\u5bb9\u5668\u4e2d\u7684\u7f16\u8f91\u5185\u5bb9\u53cd\u6620\u5230\u4e3b\u673a\u4e0a\uff0c\u9700\u8981\u5728\u5e26\u6709\u7ed1\u5b9a\u6302\u8f7d\u8bbe\u7f6e\u7684\u5f00\u53d1\u6a21\u5f0f\u4e0b\u8fdb\u884c\u6784\u5efa\u3002<br \/>\n\u5728\u8fd9\u91cc\u63d0\u5230\u7684\u4e3b\u673a\u662f\u6307\u5728WSL2 Ubuntu\u4e0a\u521b\u5efa\u7684\u6570\u636e\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<p>\u5728 web \u5bb9\u5668\u4e2d\u6267\u884c Django \u7684 startapp \u547d\u4ee4\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/*$ docker-compose exec web python manage.py startapp upload\r\n<\/code><\/pre>\n<p>\u5982\u679c\u5728\u8fd9\u91cc\uff0c\u4e3b\u673a\u7aef\u7684app\u76ee\u5f55\u4e5f\u751f\u6210\u4e86upload\uff0c\u90a3\u4e48\u5c31\u8bf4\u660e\u7ed1\u5b9a\u6302\u8f7d\u751f\u6548\u4e86\u3002<br \/>\n\u867d\u7136\u5728\u524d\u9762\u7a0d\u5fae\u63d0\u5230\u8fc7\uff0c\u4f46\u6211\u9047\u5230\u4e86\u5b8c\u5168\u6ca1\u6709\u7ed1\u5b9a\u6302\u8f7d\u8d77\u4f5c\u7528\u7684\u60c5\u51b5\u3002\u5728\u53e6\u4e00\u53f0\u7535\u8111\u4e0a\u91cd\u65b0\u521b\u5efa\u9879\u76ee\u540e\u5c31\u6210\u529f\u4e86\uff0c\u539f\u56e0\u4e0d\u660e\u3002\u3002<\/p>\n<p>\u521a\u624d\u548c\u4e4b\u524d\u76f8\u53cd\uff0c\u4e3b\u673a\u4e0a\u8fdb\u884c\u7684\u66f4\u6539\u5e94\u8be5\u4f1a\u53cd\u6620\u5728\u5bb9\u5668\u4e2d\u3002<br \/>\n\u5728\u4e3b\u673a\u4e0a\u7684 WSL2 Ubuntu \u4e0a\u66f4\u6539\u5e76\u4fdd\u5b58 $~\/works\/hoge-on-docker\/app\/config\/ \u76ee\u5f55\u4e0b\u7684 settings.py \u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">INSTALLED_APPS<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\r\n    <span class=\"err\">\u30fb\u30fb\u30fb\u30fb\u30fb\u30fb<\/span><span class=\"p\">,<\/span>\r\n    <span class=\"err\">\u30fb\u30fb\u30fb<\/span><span class=\"p\">,<\/span>\r\n\r\n    <span class=\"sh\">'<\/span><span class=\"s\">upload<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span>\r\n<span class=\"p\">]<\/span>\r\n<\/code><\/pre>\n<p>\u8986\u76d6\u4fdd\u5b58\uff0c\u6ca1\u6709\u4efb\u4f55\u95ee\u9898\u3002<\/p>\n<p>\u4e0b\u4e00\u6b65\u662f\u5728\u5bb9\u5668\u7aef\u751f\u6210\u5e76\u4fee\u6539\u5728\u4e3b\u673a\u7aef\u53cd\u6620\u7684\u4e0a\u4f20\u6587\u4ef6\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">django.shortcuts<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">render<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">django.core.files.storage<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">FileSystemStorage<\/span>\r\n\r\n<span class=\"k\">def<\/span> <span class=\"nf\">image_upload<\/span><span class=\"p\">(<\/span><span class=\"n\">request<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"n\">request<\/span><span class=\"p\">.<\/span><span class=\"n\">method<\/span> <span class=\"o\">==<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">POST<\/span><span class=\"sh\">\"<\/span> <span class=\"ow\">and<\/span> <span class=\"n\">request<\/span><span class=\"p\">.<\/span><span class=\"n\">FILES<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">image_file<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]:<\/span>\r\n        <span class=\"n\">image_file<\/span> <span class=\"o\">=<\/span> <span class=\"n\">request<\/span><span class=\"p\">.<\/span><span class=\"n\">FILES<\/span><span class=\"p\">[<\/span><span class=\"sh\">\"<\/span><span class=\"s\">image_file<\/span><span class=\"sh\">\"<\/span><span class=\"p\">]<\/span>\r\n        <span class=\"n\">fs<\/span> <span class=\"o\">=<\/span> <span class=\"nc\">FileSystemStorage<\/span><span class=\"p\">()<\/span>\r\n        <span class=\"n\">filename<\/span> <span class=\"o\">=<\/span> <span class=\"n\">fs<\/span><span class=\"p\">.<\/span><span class=\"nf\">save<\/span><span class=\"p\">(<\/span><span class=\"n\">image_file<\/span><span class=\"p\">.<\/span><span class=\"n\">name<\/span><span class=\"p\">,<\/span> <span class=\"n\">image_file<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"n\">image_url<\/span> <span class=\"o\">=<\/span> <span class=\"n\">fs<\/span><span class=\"p\">.<\/span><span class=\"nf\">url<\/span><span class=\"p\">(<\/span><span class=\"n\">filename<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"nf\">print<\/span><span class=\"p\">(<\/span><span class=\"n\">image_url<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span> <span class=\"nf\">render<\/span><span class=\"p\">(<\/span><span class=\"n\">request<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">upload.html<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span>\r\n            <span class=\"sh\">\"<\/span><span class=\"s\">image_url<\/span><span class=\"sh\">\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">image_url<\/span>\r\n        <span class=\"p\">})<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"nf\">render<\/span><span class=\"p\">(<\/span><span class=\"n\">request<\/span><span class=\"p\">,<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">upload.html<\/span><span class=\"sh\">\"<\/span><span class=\"p\">)<\/span>\r\n\r\n<\/code><\/pre>\n<p>\u65e0\u6cd5\u8fdb\u884c\u8986\u76d6\u4fdd\u5b58\u3002\u3002VScode\u663e\u793a\u9519\u8bef\u6d88\u606f\u3002<\/p>\n<pre class=\"post-pre\"><code>'views.py' \u3092\u4fdd\u5b58\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002\r\n\u30d5\u30a1\u30a4\u30eb 'vscode-remote:\/\/wsl+ubuntu\/home\/\u25cf\u25cf\u25cf\/works\/hoge-on-docker\/app\/upload\/views.py' \u3092\r\n\u66f8\u304d\u8fbc\u3080\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093 (NoPermissions (FileSystemError): \r\nError: EACCES: permission denied, open '\/home\/\u25cf\u25cf\u25cf\/works\/hoge-on-docker\/app\/upload\/views.py')\r\n<\/code><\/pre>\n<p>\u4f7f\u7528WSL2\u8fd0\u884cDocker\u65f6\u89e3\u51b3\u6743\u9650\u95ee\u9898\u7684\u7b80\u5355\u65b9\u6cd5\uff08\u4f7f\u7528docker-compose.yml\uff09\u3002\u8ba9\u6211\u91c7\u7528\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684WSL2\u89e3\u51b3\u65b9\u6848\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span><span class=\"nb\">sudo chown<\/span> <span class=\"nt\">-R<\/span> <span class=\"nv\">$USER<\/span>:<span class=\"nv\">$USER<\/span> <span class=\"nb\">.<\/span>\r\n<\/code><\/pre>\n<p>\u5982\u679c\u80fd\u6309\u4e0b&#8221;\u518d\u8bd5\u884c&#8221;\u6309\u94ae\uff0c\u5219\u8868\u793a\u6210\u529f\u8fdb\u884c\u4e86\u8986\u76d6\u4fdd\u5b58\u64cd\u4f5c\u3002\u5982\u679c\u6ca1\u6709\u4efb\u4f55\u53cd\u5e94\uff0c\u5373\u53ef\u786e\u8ba4\u6210\u529f\u4fdd\u5b58\u3002\u8fd9\u4e5f\u610f\u5473\u7740\u540c\u65f6\u5c06\u66f4\u6539\u53cd\u6620\u5230\u5bb9\u5668\u4e2d\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\uff0c\u521b\u5efa\u4e00\u4e2a\u540d\u4e3a app\/upload\/templates \u7684\u76ee\u5f55\uff0c\u5e76\u5728\u5176\u4e2d\u521b\u5efa upload.html\u3002<\/p>\n<pre class=\"post-pre\"><code>{% block content %}\r\n\r\n  <span class=\"nt\">&lt;form<\/span> <span class=\"na\">action=<\/span><span class=\"s\">\"{% url \"<\/span><span class=\"na\">upload<\/span><span class=\"err\">\"<\/span> <span class=\"err\">%}\"<\/span> <span class=\"na\">method=<\/span><span class=\"s\">\"post\"<\/span> <span class=\"na\">enctype=<\/span><span class=\"s\">\"multipart\/form-data\"<\/span><span class=\"nt\">&gt;<\/span>\r\n    {% csrf_token %}\r\n    <span class=\"nt\">&lt;input<\/span> <span class=\"na\">type=<\/span><span class=\"s\">\"file\"<\/span> <span class=\"na\">name=<\/span><span class=\"s\">\"image_file\"<\/span><span class=\"nt\">&gt;<\/span>\r\n    <span class=\"nt\">&lt;input<\/span> <span class=\"na\">type=<\/span><span class=\"s\">\"submit\"<\/span> <span class=\"na\">value=<\/span><span class=\"s\">\"submit\"<\/span> <span class=\"nt\">\/&gt;<\/span>\r\n  <span class=\"nt\">&lt;\/form&gt;<\/span>\r\n\r\n  {% if image_url %}\r\n    <span class=\"nt\">&lt;p&gt;<\/span>File uploaded at: <span class=\"nt\">&lt;a<\/span> <span class=\"na\">href=<\/span><span class=\"s\">\"{{ image_url }}\"<\/span><span class=\"nt\">&gt;<\/span>{{ image_url }}<span class=\"nt\">&lt;\/a&gt;&lt;\/p&gt;<\/span>\r\n  {% endif %}\r\n\r\n{% endblock %}\r\n\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"kn\">from<\/span> <span class=\"n\">django.contrib<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">admin<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">django.urls<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">path<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">django.conf<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">settings<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"n\">django.conf.urls.static<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">static<\/span>\r\n\r\n<span class=\"kn\">from<\/span> <span class=\"n\">upload.views<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">image_upload<\/span>\r\n\r\n<span class=\"n\">urlpatterns<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span>\r\n    <span class=\"nf\">path<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">image_upload<\/span><span class=\"p\">,<\/span> <span class=\"n\">name<\/span><span class=\"o\">=<\/span><span class=\"sh\">\"<\/span><span class=\"s\">upload<\/span><span class=\"sh\">\"<\/span><span class=\"p\">),<\/span>\r\n    <span class=\"nf\">path<\/span><span class=\"p\">(<\/span><span class=\"sh\">\"<\/span><span class=\"s\">admin\/<\/span><span class=\"sh\">\"<\/span><span class=\"p\">,<\/span> <span class=\"n\">admin<\/span><span class=\"p\">.<\/span><span class=\"n\">site<\/span><span class=\"p\">.<\/span><span class=\"n\">urls<\/span><span class=\"p\">),<\/span>\r\n<span class=\"p\">]<\/span>\r\n\r\n<span class=\"k\">if<\/span> <span class=\"nf\">bool<\/span><span class=\"p\">(<\/span><span class=\"n\">settings<\/span><span class=\"p\">.<\/span><span class=\"n\">DEBUG<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"n\">urlpatterns<\/span> <span class=\"o\">+=<\/span> <span class=\"nf\">static<\/span><span class=\"p\">(<\/span><span class=\"n\">settings<\/span><span class=\"p\">.<\/span><span class=\"n\">MEDIA_URL<\/span><span class=\"p\">,<\/span> <span class=\"n\">document_root<\/span><span class=\"o\">=<\/span><span class=\"n\">settings<\/span><span class=\"p\">.<\/span><span class=\"n\">MEDIA_ROOT<\/span><span class=\"p\">)<\/span>\r\n\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"n\">MEDIA_URL<\/span> <span class=\"o\">=<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">\/media\/<\/span><span class=\"sh\">\"<\/span>\r\n<span class=\"n\">MEDIA_ROOT<\/span> <span class=\"o\">=<\/span> <span class=\"n\">BASE_DIR<\/span> <span class=\"o\">\/<\/span> <span class=\"sh\">\"<\/span><span class=\"s\">mediafiles<\/span><span class=\"sh\">\"<\/span>\r\n<\/code><\/pre>\n<div>\uff08\u53ef\u80fd\u5fd8\u8bb0\u5907\u5fd8\u5f55..\uff09<br \/>\n\u5982\u679c\u5728\u4e3b\u673a\u4e0a\u521b\u5efa\u4e86\u65b0\u6587\u4ef6\uff0c\u5219\u5e94\u8be5\u4f1a\u51fa\u73b0\u4e0e\u5bb9\u5668\u6743\u9650\u4e0d\u5339\u914d\u7684\u60c5\u51b5\uff0c\u6240\u4ee5\u5728\u8fd9\u4e2a\u9636\u6bb5\u53ef\u80fd\u9700\u8981\u518d\u6b21\u6267\u884c\u4ee5\u4e0b\u547d\u4ee4\uff1a<br \/>\n~\/*$ sudo chown -R $USER:$USER .<\/div>\n<p>\u6211\u8981\u8bd5\u8bd5\u5f00\u8f66\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<p>\u4f7f\u7528\u6d4f\u89c8\u5668\u8bbf\u95ee http:\/\/localhost:8000\/ \u3002\u51c6\u5907\u4e00\u5f20\u56fe\u7247\uff0c\u9009\u62e9\u6587\u4ef6\u5e76\u63d0\u4ea4\u3002\u70b9\u51fb\u663e\u793a\u7684\u94fe\u63a5\uff0c\u5982\u679c\u80fd\u591f\u663e\u793a\u56fe\u7247\u5c31\u8bf4\u660e\u6210\u529f\u3002<\/p>\n<p>\u56e0\u4e3a\u5728\u5f00\u53d1\u6a21\u5f0f\u4e0b\u8fdb\u884c\u4e86\u4e00\u4e9b\u8fdb\u5c55\uff0c\u6240\u4ee5\u9700\u8981\u5728\u6b63\u5f0f\u73af\u5883\u4e2d\u8fdb\u884c\u76f8\u5e94\u7684\u66f4\u6539\u3002<br \/>\n\u9700\u8981\u7ed9docker-compose.prod.yml\u6587\u4ef6\u4e2dweb\u548cnginx\u7684\u5377\u6dfb\u52a0\u8865\u5145\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"na\">version<\/span><span class=\"pi\">:<\/span> <span class=\"s1\">'<\/span><span class=\"s\">3.8'<\/span>\r\n\r\n<span class=\"na\">services<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">web<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">build<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"na\">context<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/app<\/span>\r\n      <span class=\"na\">dockerfile<\/span><span class=\"pi\">:<\/span> <span class=\"s\">Dockerfile.prod<\/span>\r\n    <span class=\"na\">command<\/span><span class=\"pi\">:<\/span> <span class=\"s\">gunicorn config.wsgi:application --bind 0.0.0.0:8000<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">static_volume:\/home\/app\/web\/staticfiles<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">media_volume:\/home\/app\/web\/mediafiles<\/span>\r\n    <span class=\"na\">expose<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"m\">8000<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">db<\/span>\r\n  <span class=\"na\">db<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">image<\/span><span class=\"pi\">:<\/span> <span class=\"s\">postgres:13.0-alpine<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">postgres_data:\/var\/lib\/postgresql\/data\/<\/span>\r\n    <span class=\"na\">env_file<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">.\/.env.prod.db<\/span>\r\n  <span class=\"na\">nginx<\/span><span class=\"pi\">:<\/span>\r\n    <span class=\"na\">build<\/span><span class=\"pi\">:<\/span> <span class=\"s\">.\/nginx<\/span>\r\n    <span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">static_volume:\/home\/app\/web\/staticfiles<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">media_volume:\/home\/app\/web\/mediafiles<\/span>\r\n    <span class=\"na\">ports<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">1337:80<\/span>\r\n    <span class=\"na\">depends_on<\/span><span class=\"pi\">:<\/span>\r\n      <span class=\"pi\">-<\/span> <span class=\"s\">web<\/span>\r\n\r\n<span class=\"na\">volumes<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">postgres_data<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">static_volume<\/span><span class=\"pi\">:<\/span>\r\n  <span class=\"na\">media_volume<\/span><span class=\"pi\">:<\/span>\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code>\r\n<span class=\"c\"># create the appropriate directories<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> HOME=\/home\/app<\/span>\r\n<span class=\"k\">ENV<\/span><span class=\"s\"> APP_HOME=\/home\/app\/web<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">mkdir<\/span> <span class=\"nv\">$APP_HOME<\/span>\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">mkdir<\/span> <span class=\"nv\">$APP_HOME<\/span>\/staticfiles\r\n<span class=\"k\">RUN <\/span><span class=\"nb\">mkdir<\/span> <span class=\"nv\">$APP_HOME<\/span>\/mediafiles\r\n<span class=\"k\">WORKDIR<\/span><span class=\"s\"> $APP_HOME<\/span>\r\n\r\n<\/code><\/pre>\n<pre class=\"post-pre\"><code><span class=\"k\">upstream<\/span> <span class=\"s\">config<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kn\">server<\/span> <span class=\"nf\">web<\/span><span class=\"p\">:<\/span><span class=\"mi\">8000<\/span><span class=\"p\">;<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n<span class=\"k\">server<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kn\">listen<\/span> <span class=\"mi\">80<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"kn\">location<\/span> <span class=\"n\">\/<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kn\">proxy_pass<\/span> <span class=\"s\">http:\/\/config<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_set_header<\/span> <span class=\"s\">X-Forwarded-For<\/span> <span class=\"nv\">$proxy_add_x_forwarded_for<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_set_header<\/span> <span class=\"s\">Host<\/span> <span class=\"nv\">$host<\/span><span class=\"p\">;<\/span>\r\n        <span class=\"kn\">proxy_redirect<\/span> <span class=\"no\">off<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"kn\">location<\/span> <span class=\"n\">\/static\/<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kn\">alias<\/span> <span class=\"n\">\/home\/app\/web\/staticfiles\/<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"kn\">location<\/span> <span class=\"n\">\/media\/<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"kn\">alias<\/span> <span class=\"n\">\/home\/app\/web\/mediafiles\/<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<p>\u5173\u95ed\u5f00\u53d1\u6a21\u5f0f\u5bb9\u5668\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose down <span class=\"nt\">-v<\/span>\r\n<\/code><\/pre>\n<p>\u6784\u5efa\u751f\u4ea7\u5bb9\u5668<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n<\/code><\/pre>\n<h4>\u9519\u8bef\u5904\u7406\uff08\u5982\u679c\u6ca1\u6709\u9519\u8bef\uff0c\u8bf7\u7ee7\u7eed\u524d\u8fdb\uff09<\/h4>\n<pre class=\"post-pre\"><code> <span class=\"o\">=&gt;<\/span> <span class=\"o\">[<\/span>builder 6\/9] COPY <span class=\"nb\">.<\/span> <span class=\"nb\">.<\/span>                                            3.6s\r\n <span class=\"o\">=&gt;<\/span> ERROR <span class=\"o\">[<\/span>builder 7\/9] RUN flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .\/config        3.9s\r\n<span class=\"nt\">------<\/span>\r\n <span class=\"o\">&gt;<\/span> <span class=\"o\">[<\/span>builder 7\/9] RUN flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .\/config:\r\n<span class=\"c\">#18 2.898 .\/config\/urls.py:14:81: W292 no newline at end of file<\/span>\r\n<span class=\"nt\">------<\/span>\r\nexecutor failed running <span class=\"o\">[<\/span>\/bin\/sh <span class=\"nt\">-c<\/span> flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .\/config]: <span class=\"nb\">exit <\/span>code: 1\r\nERROR: Service <span class=\"s1\">'web'<\/span> failed to build : Build failed\r\n<\/code><\/pre>\n<p>\u5f53\u6211\u4eceflake8\u5f97\u5230urls.py\u6587\u4ef6\u7684\u6700\u540e\u4e00\u884c\u6ca1\u6709\u6362\u884c\u7b26\u7684\u8b66\u544a\u65f6\uff0c\u6211\u610f\u8bc6\u5230\u590d\u5236\u7c98\u8d34\u65f6\u9700\u8981\u6ce8\u610f\u3002<br \/>\n\u5373\u4f7f\u6dfb\u52a0\u4e86\u6700\u540e\u4e00\u884c\uff0c\u5982\u679c\u5b58\u5728\u5236\u8868\u7b26\uff0c\u4e5f\u662f\u4e0d\u88ab\u5141\u8bb8\u7684\u3002\u4e3a\u4e86\u907f\u514d\u8fd9\u79cd\u60c5\u51b5\uff0c\u6211\u4eec\u5e94\u8be5\u5c06\u6700\u540e\u4e00\u884c\u7559\u7a7a\u3002<br \/>\n\u91cd\u65b0\u6784\u5efa\u540e\uff0c\u95ee\u9898\u5f97\u4ee5\u89e3\u51b3\u3002<\/p>\n<p>\u63a5\u4e0b\u6765\u6267\u884c\u6570\u636e\u8fc1\u79fb\u548c\u9759\u6001\u6587\u4ef6\u6536\u96c6\u3002<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml <span class=\"nb\">exec <\/span>web python manage.py migrate <span class=\"nt\">--noinput<\/span>\r\n~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml <span class=\"nb\">exec <\/span>web python manage.py collectstatic <span class=\"nt\">--no-input<\/span> <span class=\"nt\">--clear<\/span>\r\n<\/code><\/pre>\n<p>\u6784\u5efa\u901a\u8fc7\u540e\uff0c\u53ef\u4ee5\u8bbf\u95eehttp:\/\/localhost:1337\/\uff0c\u4f46\u5728\u9009\u62e9\u56fe\u50cf\u6587\u4ef6\u540e\uff0c\u70b9\u51fb\u56fe\u50cf\u663e\u793a\u9875\u9762\u7684\u94fe\u63a5\u65f6\u51fa\u73b0\u9519\u8bef\u3002<\/p>\n<pre class=\"post-pre\"><code>Forbidden (403)\r\nCSRF verification failed. Request aborted.\r\n\r\nMore information is available with DEBUG=True.\r\n<\/code><\/pre>\n<p>\u4eceDjango4\uff084.1\uff1f\uff09\u5f00\u59cb\uff0c\u9700\u8981\u5728settings.py\u4e2d\u6dfb\u52a0CSRF_TRUSTED_ORIGINS\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">CSRF_TRUSTED_ORIGINS<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"sh\">'<\/span><span class=\"s\">http:\/\/localhost:1337<\/span><span class=\"sh\">'<\/span><span class=\"p\">,]<\/span>\r\n<\/code><\/pre>\n<p>\u91cd\u65b0\u6784\u5efa\u3002\u3002\uff08\u5982\u4e0a\u6240\u8ff0\uff0c\u5e94\u8bbe\u7f6e\u4e3aDEBUG=1\u4ee5\u4fbf\u8be6\u7ec6\u68c0\u67e5\u9519\u8bef\uff09<\/p>\n<p>\u518d\u6b21flake8<\/p>\n<pre class=\"post-pre\"><code> <span class=\"o\">=&gt;<\/span> <span class=\"o\">[<\/span>builder 6\/9] COPY <span class=\"nb\">.<\/span> <span class=\"nb\">.<\/span>                                                          2.6s\r\n <span class=\"o\">=&gt;<\/span> ERROR <span class=\"o\">[<\/span>builder 7\/9] RUN flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .\/config                      4.3s\r\n<span class=\"nt\">------<\/span>\r\n <span class=\"o\">&gt;<\/span> <span class=\"o\">[<\/span>builder 7\/9] RUN flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .\/config:\r\n<span class=\"c\">#18 3.614 .\/config\/settings.py:134:48: E231 missing whitespace after ','<\/span>\r\n<span class=\"nt\">------<\/span>\r\nexecutor failed running <span class=\"o\">[<\/span>\/bin\/sh <span class=\"nt\">-c<\/span> flake8 <span class=\"nt\">--ignore<\/span><span class=\"o\">=<\/span>E501,F401 .\/config]: <span class=\"nb\">exit <\/span>code: 1\r\nERROR: Service <span class=\"s1\">'web'<\/span> failed to build : Build failed\r\n<\/code><\/pre>\n<p>\u4e0d\u6d88\u5931\u9017\u53f7\u540e\u7684\u7a7a\u683c&#8221;\u306e\u304a\u624b\u5f53&#8221;\u3002\u5f88\u9ebb\u70e6\u554a\u3002\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"n\">CSRF_TRUSTED_ORIGINS<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"sh\">'<\/span><span class=\"s\">http:\/\/localhost:1337<\/span><span class=\"sh\">'<\/span><span class=\"p\">,<\/span> <span class=\"p\">]<\/span>\r\n<\/code><\/pre>\n<p>\u8fd9\u6b21\u4e00\u5b9a\uff01<\/p>\n<pre class=\"post-pre\"><code>~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml up <span class=\"nt\">-d<\/span> <span class=\"nt\">--build<\/span>\r\n~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml <span class=\"nb\">exec <\/span>web python manage.py migrate <span class=\"nt\">--noinput<\/span>\r\n~\/<span class=\"k\">*<\/span><span class=\"nv\">$ <\/span>docker-compose <span class=\"nt\">-f<\/span> docker-compose.prod.yml <span class=\"nb\">exec <\/span>web python manage.py collectstatic <span class=\"nt\">--no-input<\/span> <span class=\"nt\">--clear<\/span>\r\n<\/code><\/pre>\n<p>\u5b8c\u6210\u4e86\u3002<br \/>\n\u5728\u793a\u4f8b\u7f51\u7ad9\u4e2d\uff0c\u5982\u679c\u4fdd\u6301\u73b0\u72b6\uff0c\u4e0a\u4f20\u6587\u4ef6\u5bb9\u91cf\u4e0a\u9650\u4e3a1MB\u3002\u9700\u8981\u4fee\u6539nginx.conf\u3002<\/p>\n<pre class=\"post-pre\"><code>location \/ {\r\n    proxy_pass http:\/\/hello_django;\r\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\r\n    proxy_set_header Host $host;\r\n    proxy_redirect off;\r\n    client_max_body_size 100M;\r\n}\r\n<\/code><\/pre>\n<p>\u8fd9\u5c31\u662f\u5728\u793a\u8303\u7f51\u7ad9\u4e0a\u53ef\u4ee5\u8fdb\u884c\u7684\u5168\u90e8\u5185\u5bb9\u7684\u7ed3\u675f\u3002<\/p>\n<h2>\u7ed3\u8bba<\/h2>\n<p>\u6709\u4e00\u79cd\u4ecb\u7ecd\u4e86SSL\u5316\u7684\u65b9\u6cd5\uff0c\u4f46\u6211\u89c9\u5f97\u81ea\u5df1\u65e0\u6cd5\u5b9e\u73b0\uff0c\u6240\u4ee5\u653e\u5f03\u4e86\u3002\u7ecf\u8fc7\u8c03\u67e5\uff0c\u6211\u51b3\u5b9a\u4f7f\u7528https-portal\u3002<\/p>\n<h1>\u6700\u540e<\/h1>\n<p>\u5728\u6211\u5199\u6587\u7ae0\u7684\u8fc7\u7a0b\u4e2d\uff0c\u6211\u641c\u5230\u4e86\u300a\u8ffd\u6c42\u7406\u89e3Docker\u955c\u50cf\u7684\u6559\u7a0b\u300b\u3002\u592a\u5389\u5bb3\u4e86\uff01\u6211\u8981\u597d\u597d\u5b66\u4e60\u4e00\u4e0b\u3002\u6dfb\u52a0SSL\u52a0\u5bc6\u7684https-portal\u7b49\u5f85\u4e0b\u6b21\u673a\u4f1a\u5427\u3002\u7b49\u6211\u6709\u4e86\u52a8\u529b\u518d\u5199\u3002<\/p>\n<p>\u2193 \u6211\u5199\u4e86\u300aDocker\u5b66\u4e60\u7684\u6536\u5c3e\u9636\u6bb5\uff0cSSL\u652f\u6301\u548c\u90e8\u7f72\u300b\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u9996\u5148 \u8fd9\u662f\u6211\u5728\u4e2a\u4eba\u5f00\u53d1\u7684\u4e24\u5e74\u4e2d\uff0c\u5b66\u4e60Docker\u7684\u6700\u540e\u9636\u6bb5\u65f6\u53c2\u8003\u4e86\u300eDockerizing Django wi [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-50034","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5 - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5b66\u4e60docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5\u3002\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5\" \/>\n<meta property=\"og:description\" content=\"\u9996\u5148 \u8fd9\u662f\u6211\u5728\u4e2a\u4eba\u5f00\u53d1\u7684\u4e24\u5e74\u4e2d\uff0c\u5b66\u4e60Docker\u7684\u6700\u540e\u9636\u6bb5\u65f6\u53c2\u8003\u4e86\u300eDockerizing Django wi [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u5b66\u4e60docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5\u3002\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-10-25T01:35:31+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-04T04:24:27+00:00\" \/>\n<meta name=\"author\" content=\"\u96c5, \u609f\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u96c5, \u609f\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"14 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/\",\"name\":\"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5 - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-10-25T01:35:31+00:00\",\"dateModified\":\"2024-05-04T04:24:27+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/f044a4b7fa4ee2701702942002419ca6\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/f044a4b7fa4ee2701702942002419ca6\",\"name\":\"\u96c5, \u609f\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/e71a913e914f1aad1efc391f92084294bac54bc782acd289638580134cf667a6?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/e71a913e914f1aad1efc391f92084294bac54bc782acd289638580134cf667a6?s=96&d=mm&r=g\",\"caption\":\"\u96c5, \u609f\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/yawu\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5 - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u5b66\u4e60docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5\u3002\/","og_locale":"zh_CN","og_type":"article","og_title":"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5","og_description":"\u9996\u5148 \u8fd9\u662f\u6211\u5728\u4e2a\u4eba\u5f00\u53d1\u7684\u4e24\u5e74\u4e2d\uff0c\u5b66\u4e60Docker\u7684\u6700\u540e\u9636\u6bb5\u65f6\u53c2\u8003\u4e86\u300eDockerizing Django wi [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u5b66\u4e60docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5\u3002\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-10-25T01:35:31+00:00","article_modified_time":"2024-05-04T04:24:27+00:00","author":"\u96c5, \u609f","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u96c5, \u609f","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"14 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/","name":"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5 - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-10-25T01:35:31+00:00","dateModified":"2024-05-04T04:24:27+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/f044a4b7fa4ee2701702942002419ca6"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u5b66\u4e60Docker\u65f6\uff0c\u6211\u91c7\u53d6\u4e86\u8fd9\u6837\u7684\u65b9\u6cd5"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/f044a4b7fa4ee2701702942002419ca6","name":"\u96c5, \u609f","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/e71a913e914f1aad1efc391f92084294bac54bc782acd289638580134cf667a6?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/e71a913e914f1aad1efc391f92084294bac54bc782acd289638580134cf667a6?s=96&d=mm&r=g","caption":"\u96c5, \u609f"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/yawu\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e5%ad%a6%e4%b9%a0docker%e6%97%b6%ef%bc%8c%e6%88%91%e9%87%87%e5%8f%96%e4%ba%86%e8%bf%99%e6%a0%b7%e7%9a%84%e6%96%b9%e6%b3%95%e3%80%82\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50034","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=50034"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50034\/revisions"}],"predecessor-version":[{"id":98301,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/50034\/revisions\/98301"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=50034"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=50034"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=50034"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}