Tailwind CSSのナビゲーション

### live-server
$ npm install live-server
$ npx live-server public –host=0.0.0.0
// ポートが8080になるので注意

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
	<div id="app">
		<div>
			<header>
				<div>
					<h1>HR</h1>
						<button>
							<svg class="h-6 w-6 fill-current" viewBox="0 0 24 24">
								<path d="M24 6h-24v-4h24v4zm0 4h-24v4h24v-4zm0 8h-24v4h24v-4z"/>
							</svg>
						</button>
				</div>
			</header>
		</div>
	</div>
	<script>
		cost app = new Vue({
			el: "#app",
			data: {

			}
		});
	</script>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Document</title>
	<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
	<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
	<div id="app">
		<div class="bg-gray-500">
			<header class="container mx-auto text-white">
					<div class="flex justify-between items-center fixed w-full left-0 h-16 bg-gray-500 px-2 md:static">
						<h1 class="text-4xl font-semibold md:text-xl">HR</h1>
						<div>
							<button @click="isOpen = !isOpen" class="focus:outline-none">
								<svg class="h-6 w-6 fill-current" viewBox="0 0 24 24">
									<path v-show="!isOpen" d="M24 6h-24v-4h24v4zm0 4h-24v4h24v-4zm0 8h-24v4h24v-4z"/>
									<path v-show="isOpen" d="M24 20.188l-8.315-8.209 8.2-8.282-3.697-3.697-8.212 8.318-8.31-8.203-3.666 3.666 8.321 8.24-8.206 8.313 3.666 3.666 8.237-8.318 8.285 8.203z"/>
								</svg>
							</button>
						</div>
					</div>
					<div :class="isOpen ? 'block' : 'hidden'" class="fixed left-0 w-full mt-16 bg-gray-500 h-full overflow-y-scroll md:overflow-visible md:block md:static md:mt-0">
					<ul class="md:flex md:justify-end md:items-center pb-24 md:pb-0">
						<li class="border-b md:border-none"><a href="#" class="block px-8 py-2 my-4 hover:bg-gray-600 rounded">HRとは</a></li>
						<li class="border-b md:border-none"><a href="#" class="block px-8 py-2 my-4 hover:bg-gray-600 rounded">機能一覧</a></li>
						<li class="border-b md:border-none"><a href="#" class="block px-8 py-2 my-4 hover:bg-gray-600 rounded">料金プラン</a></li>
						<li class="border-b md:border-none"><a href="#" class="block px-8 py-2 my-4 hover:bg-gray-600 rounded">お知らせ</a></li>
						<li class="my-4"><a href="#" class="block px-8 py-2 my-4 bg-orange-500 hover:bg-gray-400 rounded-full">お問い合わせ</a></li>
					</ul>
					</div>
			</header>
		</div>
		<div class="container mx-auto mt-16 md:mt-0">
			<p>コンテンツ領域</p>
		</div>
	</div>
	<script>
		const app = new Vue({
			el: "#app",
			data: {
				isOpen: false,
			}
		});
	</script>
</body>
</html>

なるほど、ハンバーガーは難しいね

Tailwind CSSとは

Bootstrapでは事前に準備されているボタン、メニュー、パンくずリストなどのコンポーネントは準備されておらず、utility classを使って独自のコンポーネントを作成し、デザインを行っていく。
その為、bootstrapよりオリジナリティの高いサイトを構築できる。

<button class="bg-indigo-700 font-semibold text-white py-2 px-4 rounded">ボタン</button>

– 文字の大きさは9種類、色の数はかなりの数のutility classが準備されている。

### cdnを利用する場合

<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">

### npmを使用する場合
$ npm init -y
$ npm install tailwindcss
/css/style.css を作成

@tailwind base;

@tailwind components;

@tailwind utilities;

/public/css フォルダを作成
$ npx tailwind build ./css/style.css -o ./public/css/style.css

