さくらのVPSでDockerでNginx+WordPress+Djangoを動かしてみた!

※ 当サイトではアフィリエイト広告を利用しています。リンクは広告リンクも含みます。

この記事は約13分で読めます。
広告

さくらのVPS さくらのVPS 1G
port80をWordPress、port81をDjangoでアクセスできるようにつくりました。
ドメインを取っていないため、このような形になっています。
完全に実験用なので実用的ではありません。
この方法ではhttps化は多分できないないと思います。
またRestAPIのようなurlを動的に動かすのも多分できないと思います。やろうとしたけど挫折。
単純にhtmlと静的ファイルを動かすことしかやってません。
Nginxをよく理解してないまま試行錯誤で取り合えず動いただけなので、
このまま活用するのは危険です。


この記事の続きです。

この記事書いたときより、私の理解が進んだ、こっち↓のほうがおすすめです!

広告

Nginx(ネットワークコンテナ)

こちら↓でローカルでやった内容をもとにVPSでやってみます。

upstream tk2-110-56065.vs.sakura.ne.jp {
    server site-a1:80;
}
upstream project1 {
    server site-b:8000;
}
server {
    client_max_body_size 32M; 
    listen       80;

    server_name  "";

    location / {
        proxy_pass   http://tk2-110-56065.vs.sakura.ne.jp;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /var/www/htdocs;
    }
}
server {
    listen       81;

    server_name  "";

    location / {
        proxy_pass   http://project1;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /var/www/htdocs;
    }
}

client_max_body_size 32M;はこちらを参照してください

実験した動きからの理解でNginxの公式のドキュメントは読んでおりません。
upstreamに設定した文字列、server_name (今回は””)、proxy_passのurl、ブラウザのアドレスバーのurlの関係は詰められていません。取り合えず動いた形(正確にはちゃんと動いてない)がこういう形でした。
upstreamの後ろのtk2-110-56065.vs.sakura.ne.jp(ホスト名と一緒にしている)とproject1は仮のurlです。

http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node79.html
を見ると「upstreamはサーバグループを定義します。」となっているので
1個だけサーバーをグループ化している状態。
ロードバランサーのときのupstreamの使い方が参考になります。
【入門】nginx とは?設定方法を紹介 | ほげほげテクノロジー (hogetech.info)

実体のサーバーはsite-a1:80site-b:8000になります。
site-a1とsite-bはコンテナ名でnginxのコンテナ(proxy=「docker-compose.ymlのcontainer_name:proxyで設定した名前」)も含め
同じブリッジネットワーク(shared)に入ってないと通信できないと思います。
Docker Compose入門 (3) ~ネットワークの理解を深める~が参考になります。
(1)から全部みたほうがいい。