package.jsonにbuildコマンドを追加

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "tailwind build css/style.css -o public/css/style.css"
  },

/public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="css/style.css">
</head>
<body>
	<h1>Hello Tailwind</h1>
</body>
</html>

<h1 class="text-4xl text-green-700 text-center font-semibold">Hello Tailwind</h1>

文字の大きさにはtext-xs, txt-sm, text-base … など10の値がある
文字の太さはfont-hairline, font-thin, font-light … など9つの値がある
色はtext-{色}-{色の濃さ}で設定を行う text-green-100, text-green-200 ..など濃さは9個設定できる

<button class="bg-indigo-700 font-semibold text-white py-2 px-4 rounded">ボタン</button>

css/sytle.css

@tailwind base;
@tailwind components;
.btn {
	@apply font-semibold text-white py-2 px-4 rounded;
}
@tailwind utilities;

$ npm run build

<div class="text-center mt-10">
	<button class="bg-indigo-700 font-semibold text-white py-2 px-4 rounded">ボタン</button>
	<button class="bg-red-700 btn hover:bg-red-500">ボタン</button>
</div>

### 設定ファイルの追加
$ npx tailwind init
tailwind.config.js

module.exports = {
  future: {
    // removeDeprecatedGapUtilities: true,
    // purgeLayersByDefault: true,
  },
  purge: [],
  theme: {
    extend: {
      colors: {
        cyan: '#9cdbff',
      }
    },
  },
  variants: {},
  plugins: [],
}

$ npm run build

<button class="bg-cyan btn hover:bg-red-500 focus:outline-none focus:shadow-outline">ボタン</button>

なるほど、良く出来ている

[Laravel8.x] Laravel7.xとの違い

Laravel8系の変更点
– Jetstreamの導入
– モデルファクトリクラスの導入
– マイグレーション圧縮の導入
– ジョブバッチの導入
– レート制限の向上
– キューの向上
– ダイナミックBladeコンポーネントの導入
– Tailwindページネーションビューの導入
– 時間テストヘルパの導入
– artisan serveの向上
– イベントリスナの向上

一つ一つ見ていきましょう。

### Jetstream
ログイン、ユーザー登録、メール認証、二要素認証、セッション管理、Laravel SanctumによるAPIサポート、チーム管理
Tailwind CSSを使用してデザイン(bootstrapから変更)

### モデルのディレクトリ
app/Modelsが作られた
-> 確かにこれは良いですね。

### モデルファクトリクラス
functionの書き方から、クラスを使う書き方に変更

### マイグレーションの圧縮
マイグレーションファイルをphp artisan schema:dumpで一つのファイルに圧縮できる

### ジョブバッチ
ジョブの状況に応じて処理ができる

### リクエストレート制限の向上
何回までアクセスできるかなどを制御できる

### メンテナンスモード
許可IPアドレスからトークンに変更

### ディスパッチクロージャとcatchチェーン
Queue実行時にcatchが使えるようになった

### 動的Bladeコンポーネント
ユーザ情報を元にコンポーネントを変える場合、x-dynamic-component :component=”$componentName”と書く

### イベントリスナの向上
Event::listenメソッドを渡すだけで登録できる

### 時間テストのヘルパ
現時刻を操作できるヘルパ

### Artisan serveの向上
.envの変更が検出されると自動でリロードできる

### Tailwindページネーション
ページネータはTailwind CSSを使用する

### ルートの名前空間の工場

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar create-project –prefer-dist laravel/laravel testApp
$ php artisan –version
Laravel Framework 8.12.3

認証に関してはlivewire(js)とinertia(SinglePageApplication)が用意さてている

composer require laravel/jetstream

// Livewireスタックを使用するJetstreamをインストールする
php artisan jetstream:install livewire

// Inertiaスタックを使用するJetstreamをインストールする
php artisan jetstream:install inertia

Tailwindを復習してからlivewireで確認ってところだな。

jQueryとCSSでタブメニューを切り替える

yahooトップのタブのように、クリックしてもページ遷移しないタブを作りたい。

### jQueryとCSSで作る場合
index.html
– jqueryの制御は後から書きます。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" href="styles.css" type="text/css">
	<script
  src="https://code.jquery.com/jquery-3.5.1.js"
  integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
  crossorigin="anonymous"></script>
</head>
<body>
	<div class="tab">
		<ul class="tab-menu">
			<li class="tab-item active">タブ1</li>
			<li class="tab-item">タブ2</li>
			<li class="tab-item">タブ3</li>
		</ul>

		<div class="tab-box">
			<div class="tab-content show">コンテンツ1</div>
			<div class="tab-content">コンテンツ2</div>
			<div class="tab-content">コンテンツ3</div>
		</div>
	</div>
	<script>
	</script>
</body>
</html>

styles.css

* {
	box-sizing: border-box;
}
ul, li {
	padding: 0;
	margin: 0;
}
li {
	list-style: none;
}
.tab {
	width: 500px;
	max-width: 100%;
	margin: auto;
}
.tab-menu{
	display: flex;
}
.tab-item {
	text-align: center;
	padding: 10px 0;
	cursor: pointer;

	flex-grow: 1;

	border-top: 1px solid skyblue;
	border-left: 1px solid skyblue;
	border-right: 1px solid skyblue;
}
.tab-item:not(:first-child){
	border-left: none;
}
.tab-item.active {
	background: red;
	color: white;
}
.tab-box {
	height:200px;
	display: flex;
	justify-content: center;
	align-items: center;
	border: 1px solid skyblue;
}
.tab-content {
	display: none;
	font-size: 40px;
}
.tab-content.show {
	display: block;
}

jquery
– タブclick時にactiveとshowのclassをremoveして、clickされたタブのindexと同じindexにcontentのclassにshowを追加する
– タブとコンテンツの数、順番を一致させる必要がある

<script>
		$(function(){
			$('.tab-item').click(function(){
				$('.active').removeClass('active');
				$(this).addClass('active');
				$('.show').removeClass('show');

				const index = $(this).index();

				$('.tab-content').eq(index).addClass('show');
			})
		})
	</script>

### CSSのみで作る場合
index.html

<div class="tab">
		<input id="menu1" class="tab-input" name="menu" type="radio" checked="checked">
		<label for="menu1" class="tab-item">タブ1</label>
		<div class="tab-content">コンテンツ1</div>

		<input id="menu2" class="tab-input" name="menu" type="radio">
		<label for="menu2" class="tab-item">タブ2</label>
		<div class="tab-content">コンテンツ2</div>

		<input id="menu3" class="tab-input" name="menu" type="radio">
		<label for="menu3" class="tab-item">タブ3</label>
		<div class="tab-content">コンテンツ3</div>
	</div>

* {
	box-sizing: border-box;
}
input[type="radio"]{
	display:none;
}
.tab {
	width: 500px;
	max-width: 100%;
	margin: auto;
	display: flex;
	flex-flow: wrap;
}
.tab-item {
	display: block;
	flex-grow: 1;
	text-align: center;
	padding: 10px 0;
	cursor: pointer;
	order: -1;

	border-top: 1px solid skyblue;
	border-left: 1px solid skyblue;
	border-right: 1px solid skyblue;
}
.tab-item:not(:first-of-type){
	border-left: none;
}
.tab-input:checked + .tab-item {
	background: red;
	color: white;
}
.tab-content {
	width: 100%;
	height: 200px;
	display: none;
	justify-content: center;
	align-items:center;
	font-size: 40px;
	border: 1px solid skyblue;
}

.tab-input:checked + .tab-item + .tab-content {
	display: flex;
}

input formとradioボタンで切り替えるってなんか違和感あるけど、うまく表示されますね。
思ったより簡単でワロタ。

[Laravel8.x] Amazon Linux2のVagrant/EC2開発環境構築