docker network inspect shared
でみたとき"Name"のコンテナ名に対して通信できるようです。
"Name": "site-a1",
"Name": "site-b",
"Name": "proxy",
具体的にはconf.d/default.conf
でupstreamを使わない場合
server {のlocationでproxy_pass   http://site-a1:80;

実際の動きはホスト名tk2-110-56065.vs.sakura.ne.jpにアクセスしてportを指定していなければ
server{の中のlisten 80;のほうへいき、proxy_pass で設定してあるhttp://tk2-110-56065.vs.sakura.ne.jp(実体はsite-a1:80)へいきます。
ブラウザのアドレスバーのurlはhttp://tk2-110-56065.vs.sakura.ne.jp/になってました。

tk2-110-56065.vs.sakura.ne.jp:81でアクセスすると
とserver{の中のlisten 81;へいき、proxy_pass で設定してあるhttp://project1(実体はsite-b:8000)へいきます。
ブラウザのアドレスバーのurlはhttp://tk2-110-56065.vs.sakura.ne.jp:81/project1/aになってました。
http://project1/aではなかった。
さくらVpsは、もう使ってないので、なぜこうなっているか検証できないですがDjangoの設定も影響してるかも。

このブラウザのアドレスバーの表示が厄介です。
表示だけなら問題ないですが、
この表示は、クライアントに対して次は、ここにアクセスしてくれという意味なので、
ここがproxy_passで設定したアドレスだとクライアントがVPSにたどり着けません。

クラウド VPS byGMO(無料お試し)ではIPアドレスしか使えなかったので
リダイレクトしたとき(WordPressのログインなど)ブラウザのアドレスバーにproxy_passで設定したものが出てしまいVPSにたどり着けなくなってしまいました。
これは301リダイレクトで応答ヘッダのlocationがproxy_passで設定したものになっているからです。
またさくらVpsでWordPressにつながったとき画面の表示が崩れていました。
今、思えば、上と同じようにcssを見に行くアドレスが変わっていて
cssが当たってない状態だったと思います。
またproxy_redirectやproxy_set_headerなど、いろいろいじって応答ヘッダのlocationを
IPアドレスに変換しようとしたけどダメだった。
さらにWordPressが自分のアドレスをコンテナとして認識しているため、
それを応答ヘッダのlocationに書いていると考え
WordPressの.htaccessをいじったらリダイレクトを繰り返してダメだった。

この辺はドメインを取って、サブドメインとコンテナ名を同じにすれば解決するのかな?
今回やったようにportで切り替えるのは現実的ではなさそうです。

server_name (今回は””)は6.1 名前によるバーチャルサーバが参考になります。
ここにサブドメインを書いておけばportが同じ80でも振り分けられると思われます。
WordPressやDjangoのコンテナ名もサブドメインにしてproxy_passにサブドメインを書けば
301の時の応答ヘッダのlocationもサブドメインになると思われます。

version: '3'
services:

  proxy_prod:
    image: nginx:latest
    container_name: 'proxy'
    volumes:
      - ./conf.d/:/etc/nginx/conf.d
      - /etc/letsencrypt:/etc/letsencrypt
    ports:
      - "80:80"
      - "81:81"
    restart: always

networks:
  default:
    name: shared
    external: true

docker-compose.ymlはports: – “80:80” – “81:81″の2つ設定しています。
左側がVPSのポートで右がコンテナのポート、この設定でつながります。(ポートフォワーディングというのかな?マッピング?)
またport81が使えるようにさくらVPSのコントロールパネルのパケットフィルター設定で
「カスタムTCP81送信元IPアドレス:すべて許可する」を追加しました。

目次へ

WordPressとDjango

それぞれのymlファイルだけ載せます。
ローカルでやったものがベースになっているので、こちらを参照してください。

version: '3'

services:
   db:
     image: mysql:5.7
     volumes:
       - db_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: somewordpress
       MYSQL_DATABASE: wordpress
       MYSQL_USER: wordpress
       MYSQL_PASSWORD: wordpress

   site-a1:
     depends_on:
       - db
     image: wordpress:latest
     expose:
       - 80
     restart: always
     environment:
       WORDPRESS_DB_HOST: db:3306
       WORDPRESS_DB_USER: wordpress
       WORDPRESS_DB_PASSWORD: wordpress
       VIRTUAL_HOST: 'site-a1'
volumes:
    db_data:
networks:
  default:
      name: shared
      external: true
version: "3.9"
services:
  site-b:
    build: .
    command: gunicorn composeexample.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - .:/code
      - static_volume:/code/static
    expose:
      - 8000
    environment:
      VIRTUAL_HOST: 'site-b'
networks:
  default:
      name: shared
      external: true
volumes:
  static_volume:
sudo docker-compose up -dでエラー
'services[site-a1.com].depends_on' expected a map, got 'slice'

* 'services[site-b.com].build' expected a map, got 'string'
* 'services[site-b.com].volumes[0]' expected a map, got 'string'
* 'services[site-b.com].volumes[1]' expected a map, got 'string'

参考:https://github.com/wazuh/wazuh-docker/issues/1191
を見るとservicesに.を使うとエラーになるようです。(バージョンによるのかローカルでやっていたときは大丈夫だった。)
services:
       site-a.com→site-a
VIRTUAL_HOST: 'site-a1.com'→VIRTUAL_HOST: 'site-a1'
services:
       site-b.com→site-b
VIRTUAL_HOST: 'site-b.com'→VIRTUAL_HOST: 'site-b'
目次へ

コマンド一覧

さくらのVPS のシリアルコンソール(VNCコンソール)で使ったコマンドです。

コンテナ一覧表示(-aを付けない場合は稼働中のコンテナのみ表示)
sudo docker ps -a
コンテナstop
sudo docker stop コンテナID
コンテナ個別削除
sudo docker rm コンテナID
コンテナ全削除
docker container prune
コンテナ全削除(動いていても削除できる)
docker rm -f `docker ps -a -q`

イメージ一覧
sudo docker images
イメージ個別削除
sudo docker rmi イメージID
イメージ全削除(うまくいかない場合は個別で削除)
docker image prune

ボリューム一覧
sudo docker volume ls
ボリューム削除
sudo docker volume rm ボリューム名

ネットワーク一覧
sudo docker network ls
動いているネットワーク名はbridge、host、noneは多分必要なもので消さないほうがいい。
ネットワーク削除
sudo docker network rm ネットワークID
ネットワーク作成(Error response from daemon: network shared not foundが出たとき実施)
sudo docker network create shared

Build Cacheを削除
docker system prune
イメージ、コンテナ、ネットワークを削除(prune)するショートカットのようですが。
(ボリュームはデフォルトでは削除されない。)
これを実行するとDeleted build cache objects:となってBuild Cacheも削除されました。

コマンド
一覧表示
ls
削除
rm -r 削除するディレクトリ
消していいか聞かれるのでy+Enter
ディレクトリ移動
cd ディレクトリ名
ディレクトリ上へ移動
cd ..

Git
git clone https://アクセストークン@github.com/ユーザーname/レポジトリ名.git

Nginxのコンテナに入ってNginxのコマンド実行
docker exec -it proxy bash 
バージョン確認
nginx -v
configrationの読み込み
nginx -s reload
ただnginxのコンテナに入らなくても
dockerコマンドのdocker restart proxyでconfigrationも読み込まれてるかもしれません。
目次へ

ネットワーク(shared)修正の場合

WordPressもDjangoも基本的にソースを変更したときは同じようにコンテナとソースを削除してgit cloneする手順です。

コンテナ全部停止・削除→ネットワーク(shared)停止削除→ネットワーク(shared)新規作成→sharedフォルダ削除→git clone→cd shared→sudo docker-compose up -d

まとめ

取り合えずDockerを使ってNginx+WordPress+DjangoをVPSで仮に動かすことができました。
実用的にするには、ドメインを取得しないとダメだと思います。
目次へ

イチゲをOFUSEで応援する(御質問でもOKです)Vプリカでのお支払いがおすすめです。
MENTAやってます(ichige)

コメント

タイトルとURLをコピーしました