Laravel8.xをAmazon Linux 2 AMI(HVM), SSD Volume Type 64-bit(x86)で動かすことを想定して、Vagrant or EC2の開発環境構築をやっていきたい。
8系はPHP >= 7.3なので、7.4を入れるのがポイント。他は大体いつもの通りです。
EC2の場合はvagrant initは飛ばしてsshログインから始めてください。

### 1.vagrant initからsshログインまで
$ mkdir amazonlinux2
$ cd amazonlinux2
$ vagrant init gbailey/amzn2
$ vi vagrantfile
// 35行目ポートフォワーディング解除

config.vm.network "private_network", ip: "192.168.33.10"

$ vagrant up
$ vagrant ssh-config –host 192.168.33.10
$ vagrant ssh
// sshログイン後
$ cat /etc/*release
$ sudo yum update

### 2.Gitインストール(2.29.2)
$ sudo yum -y install gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
// ダウンロード対象を確認(https://mirrors.edge.kernel.org/pub/software/scm/git/)
// 11月3日時点で最新のgit2.29.2を入れる
$ cd /usr/local/src/
$ sudo wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.29.2.tar.gz
$ sudo tar xzvf git-2.29.2.tar.gz
$ sudo rm -rf git-2.29.2.tar.gz
$ cd git-2.29.2
$ sudo make prefix=/usr/local all
$ sudo make prefix=/usr/local install
$ git –version
git version 2.29.2

### 3.Node.jsインストール(v11.15.0)
// 11系を入れる
$ curl –silent –location https://rpm.nodesource.com/setup_11.x | sudo bash –
$ yum install -y gcc-c++ make
$ sudo yum install -y nodejs
$ node –version
$ npm –version

### 4.Apacheインストール(Apache/2.4.46)
$ sudo yum install httpd
$ sudo systemctl start httpd
$ sudo systemctl status httpd
$ sudo systemctl enable httpd
$ sudo systemctl is-enabled httpd
$ httpd -v

### 5.PHP7.4インストール ※laravel8.xはPHP >= 7.3
$ amazon-linux-extras
$ amazon-linux-extras info php7.4
$ sudo amazon-linux-extras install php7.4
$ yum list php* | grep amzn2extra-php7.4
$ sudo yum install php-cli php-pdo php-fpm php-json php-mysqlnd php-mbstring php-xml
$ php -v
PHP 7.4.11 (cli) (built: Oct 21 2020 19:12:26) ( NTS )
おっしゃーーーーーーーーーーーー  ここで一息入れてジンジャーエールを飲みます

### 6.MySQL(8.0.22)
$ sudo yum install https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
$ sudo yum install –enablerepo=mysql80-community mysql-community-server
$ sudo systemctl start mysqld
// パスワード変更
$ sudo cat /var/log/mysqld.log | grep “temporary password”
$ mysql -u root -p
mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED BY ‘${temporary password}’;
mysql> SET GLOBAL validate_password.length=6;
mysql> SET GLOBAL validate_password.policy=LOW;
mysql> ALTER USER ‘root’@’localhost’ IDENTIFIED WITH mysql_native_password BY ‘${new password}’;
$ sudo systemctl enable mysqld
$ mysql -u root -p

### 7.Ansible(2.9.13)
$ sudo amazon-linux-extras install ansible2
$ ansible –version

### 8.Ruby(2.7.2)
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo ‘export PATH=”$HOME/.rbenv/bin:$PATH”‘ >> ~/.bash_profile
$ echo ‘eval “$(rbenv init -)”‘ >> ~/.bash_profile
$ source ~/.bash_profile
// rbenvは時間がかかるので注意 痺れを切らさず待ちます
$ rbenv install 2.7.2
$ rbenv rehash
$ sudo yum install rubygems
$ gem update –system 2.7.2

### 9.AmazonLinux2 timezone変更
$ date
$ cat /etc/localtime
$ sudo vi /etc/sysconfig/clock

ZONE="Asia/Tokyo" 
UTC=false

$ sudo cp /etc/sysconfig/clock /etc/sysconfig/clock.org
$ strings /etc/localtime
$ date

お疲れ様でしたあああああああああああああああああああああ。githubに貼り付けときます。
今までPHP7.3で開発してたので、取り敢えず7.4が入ったあたりで満足した。
さて、いよいよcomposerでlaravel8.xをinstallしていきましょう。

[Laravel8.x] PHPのバージョン PHP >= 7.3

9月8日に8系がリリースされています。3月3日に7系がリリースされたばかりですから、非常に早いペースですね。
まず公式ドキュメントを確認してみましょう。

https://readouble.com/laravel/8.x/ja/releases.html

– Jetstreamの導入
– モデルファクトリクラスの導入
– マイグレーション圧縮の導入
– ジョブバッチの導入
– レート制限の向上
– キューの向上
– ダイナミックBladeコンポーネントの導入
– Tailwindページネーションビューの導入
– 時間テストへるぱの導入
– artisan serveの工場
– イベントリスナの向上

結構沢山ありますね。重要そうなJetstreamは必ず確認するとして、最初にPHPのバージョンから確認します。
まず、8系では PHP >= 7.3 となっています。
amazon linux 2でどこまで行けるか確認してみたいと思います。

$ cat /etc/*release
NAME=”Amazon Linux”
VERSION=”2″
ID=”amzn”
ID_LIKE=”centos rhel fedora”
VERSION_ID=”2″
PRETTY_NAME=”Amazon Linux 2″
ANSI_COLOR=”0;33″
CPE_NAME=”cpe:2.3:o:amazon:amazon_linux:2″
HOME_URL=”https://amazonlinux.com/”
Amazon Linux release 2 (Karoo)

$ sudo yum list | grep php
php-cli.x86_64 7.3.23-1.amzn2 @amzn2extra-ph7.3
// 省略

$ amazon-linux-extras info php7.4
php7.4 recommends php-cli # yum install php-cli
php7.4 recommends php-pdo # yum install php-pdo
php7.4 recommends php-fpm # yum install php-fpm
php7.4 recommends php-json # yum install php-json
php7.4 recommends php-mysqlnd # yum install php-mysqlnd

php7.4インストールできそうですね。環境を最新版に作り直さないとダメですね。

[Django3.0] staticの静的ファイルをS3に画像をアップロード

dev環境だとstaticに画像を置けば良かったが、prd環境だと画像保存がcollectstaticで上手くいかないのでS3を使いたい。まずはテストする。

$ django-admin startproject statictest
$ cd statictest
$ python3 manage.py startapp testApp

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'testApp',
]

statictest/urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('testApp.urls'))
]

testApp/urls.py

from django.urls import path
from django.conf import settings
from . import views

urlpatterns = [
	path('', views.index, name='index'),
]

testApp/templates/testApp/index.html

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<link rel="stylesheet" href="{% static 'testApp/css/base.css' %}">
</head>
<body>
	<header>
	<h1>test1</h1>
	</header>
	<div>
		test page!
	</div>
</body>
</html>

testApp/static/testApp/css/base.css

h1 {
	color: red;
}

views.py

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
	return render(request, 'testApp/index.html')

$ python3 manage.py runserver 192.168.33.10:8000

これをsettings.pyのDEBUG=Falseにすると、static fileを読み込まなくなる。

DEBUG = False

### AWS S3
– S3fullAccessのユーザ作成
accesskey, secretkey, regionを取得
– testapp-djangoのbucket作成

$ pip3 install boto3
$ pip3 install django-storages

settings.py

INSTALLED_APPS = [
    //
    'testApp',
    'storages' # 追加
]

# STATIC_URL = '/static/'

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'testApp/static')]
AWS_ACCESS_KEY_ID = 'AKIAXXXXXXXXXXXXXX'
AWS_SECRET_ACCESS_KEY = 'YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY'
AWS_STORAGE_BUCKET_NAME = 'static-test-reiwa'
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'
AWS_DEFAULT_ACL = None
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

S3で対象のbucketをpublicにして、フォルダをmake publicに変更する

– STATICFILES_DIRS = [os.path.join(BASE_DIR, ‘static’)] だとファイルがないとエラーになるので注意。

なるほどー

[aws ec2] Ubuntu20.04 x Apache2 x Django3.0 x MySQL8系 環境構築

結論から言うと、ec2 x Djangoでapache2 or Nginxを使う場合、仮想環境を作らないと、Djangoのパスが通らずに、「ModuleNotFoundError: No module named ‘django’」とエラーになる。開発環境では、manage.py runserverで確認すれば良かったが、ec2にデプロイしてapache2もしくはNginxを通す場合は、仮想環境の構築が必須。
ec2でapache2もしくはNginxを構築する前に、uWSGIの基礎を学んでから構築した方が、理解が深まるし、トラブルシューティングしやすくなる。
それを省略したので、結局2日かかった orz…

以下が構築手順。Ubuntu20.04のインスタンスが出来ている状態から始める。

### 1.インスタンスログイン
$ ssh ubuntu@${public ip} -i ~/.ssh/*.pem
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install python3-pip

### 2.MySQL8系インストールとdjango用のdb作成
$ sudo apt install mysql-client-core-8.0
$ sudo apt-get update
$ sudo apt install mysql-server
$ sudo service mysql start
$ sudo mysql_secure_installation
$ sudo mysql -u root -p
mysql>set global validate_password.length=6;
mysql>set global validate_password.policy=LOW;
mysql>CREATE USER ‘admin’@’%’ IDENTIFIED BY ‘hogehoge’;
mysql>GRANT ALL PRIVILEGES ON *.* TO ‘admin’@’%’ WITH GRANT OPTION;
mysql>FLUSH PRIVILEGES;
mysql>create database hoge;

### 3.apacheインストール
$ sudo apt update
$ sudo apt install apache2
$ sudo ufw app list
$ sudo ufw allow ‘Apache Full’
$ sudo ufw status
$ sudo systemctl status apache2

### 4.git clone
// 所有権
$ sudo chown ubuntu /home
$ git clone https://github.com/hoge/hoge.git
$ cd hoge

#### 5.django商用設定
settings.py

DEBUG = False
ALLOWED_HOSTS = ['*']  #もしくはEC2のIP
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
migration

// migration
$ python3 manage.py makemigrations hoges
$ python3 manage.py migrate

### 6. 仮想環境構築(!!重要!!)
$ sudo apt install -y python3-wheel python3-venv python3-dev
$ python3 -m venv env
$ source env/bin/activate
$ pip install wheel
// 各種ライブラリインストール 省略
$ apt-get install apache2-dev
$ sudo pip3 install mod_wsgi
$ mod_wsgi-express module-config
LoadModule wsgi_module “/usr/local/lib/python3.8/dist-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so”
WSGIPythonHome “/usr”
$ python3 manage.py collectstatic
$ deactivate

### 7. Apache設定
$ sudo vi /etc/apache2/sites-available/django.conf

LoadModule wsgi_module /usr/local/lib/python3.8/dist-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so

WSGIPythonHome /usr
WSGIScriptAlias / /home/ubuntu/hoge/hoge/wsgi.py
WSGIPythonPath /home/ubuntu/hoge:/home/ubuntu/hoge/env/lib/python3.8/site-packages

<Directory /home/ubuntu/hoge/hoge>
  <Files wsgi.py>
    Require all granted
  </Files>
</Directory>

Alias /static/ /home/ubuntu/hoge/hoge/
<Directory /home/ubuntu/hoge/static>
  Require all granted
</Directory>

$ sudo a2dissite 000-default
$ sudo a2ensite django
$ sudo systemctl restart apache2
$ sudo systemctl enable apache2

### 8.挙動確認
EC2のpublic IPを叩く

### 9.AMI作成
– インスタンスのバックアップ

お疲れ様でした。

ちなみにこれ、仮想環境構築をすっ飛ばしてインスタンス作成を5〜6回ぐらいやり直してapacheのエラーログ見て悶絶してた。まあ、ここを乗り切ればハードルは一気に下がりますね。

[uWSGI] DjangoをUbuntu+Nginx+uWSGIの構成で動かしたい

### uWSGIとは?
-WSGIは仕様で、uWSGIは既存のWebサーバに機能を追加
-WebサーバにNginx, WSGIコンテナにuWSGI(Nginxとは別プロセス)
-Apache2, Nginx, cherokee, lighttpdに対応
-gunicornというWSGIも有名
-Apacheは同時接続数が極端に多くなると対応できないが、Nginxはレスポンスが早い

### Django構築
$ django-admin startproject testSite
$ python3 manage.py startapp testapp

settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'testapp',
]
ALLOWED_HOSTS = ['*']

views.py

from django.http import HttpResponse
# Create your views here.

def hello(request):
	return HttpResponse("hello, Nginx!")

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.hello, name='hello'),
]
urlpatterns = [
    path('admin/', admin.site.urls),
    path('testapp/', include('testapp.urls')),
]

### UbuntuにNginx
$ sudo apt update
$ apt show nginx
Package: nginx
Version: 1.18.0-0ubuntu1
$ sudo apt install nginx
$ nginx -v

### djangoでuWSGI
$ python3 manage.py runserver 192.168.33.10:8000

$ uwsgi –http :8000 –module testSite.wsgi

testApp/uwsgi_params

uwsgi_param  QUERY_STRING       $query_string;
uwsgi_param  REQUEST_METHOD     $request_method;
uwsgi_param  CONTENT_TYPE       $content_type;
uwsgi_param  CONTENT_LENGTH     $content_length;
 
uwsgi_param  REQUEST_URI        $request_uri;
uwsgi_param  PATH_INFO          $document_uri;
uwsgi_param  DOCUMENT_ROOT      $document_root;
uwsgi_param  SERVER_PROTOCOL    $server_protocol;
uwsgi_param  REQUEST_SCHEME     $scheme;
uwsgi_param  HTTPS              $https if_not_empty;
 
uwsgi_param  REMOTE_ADDR        $remote_addr;
uwsgi_param  REMOTE_PORT        $remote_port;
uwsgi_param  SERVER_PORT        $server_port;
uwsgi_param  SERVER_NAME        $server_name;

testApp/testSite_nginx.conf

upstream django {
	server 192.168.33.10:8001;
}

server {
	listen 8000;
	server_name 192.168.33.10;
	charset utf-8;

	location /static {
		alias /home/vagrant/other/testSite/static;
	}

	location / {
		uwsgi_pass django;
		include /home/vagrant/other/testSite/testSite/uwsgi_params;
	}
}

$ sudo ln -s /home/vagrant/other/testSite/testSite/testSite_nginx.conf /etc/nginx/sites-enabled/

setting.py

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

$ python3 manage.py collectstatic

$ sudo nginx
failed (Result: exit-code)

$ sudo lsof -i:80
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
nginx 75758 root 6u IPv4 87712 0t0 TCP *:http (LISTEN)
nginx 75758 root 7u IPv6 87713 0t0 TCP *:http (LISTEN)
nginx 75759 www-data 6u IPv4 87712 0t0 TCP *:http (LISTEN)
nginx 75759 www-data 7u IPv6 87713 0t0 TCP *:http (LISTEN)
nginx 75760 www-data 6u IPv4 87712 0t0 TCP *:http (LISTEN)
nginx 75760 www-data 7u IPv6 87713 0t0 TCP *:http (LISTEN)

$ uwsgi –socket :8001 –module testSite.wsgi buffer-size=32768

うーん、ちょっとよくわからんな。。