20200322のMacに関する記事は9件です。

Docker Compose でWebアプリケーションを開発する環境(NGINX + uWSGI + PostgreSQL)を構築する。

はじめに

 Docker Composeを使って、NGINX、uWSGI、PostgreSQLが動作するDocker コンテナを構築し、
 Django(Python)で開発したWebアプリケーションをブラウザで動作確認するまでの手順を記載します。
 ※ 本投稿は、Mac OSを前提としています。
  macOS Catalina 10.15.3で作業しています。

No. 項目 説明
1 Docker Compose 複数のDocker コンテナを一元管理するツールです。
本投稿では、NGINX、uWSGI、PostgreSQLが動作するDocker コンテナを
構築します。
2 NGINX Webサーバです。
本投稿では、ここに静的ファイルを配置します。
3 uWSGI アプリケーションサーバです。
Pythonで作成したWebアプリケーションを配置します。
4 PostgreSQL DBサーバです。
Webアプリケーションで利用するデータを保持します。
5 Django PythonのWebフレームワークです。

前提条件

 Docker for Macをダウンロードする際、Dockerの公式サイトにログインする必要があります。
 Dockerの公式サイトにログインするためのユーザを作成して下さい。

1. Docker for Mac

 最初にDocker for Macのインストールを行います。
 Docker Composeは、Docker for Macに含まれています。

1-1. ダウンロード

 以下のサイトからダウンロードします。
 https://docs.docker.com/docker-for-mac/install/

 (1) 「Download from Docker Hub」ボタンを押下します。
  FireShot Capture 192 - Install Docker Desktop on _ - https___docs.docker.com_docker-for-mac_install_.png

 (2) 「Download Docker Desktop for Mac」ボタンを押下します。
  Docker.dmg がダウンロードされます。
  FireShot Capture 193 - Docker Hub - https___hub.docker.com__overlay=onboarding.png

1-2. インストール

 (1) Docker.dmgの実行
  ダウンロードした Docker.dmg を実行して下さい。

 (2) Applicationsに移動
  DockerをApplicationsに移動させます。
  スクリーンショット 2020-02-09 18.57.37.png

 (3) Dockerの実行
  アプリケーションからDockerを実行して下さい。

1-3. 確認

 (1) ターミナルを開き、"docker --version"を実行します。
  インストールしたDockerのバージョンを確認します。

$ docker --version
Docker version 19.03.5, build 633a0ea

 (2) 次に、"docker-compose --version"を実行します。
  Docker Composeのバージョンを確認します。

$ docker-compose --version
docker-compose version 1.25.4, build 8d51620a

2. Docker コンテナの構築

 NGINX、uWSGI、PostgreSQLが動作するDocker コンテナを構築します。

2-1. 作業ディレクトリの作成

 任意の作業ディレクトリを作成して下さい。
 本投稿では、"django"を作成します。

$ mkdir django

2-2. ファイル/ディレクトリの準備

 Docker Composeの実行に必要なファイル、Webアプリケーションのソースコードを
 配置するディレクトリなどを準備します。

 (1) 作業ディレクトリへの移動

$ cd django

 (2) requirements.txt の作成

$ touch requirements.txt

 (3) Dockerfile の作成

$ touch Dockerfile

 (4) docker-compose.yml の作成

$ touch docker-compose.yml

 (5) nginx ディレクトリの作成

$ mkdir nginx

 (6) nginx/conf ディレクトリの作成

$ mkdir nginx/conf

 (7) nginx/conf/mainproject_nginx.conf の作成

$ touch nginx/conf/mainproject_nginx.conf

 (8) nginx/uwsgi_params の作成

$ touch nginx/uwsgi_params

 (9) src ディレクトリの作成

$ mkdir src

 (10) src/static ディレクトリの作成

$ mkdir src/static

 (11) dbdata ディレクトリの作成

$ mkdir dbdata

 [ファイル/ディレクトリの説明]

No. 名称 説明
1 requirements.txt 利用するPythonのパッケージ(ライブラリ)を指定するファイル
2 Dockerfile Docker コンテナの構成情報を記述するためのファイル
3 docker-compose.yml アプリケーションを動かすための処理を記述するファイル
4 nginx NGINXのルートディレクトリ
5 nginx/conf NGINXの設定ファイルを配置するディレクトリ
6 nginx/conf/mainproject_nginx.conf NGINXの設定を記述するためのファイル
※ ファイル名は任意です、拡張子は".conf"にして下さい。
7 nginx/uwsgi_params NGINXとuWSGIを連携させるためのファイル
8 src Webアプリケーションを配置するディレクトリ
9 src/static css、JavaScript、画像などの静的ファイルを配置するディレクトリ
10 dbdata PostgreSQLのデータファイルを保持するディレクトリ

 [ここまでのファイル構成]

$ tree .
.
├── Dockerfile
├── dbdata
├── docker-compose.yml
├── nginx
│   ├── conf
│   │   └── mainproject_nginx.conf
│   └── uwsgi_params
├── requirements.txt
└── src
    └── static

5 directories, 5 files

2-3. requirements.txtの設定

 requirements.txtを開き、以下の内容を記述して保存します。
 requirements.txtは、次に説明するDockerfileの中で利用しています。
 ("RUN pip install -r requirements.txt"の箇所)

Django
django-bootstrap4
uwsgi
psycopg2

 [説明]
  ① Django
   PythonのWebフレームワークのDjangoをインストールします。
  ② django-bootstrap4
   DjangoでBootstrap4を利用するためのパッケージをインストールします。
   ※ Bootstrap4を利用しない場合、インストールする必要はありません。
    最後にDjangoで作成したページにBootstrap4を適用する方法を参考に紹介します。
  ③ uwsgi
   アプリケーションサーバをインストールします。
  ④ psycopg2
   PythonからPostgreSQLに接続するためのドライバをインストールします。

2-4. Dockerfileの設定

 Dockerfileを開き、以下の内容を記述して保存します。
 Dockerfileは、次に説明するdocker-compose.ymlの中で利用しています。
 ("build: ."の箇所)

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

 [説明]
  ① FROM python:3.7
   Docker のベースイメージに"python3.7"を指定
   "Docker Hub"のイメージから作成します。
  ② ENV PYTHONUNBUFFERED 1
   Python の標準出力、標準エラー出力をバッファに溜め込まない設定となります。
   バッファが有効になっていると、標準出力の途中経過が表示されず、
   全てのタスクが終わった後に纒めて表示されます。
  ③ RUN mkdir /code
   コンテナ上にcodeディレクトリを作成します。
  ④ WORKDIR /code
   コンテナの作業ディレクトリにcodeディレクトリを指定します。
  ⑤ COPY requirements.txt /code/
   ローカルマシンのrequirements.txtをコンテナのcodeディレクトリに追加します。
  ⑥ RUN pip install --upgrade pip
   コンテナ上のpipを最新のバージョンにします。
  ⑦ RUN pip install -r requirements.txt
   requirements.txtに記載しているPythonのパッケージ(ライブラリ)を
   コンテナ上インストールします。
  ⑧ ローカルマシンのカレントディレクトリの内容をコンテナのcodeディレクトリに追加します。
 

2-5. docker-compose.ymlの設定

 docker-compose.ymlを開き、以下の内容を記述して保存します。

version: '3.7'

volumes:
  pgdata:
    driver_opts:
      type: none
      device: $PWD/dbdata
      o: bind
services:
  nginx:
    image: nginx
    container_name: container.nginx
    ports:
      - "8000:8000"
    volumes:
      - ./nginx/conf:/etc/nginx/conf.d
      - ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
      - ./src/static:/static
      - ./nginx/log:/var/log/nginx
    depends_on:
      - web
  web:
    build: .
    container_name: container.uwsgi
    command: uwsgi --ini /code/mainproject/django.ini
    volumes:
      - ./src:/code
    expose:
      - "8001"
    depends_on:
      - db
  db:
    image: postgres
    restart: always
    container_name: container.postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_DB: "postgresdb"
      POSTGRES_USER: "admin"
      POSTGRES_PASSWORD: "test"
      POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C"
    volumes:
      - pgdata:/var/lib/postgresql/data
    hostname: postgres

 [説明]
  ① version: '3.7'
   docker-composeで使用するバージョンとなります。
   バージョンによって、docker-compose.ymlの書き方が異なります。
   ※ Docker 本体のバージョンとの関連は「Compose file version 3 reference」を参照して下さい。
  ② volumes:
   トップレベルのvolumesは、名前付きvolumeとなります。
   ここでは、"pgdata"という名前付きvolumeを指定しています。
   "device: $PWD/dbdata"は、ローカルマシンの作業ディレクトリ配下のdbdataディレクトリを表します。
  ③ services:
   構築するコンテナを記述します。
   ここでは、"nginx"、"web"、"db"を記述しています。
   この名前は任意で指定が可能です。
   例えば、"db"は、"database"などでも問題ありません。
  ③-1 nginx:
  ③-1-1 image: nginx
   NGINXが動作するコンテナは、"Docker Hub"のイメージから作成します。
  ③-1-2 container_name: container.nginx
   "container.nginx"という任意のコンテナ名を付けます。
  ③-1-3 ports:
   NGINXのポート番号に8000ポートを指定します。
  ③-1-4 volumes:
   ローカルマシンの作業ディレクトリ配下の各ファイル/ディレクトリと
   NGINXのコンテナのファイル/ディレクトリのマウントを設定します。
   a) ./nginx/conf:/etc/nginx/conf.d
    これにより、"nginx/conf/mainproject_nginx.conf"が"/etc/nginx/conf.d"にマウントされます。
    "/etc/nginx/conf.d"に配置した拡張子".conf"のファイルは、
    親の設定ファイルにあたる"/etc/nginx/nginx.conf"によって読み込まれます。
    * "/etc/nginx/nginx.conf"は、nginxのコンテナにデフォルトで存在します。
   b) ./nginx/uwsgi_params:/etc/nginx/uwsgi_params
    "/etc/nginx/uwsgi_params"は、次に説明する"nginx/conf/mainproject_nginx.conf"の中で利用しています。
    ("include /etc/nginx/uwsgi_params;"の箇所)
   c) ./src/static:/static
    静的ファイルを配置するディレクトリをマウントします。
    cssなどをNGINXから配信するための設定となります。
   d) ./nginx/log:/var/log/nginx
    ログファイルを配置するディレクトリをマウントします。
    これにより、ローカル上でログを確認できるようになります。
  ③-1-5 depends_on:
   "web"、つまりuWSGIのコンテナが起動された後に、NGINXのコンテナを起動するという指定です。
  ③-2 web:
  ③-2-1 build: .
   uWSGIが動作するコンテナは、Dockerfileに記述したコンテナの構成情報で作成します。
   "build: ."は、ビルドに使用するDockerfileのパスを表します。
   つまり、このコンテナは、Dockerfileに記載したコンテナの構成情報で作成します。
  ③-2-2 container_name: container.uwsgi
   "container.uwsgi"という任意のコンテナ名を付けます。
  ③-2-3 command: uwsgi --ini /code/mainproject/django.ini
   コンテナが起動した後に、uWSGIを設定ファイル"/code/mainproject/django.ini"の
   内容に従って、起動させるということを表します。
  ③-2-4 volumes:
   ローカルマシンの作業ディレクトリ配下の各ディレクトリと
   uWSGIのコンテナのディレクトリのマウントを設定します。
  ③-2-5 expose:
   uWSGIのポート番号に8001ポートを指定します。
  ③-2-6 depends_on:
   "db"、つまりPostgreSQLのコンテナが起動された後に、uWSGIのコンテナを起動するという指定です。
  ③-3 db:
  ③-3-1 image: postgres
   PostgreSQLが動作するコンテナは、"Docker Hub"のイメージから作成します。
  ③-3-2 restart: always
   ホストOSを起動したタイミングでコンテナを自動起動するという指定です。
  ③-3-3 container_name: container.postgres
   "container.postgres"という任意のコンテナ名を付けます。
  ③-3-4 ports:
   PostgreSQLのポート番号に5432ポートを指定します。
  ③-3-5 environment:
   a) POSTGRES_DB: "postgresdb"
    コンテナ起動時に作成するデフォルトのDBの名称を指定します。
    指定しない場合、POSTGRES_USERの値が使われます。
   b) POSTGRES_USER: "admin"
    スーパユーザの名称を指定します。
    指定しない場合、"postgres"が使われます。
   c) POSTGRES_PASSWORD: "test"
    スーパユーザのパスワードを指定します。
    指定しない場合、POSTGRES_USERの値が使われます。
   d) POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --locale=C"
    DBを作成するコマンド(postgres initdb)を実行する際に渡す引数を指定します。
    エンコーディングに"UTF-8"、ロケールに"C"を指定しています。
   ※ environmentの詳細は、「Supported tags and respective Dockerfile links 」を参照して下さい。
  ③-3-6 volumes:
   名前付きvolumeの"pgdata"と
   PostgreSQLコンテナの"/var/lib/postgresql/data"のマウントを設定します。
   この設定により、DBのデータが永続化されます。
   (コンテナを削除してもデータがローカルマシン上に残ります。)
  ③-3-7 hostname:
   "postgres"という任意のホスト名を付けます。

2-6. nginx/conf/mainproject_nginx.confの設定

 nginx/conf/mainproject_nginx.confを開き、以下の内容を記述して保存します。

# the upstream component nginx needs to connect to
upstream django {
    ip_hash;
    server web:8001;
}

# configuration of the server
server {
    # the port your site will be served on
    listen      8000;
    # the domain name it will serve for
    server_name 127.0.0.1; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 75M;   # adjust to taste

    location /static {    
        alias /static; 
    }

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
    }
}

 [説明]
  ① upstream django
   細かい設定方法は割愛しますが、"server web:8001;"については、
   docker-compose.ymlに記載したweb(ポート番号は、8001)を指しています。
   つまり、uWSGIを指しています。
  ② server
   こちらも細かい設定方法は割愛しますが、"location / {"については、
   NGINXのルートにアクセスがあった場合、①で説明したuWSGIに処理を渡すという設定になります。
   また、③-1-4で説明した/etc/nginx/uwsgi_paramsの設定ファイルに基づいて連携しています。
   "location /static {"については、
   静的ファイルについては、NGINXのstaticディレクトリに配置したものを使用するという設定です。

2-7. nginx/uwsgi_paramsの設定

 nginx/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;

2-9. Djangoプロジェクトの作成

 以下のコマンドを実行し、Djangoプロジェクトを作成します。
 プロジェクト名は任意です。(ここでは、"mainproject"という名前にしました。)

$ docker-compose run --rm web django-admin.py startproject mainproject .

 下記のようなWARNINGが出力されますが、「イメージが存在していなかったので、ビルドした」という
 警告なので、問題ありません。

WARNING: Image for service web was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.

 [実行結果の確認①(ファイル構成)]
  ファイル構成は以下の構成となります。
  ※ dbdata配下には、マウントしたPostgreSQLのデータ(/var/lib/postgresql/data)が
   大量に作成されるので、省略しています。

$ tree .
.
├── Dockerfile
├── dbdata
│   ├── PG_VERSION
│   ├── base
│   │   └── ・・・ 省略
│   │   └── ・・・ 省略
│   └── ・・・ 省略
├── docker-compose.yml
├── nginx
│   ├── conf
│   │   └── mainproject_nginx.conf
│   └── uwsgi_params
├── requirements.txt
└── src
    ├── mainproject
    │   ├── __init__.py
    │   ├── asgi.py
    │   ├── settings.py
    │   ├── urls.py
    │   └── wsgi.py
    ├── manage.py
    └── static

 [実行結果の確認②(Docker コンテナの状態)]
  "docker ps -a"コマンドを実行し、Docker コンテナの状態を確認して下さい。
  以下のようにPostgreSQLのコンテナが起動しています。
  ※ uWSGIのDocker コンテナについては、次に説明するuWSGIのiniファイルを作成していない為、
   起動していません。(docker-compose.ymlの"command: uwsgi --ini /code/mainproject/django.ini"の箇所)
  ※ NGINXのDocker コンテナについては、uWSGIのDocker コンテナの起動が
   前提条件となっていますので、こちらもまだ起動していません。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
9d68d40adee0        postgres            "docker-entrypoint.s…"   25 hours ago        Up 25 hours         0.0.0.0:5432->5432/tcp   container.postgres

2-10. uWSGIのiniファイルを作成します。

 src/mainproject/django.iniを新規に作成し、以下の内容を記述します。

[uwsgi]
socket = :8001
module = mainproject.wsgi
wsgi-file = /code/mainproject/wsgi.py
logto = /code/mainproject/uwsgi.log
py-autoreload = 1

 [説明]
  ① socket = :8001
   uWSGIを起動するポート番号を指定します。
  ② module = mainproject.wsgi
   loadするwsgiモジュールを指定します。
  ③ wsgi-file = /code/mainproject/wsgi.py
   loadするwsgiファイルを指定します。
  ④ logto = /code/mainproject/uwsgi.log
   ログを出力する場所を指定します。
   アプリケーションのエラーが発生した時などに確認するログとなります。
  ⑤ py-autoreload = 1
   オートリロード機能の間隔を指定します。
   この設定では、1秒ごとにリクエストがあればリロードするという設定になります。
  ※ 詳細は、「uWSGI Options 」を参照して下さい。

2-11. ALLOWED_HOST、DB及び静的ファイルの設定を行う。

 src/mainproject/settings.pyを開き、以下の修正を行い保存します。

 (1) ALLOWED_HOSTの設定
  下記の修正を行います。
  公開するドメイン名を設定します。
  ※ Django 1.5以降のsettings.pyに、ALLOWED_HOSTSという項目が追加されました。
   これを設定しない場合、デバックモードがtrueの時にエラーとなります。

  (修正前)

ALLOWED_HOSTS = []

  (修正後)

ALLOWED_HOSTS = ["*"]

 (2) DBへの接続設定
  下記の修正を行います。
  docker-compose.ymlのdbのenvironmentに合わせます。
  (修正前)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

  (修正後)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'postgresdb',
        'USER': 'admin',
        'PASSWORD': 'test',
        'HOST': 'db',
        'PORT': 5432,
    }
}

 (3) 静的ファイルの設定
  下記の修正を行います。

  (修正前)

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

  (修正後)

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

# All applications can use Static files of this directory
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "mainproject/static/"),
)

# Collectstatic command put STATICFILES_DIRS and each application's Static files together into this directory
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

# Django template files read this directory to use Static files(example {% static 'style.css' %})
STATIC_URL = '/static/'

 [説明]
  ① STATICFILES_DIRS
   パスの指定先は任意です。
   ここでは、「2-9. Djangoプロジェクトの作成」で説明した
   Djangoプロジェクト(mainproject)配下のstaticディレクトリを指定しています。
   このディレクトリには、各アプリケーションで共通の静的ファイルを配置します。
   後術しますが、本投稿では、faviconを配置します。
  ② STATIC_ROOT
   後術するCollectstaticコマンドを実行した際に、
   STATICFILES_DIRSで指定した共通の静的ファイルと
   各アプリケーション配下のstaticディレクトリの静的ファイルを
   収集し、配置するディレクトリを指定します。
   BASE_DIRは、作業ディレクトリ(src)のことなので、STATIC_ROOTは、src/staticとなります。
   「2-5. docker-compose.ymlの設定」で説明したNGINXの静的ファイルのマウント元と一致します。
   ("- ./src/static:/static"の./src/staticの箇所)
  ③ STATIC_URL
   後術するDjangoのテンプレートファイルが静的ファイルを読み込むディレクトリ先となります。
   「2-5. docker-compose.ymlの設定」で説明したNGINXの静的ファイルのマウント先と一致します。
   ("- ./src/static:/static"の/staticの箇所)

  ※ 「Django Static Files 」を合わせて見ると理解しやすいと思います。

2-12. Docker コンテナを起動します。

以下のコマンドを実行します。

$ docker-compose up -d

 [実行結果の確認①(Docker コンテナの状態)]
  "docker ps -a"コマンドを実行し、Docker コンテナの状態を確認して下さい。
  以下のようにNGINX、uWSGI、PostgreSQLのコンテナが起動しています。

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                            NAMES
f41f7a5b634d        nginx               "nginx -g 'daemon of…"   10 minutes ago      Up 10 minutes       80/tcp, 0.0.0.0:8000->8000/tcp   container.nginx
c12eee7ac189        django_web          "uwsgi --ini /code/m…"   10 minutes ago      Up 10 minutes       8001/tcp                         container.uwsgi
9d68d40adee0        postgres            "docker-entrypoint.s…"   27 hours ago        Up 27 hours         0.0.0.0:5432->5432/tcp           container.postgres

2-13. 動作確認

 ブラウザを開き、"http://0.0.0.0:8000"にアクセスし、
 Djangoのデフォルトのページが表示されることを確認します。
  FireShot Capture 001 - Django_ the Web framework for perfectionists with deadlines. - 0.0.0.0.png

 ここまでの手順で、NGINX、uWSGI、PostgreSQLが動作するDocker コンテナの構築が完了しました。

3. Django Webアプリケーションの作成

 Djangoで"Hello world."を出力するWebアプリケーションを作成します。

3-1. Djangoアプリケーションの作成

 以下のコマンドを実行し、Djangoアプリケーションを作成します。
 アプリケーション名は任意です。(ここでは、"app"という名前にしました。)

$ docker-compose run --rm web python manage.py startapp app

 [実行結果の確認①(ファイル構成)]
  srcディレクトリ配下にappディレクトリが作成されます。

$ tree src
src
├── app
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── mainproject
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-37.pyc
│   │   ├── settings.cpython-37.pyc
│   │   ├── urls.cpython-37.pyc
│   │   └── wsgi.cpython-37.pyc
│   ├── asgi.py
│   ├── django.ini
│   ├── settings.py
│   ├── urls.py
│   ├── uwsgi.log
│   └── wsgi.py
├── manage.py
└── static

5 directories, 19 files

3-2. ビューの作成

 "Hello world."を出力するファイルです。
 src/app/views.pyを開き、以下の修正を行い保存します。

  (修正前)

from django.shortcuts import render

# Create your views here.

  (修正後)

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello world.")

3-3. URLの対応付け

 作成したビューをブラウザからアクセスするために、 URLの対応付けを行う必要があります。

 (1) appディレクトリの配下にurls.pyを新規作成します。
  urls.pyを作成することで、URLの対応付けに必要なURLconfが作成されます。
  以下の内容を記述します。

from django.urls import path
from . import views

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

 (2) mainprojectディレクトリの配下のurls.pyを更新します。
  ルート(プロジェクト)のURLconfにapp.urlsモジュールの記述を反映させます。
  具体的には、
   ① django.urls.includeのimportを追加
   ② urlpatternsのリストにinclude('app.urls')を挿入
  を行います。
  ※ 以下の修正前後のファイルは、文頭のコメント部分は省略しています。
  ※ include()関数は他のURLconfへの参照が可能になります。
   修正後の"path('app/', include('app.urls'))"の箇所は、
   app/にアクセスがあった場合、app配下のURLconfを参照するということを表します。

  (修正前)

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

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

  (修正後)

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

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

3-4. 動作確認

 ブラウザを開き、"http://0.0.0.0:8000/app/"にアクセスし、
 画面に"Hello world."が表示されることを確認します。

4. Databaseの設定

 DjangoでDatabase(PostgreSQL)を利用するための設定を行います。
 ※ 私がCafe好きなので、Cafeの情報を例に説明します。

4-1. モデルの作成

 Webアプリケーションで利用するモデルを最初に定義します。
 ここでは、Area、Cafe、Utilityの3つのモデルを作成します。
 src/app/models.pyを開き、以下の内容を記述して保存します。

  (修正前)

from django.db import models

# Create your models here.

  (修正後)

from django.db import models

class Area(models.Model):
    name = models.CharField(max_length=100)
    create_date = models.DateTimeField('date published')

    def __str__(self):
        return self.name;

class Cafe(models.Model):
    area = models.ForeignKey(Area, on_delete=models.CASCADE)
    name = models.CharField(max_length=100)
    memo = models.CharField(max_length=400)
    website = models.URLField()
    image_path = models.CharField(max_length=400)
    create_date = models.DateTimeField('date published')

    def __str__(self):
        return self.name;

class Utility(models.Model):
    key = models.CharField(max_length=100)
    value = models.CharField(max_length=100)
    create_date = models.DateTimeField('date published')

    def __str__(self):
        return self.key;

 [説明]
  ① Area
   Cafeのエリア情報(場所)を管理するマスタです。
  ② Cafe
   Cafeの情報を保持するテーブルです。
   ※ ForeignKeyを使用してリレーションシップを定義しています。
    各Cafeが1つのAreaに関連付けられています。
  ③ Utility
   汎用的なデータを保持するマスタです。
   今回は、表示方法の切り替えに利用します。
   データの変更で、制御することで、毎回プログラムの変更を行う必要がなくなります。

4-2. モデルを有効にする。

 (1) モデル有効化の準備
  src/mainproject/settings.pyを開き、INSTALLED_APPSに「'app.apps.AppConfig',」を追加します。
  後術するmigrateコマンドを実行すると、INSTALLED_APPSに記述されている
  アプリケーションに対し、各アプリケーションに必要なテーブルを作成します。
  ※ app.apps.AppConfigは、src/app/apps.pyのAppConfigクラスを表します。

  (修正前)

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

  (修正後)

INSTALLED_APPS = [
    'app.apps.AppConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

 (2) マイグレーションファイルの作成
  以下のコマンドを実行し、モデルの変更内容が記述されたマイグレーションファイルを作成します。

$ docker-compose run --rm web python manage.py makemigrations app

  下記のようなメッセージが出力され、src/app/migrations/0001_initial.pyが作成されます。
  ※ src/app/migrations/0001_initial.pyは、手動で調整することも可能です。

$ docker-compose run --rm web python manage.py makemigrations app
Starting container.postgres ... done
Migrations for 'app':
  app/migrations/0001_initial.py
    - Create model Area
    - Create model Utility
    - Create model Cafe

 (3) テーブルの作成
  マイグレーションファイルを元にモデルのテーブルを作成する。
  以下のコマンドを実行します。

$ docker-compose run --rm web python manage.py migrate

  下記のようなメッセージが出力され、テーブルが作成されます。

$ docker-compose run --rm web python manage.py migrate
Starting container.postgres ... done
Operations to perform:
  Apply all migrations: admin, app, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying app.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

 (4) テーブルの確認
  作成したテーブルをDBeaverというSQLクライアントツールを使って確認します。
  DBeaverを使ったことがない方は、「DBeaverのインストールとPostgreSQLへの接続」を参考にして下さい。

  ① DBeaverを起動します。
  ② 新しい接続を作成します。
   以下の画面で、PostgreSQLに接続するDatabase、User、Password、Portの入力を行います。
   ※ 「2-11. ALLOWED_HOSTの設定、DBへの接続設定を行う。」の(2)で設定した内容を入力します。
    スクリーンショット 2020-03-09 0.44.16.png

  ③ テーブルの確認
   下記の通り、app_area、app_cafe、app_utilityテーブルが作成されています。
    スクリーンショット 2020-03-09 0.52.03.png

 (5) データの登録
  下記のようなSQLを実行し、初期データを登録して下さい。

insert into app_area (name, create_date) values ('清澄白河', now());
insert into app_area (name, create_date) values ('神保町', now());
insert into app_area (name, create_date) values ('代々木公園', now());
insert into app_cafe (name, memo, website, image_path, create_date, area_id) values ('ブルーボトルコーヒー', 'カフェモカはここが一番美味しい。', 'https://bluebottlecoffee.jp/', 'bluebottlecoffee_IMG.jpg', now(), '1');
insert into app_cafe (name, memo, website, image_path, create_date, area_id) values ('iki ESPRESSO', 'オセアニアンスタイルのカフェ。フードもコーヒーも美味しい。', 'https://www.ikiespresso.com/', 'ikiespresso_IMG.jpg', now(), '1');
insert into app_cafe (name, memo, website, image_path, create_date, area_id) values ('GLITCH COFFEE', 'コーヒーが好きになったきっかけのカフェ。一番好きです。', 'https://glitchcoffee.com/', 'glitchcoffee_IMG.jpg', now(), '2');
insert into app_cafe (name, memo, website, image_path, create_date, area_id) values ('DIXANS', 'とてもオシャレなカフェ。デザートが絶品です。', 'http://www.dixans.jp/', 'dixans_IMG.jpg', now(), '2');
insert into app_cafe (name, memo, website, image_path, create_date, area_id) values ('Fuglen Tokyo', 'コーヒーがとても美味しいです。代々木公園で遊んだ時は必ず寄ります。', 'https://fuglencoffee.jp/', 'fuglencoffee_IMG.jpg', now(), '3');
commit;

5. 画面の作成

 Databaseに保持した情報を出力するWebアプリケーションを作成します。
 簡単な一覧画面と詳細画面を作成します。

5-1. 一覧画面の作成

 (1) src/appの配下に"templates"ディレクトリを作成し、
  "templates"ディレクトリ配下に""list.html"を作成します。

$ mkdir -p src/app/templates
$ touch src/app/templates/list.html

 (2) src/app/templates/list.htmlを開き、以下の内容で保存します。

{% load static %}

<html lang="ja">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="{% static 'app_css/style.css' %}">
  <link rel="shortcut icon" href="{% static 'pj_image/armx8-1ibhc-001.ico' %}" type="image/vnd.microsoft.icon">
</head>
<body>
<table border="1">
  <thead>
    <tr>
      <th>カフェ</th>
      <th>特徴</th>
      <th>エリア</th>
      <th>サイト</th>
    </tr>
  </thead>
  <tbody>
  {% for cafe in cafe_list %}
    <tr>
      <td><a href="{% url 'app:detail' cafe.id %}">{{ cafe.name }}</a></td>
      <td>{{ cafe.memo }}</td>
      <td>{{ cafe.area.name }}</td>
      <td><a href="{{ cafe.website }}">{{ cafe.website }}</a></td>
    </tr>
  {% endfor %}
  </tbody>
</table>
</body>
</html>

5-2. 詳細画面の作成

 (1) src/app/templatesの配下に"detail.html"を作成します。

$ touch src/app/templates/detail.html

 (2) src/app/templates/detail.htmlを開き、以下の内容で保存します。

{% load static %}

<html lang="ja">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="{% static 'app_css/style.css' %}">
  <link rel="shortcut icon" href="{% static 'pj_image/armx8-1ibhc-001.ico' %}" type="image/vnd.microsoft.icon">
</head>

<body>
<h1>{{ cafe.name }}</h1>
<h2><img src="{% static 'app_image/' %}{{ cafe.image_path }}" alt="{{ cafe.name }}のイメージ" title="{{ cafe.name }}のイメージ" width="384" height="384"></h2>
<h2>特徴{{ cafe.memo }}</h2>
<h2>エリア{{ cafe.area.name }}</h2>
<h2>サイト<a href="{{ cafe.website }}">{{ cafe.website }}</a></h2>
<a href="{% url 'app:list' %}">戻る</a>
</body>
</html>

5-3. ビューの編集

 3-2.で作成した"Hello world."を出力するファイルを編集します。
 src/app/views.pyを開き、以下の修正を行い保存します。

  (修正前)

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello world.")

  (修正後)

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from .models import Area, Cafe, Utility

class IndexView(generic.ListView):
    template_name = 'list.html'
    context_object_name = 'cafe_list'
    def get_queryset(self):
        """Return the last five published records."""
        return Cafe.objects.order_by('name')[:5]
class DetailView(generic.DetailView):
    model = Cafe
    template_name = 'detail.html'

5-4. URLの対応付け

 3-3.で作成したURLを対応付けするファイルを編集します。
 src/app/urls.pyを開き、以下の修正を行い保存します。
 ※ path()を追加し、新しいviewを app.urls モジュールと結びつけます。

  (修正前)

from django.urls import path
from . import views

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

  (修正後)

from django.urls import path
from django.contrib.auth.views import LoginView
from . import views
app_name = 'app'
urlpatterns = [
    path('', views.IndexView.as_view(), name='list'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
]

5-5. 静的ファイルの設置

 (1) appアプリケーションの静的ファイルのディレクトリを作成します。

$ mkdir -p src/app/static/app_css
$ mkdir -p src/app/static/app_image
$ mkdir -p src/app/static/app_js

 (2) appアプリケーションのcssを作成します。
  src/app/static/app_css/style.cssを新規に作成し、以下の内容を記述します。

table {
    background-color: #ffffff;
    border-collapse:  collapse;     /* セルの線を重ねる */
}
th {
    background-color: #000080;
    color: #ffffff;                 /* 文字色指定 */
}
th, td {
    border: solid 1px;              /* 枠線指定 */
    padding: 10px;                  /* 余白指定 */
}

 (3) DBに登録したCafeの画像ファイルをsrc/app/static/app_imageに配置します。
  ※ 画像ファイルは何でも良いので用意して下さい。
   無くても、画像ファイルが表示されないだけなのでスキップしても問題ありません。
 (4) mainprojectプロジェクトの静的ファイルのディレクトリを作成します。

$ mkdir -p src/mainproject/static/pj_css
$ mkdir -p src/mainproject/static/pj_image
$ mkdir -p src/mainproject/static/pj_js

  
 (5) faviconをsrc/mainproject/static/pj_imageに配置します。
  ※ faviconは何でも良いので用意して下さい。
   無くても、faviconが表示されないだけなのでスキップしても問題ありません。
 (6) 静的ファイルの収集を行う。
  以下のコマンドを実行します。

$ docker-compose run web ./manage.py collectstatic

  下記のようなメッセージが出力され、
  「2-11. ALLOWED_HOST、DB及び静的ファイルの設定を行う。」で説明した通り、
  STATICFILES_DIRSで指定した共通の静的ファイルと
  各アプリケーション配下のstaticディレクトリの静的ファイルを収集します。
   → src/app/static/app_css/style.cssと
    src/app/static/app_imageに配置した画像ファイルと
    src/mainproject/static/pj_imageのfaviconが
    src/staticにコピーされます。

$ docker-compose run web ./manage.py collectstatic
Starting container.postgres ... done

137 static files copied to '/code/static'.

5-6. 動作確認

 ブラウザを開き、"http://0.0.0.0:8000/app/"にアクセスし、
 一覧画面と詳細画面が下記のように表示されていることを確認します。
 (1) 一覧画面
  FireShot Capture 008 -  - 0.0.0.0.png

 (2) 詳細画面
  FireShot Capture 009 -  - 0.0.0.0.png

NGINX、uWSGI、PostgreSQLが動作するDocker コンテナで、
DjangoのWebアプリケーションを動作確認するまでの手順が完了です。
Webアプリケーションを作る上で、基本的なことは紹介できたと思いますので、
本投稿が役に立てば幸いです。

6. 参考情報(Django Admin)

 本投稿では、DBeaverを使ってデータの登録を行いましたが、Django Adminという
 Djangoに用意されている管理画面を使ってデータを登録することも可能です。

6-1. 管理ユーザの作成

 以下のコマンドを実行します。

$ docker-compose run --rm web python manage.py createsuperuser

 コマンドプロンプトで以下のように任意の情報を入力します。
  Username:admin
  Email address:admin@example.com
  Password:admin

$ docker-compose run --rm web python manage.py createsuperuser
Starting container.postgres ... done
Username (leave blank to use 'root'): admin
Email address: admin@example.com
Password: 
Password (again): 
The password is too similar to the username.
This password is too short. It must contain at least 8 characters.
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

6-2. モデルをDjango Adminに登録

  「4-1. モデルの作成」で作成したモデルをDjango Adminで編集できるようにします。

  src/app/admin.pyを開き、以下の修正を行い保存します。

  (修正前)

from django.contrib import admin

# Register your models here.

  (修正後)

from django.contrib import admin

from .models import Area
from .models import Cafe
from .models import Utility

admin.site.register(Area)
admin.site.register(Cafe)
admin.site.register(Utility)

6-3. 動作確認

 ブラウザを開き、"http://0.0.0.0:8000/admin/"にアクセスします。
 Django Adminのログイン画面が開くので、
 「6-1. 管理ユーザの作成」で作成した管理ユーザでログインして下さい。
 ログイン後、Area、Cafe、Utilityのモデルの参照、追加、更新が出来ることを確認して下さい。

 (1) ログイン画面
  FireShot Capture 006 - Log in - Django site admin - 0.0.0.0.png

 (2) 管理画面
  FireShot Capture 007 - Site administration - Django site admin - 0.0.0.0.png
  

7. 参考情報(Bootstrap4)

 Bootstrap4を使用する方法を説明します。
 「2-3. requirements.txtの設定」で説明した通り、
 DjangoでBootstrap4を利用するためのパッケージをインストールしていますので、
 以下の手順を行うことで、Bootstrap4のcss、Javascriptの利用が可能です。

7-1. django-bootstrap4の設定

 src/mainproject/settings.pyを開き、以下の修正を行い保存します。

 (1) INSTALLED_APPSにdjango-bootstrap4を追加します。

  (修正前)

INSTALLED_APPS = [
    'app.apps.AppConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

  (修正後)

INSTALLED_APPS = [
    'app.apps.AppConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap4',
]

 (2) TEMPLATESのbuiltinsにbootstrap4.templatetags.bootstrap4を追加します。
  ※ これを追加することで、各htmlに{% load bootstrap4 %}を記述する必要がなくなります。

  (修正前)

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

  (修正後)

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            'builtins':[
                'bootstrap4.templatetags.bootstrap4',
            ],
        },
    },
]

7-2. Utilityテーブルに制御フラグを追加(おまけ①)

 UtilityテーブルにBootstrap4のcssを利用するかしないかを制御するデータを追加します。
 このデータを使って、一覧画面のhtmlでBootstrap4のcssを読み込むか読み込まないか判別します。
 * 使用しない場合、value列の値を”1”以外に設定します。

insert into app_utility (key, value, create_date) values ('bootstrap_flg', '1', now());
commit;

7-3. 一覧画面の修正

 (1) src/mainproject/settings.pyを開き、以下の修正を行い保存します。(おまけ②)
  get_context_dataを使って、「7-2. Utilityテーブルに制御フラグを追加」で
  追加したデータをhtmlで利用できるようにしています。

  (修正前)

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from .models import Area, Cafe, Utility

class IndexView(generic.ListView):
    template_name = 'list.html'
    context_object_name = 'cafe_list'
    def get_queryset(self):
        """Return the last five published records."""
        return Cafe.objects.order_by('name')[:5]
class DetailView(generic.DetailView):
    model = Cafe
    template_name = 'detail.html'

  (修正後)

from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.views import generic
from .models import Area, Cafe, Utility

class IndexView(generic.ListView):
    template_name = 'list.html'
    context_object_name = 'cafe_list'
    def get_queryset(self):
        """Return the last five published records."""
        return Cafe.objects.order_by('name')[:5]

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context["bootstrap_flg"] = Utility.objects.all().filter(key='bootstrap_flg').first()
        return context

class DetailView(generic.DetailView):
    model = Cafe
    template_name = 'detail.html'

 (2) src/app/templates/list.htmlを開き、以下の修正を行い保存します。
  bootstrap_flg.value == "1"の時に、{% bootstrap_css %}を読み込むように記述しています。
  今回、おまけ①②をすることで、テーブルのデータによって、
  Bootstrap4のcssを読み込むか制御できるように対応しましたが、
  単純に使用したい場合は、おまけ①②は飛ばし、{% bootstrap_css %}を
  htmlに追加するだけで使用が可能です。
  
  (修正前)

{% load static %}

<html lang="ja">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="{% static 'app_css/style.css' %}">
  <link rel="shortcut icon" href="{% static 'pj_image/armx8-1ibhc-001.ico' %}" type="image/vnd.microsoft.icon">
</head>
<body>
<table border="1">
  <thead>
    <tr>
      <th>カフェ</th>
      <th>特徴</th>
      <th>エリア</th>
      <th>サイト</th>
    </tr>
  </thead>
  <tbody>
  {% for cafe in cafe_list %}
    <tr>
      <td><a href="{% url 'app:detail' cafe.id %}">{{ cafe.name }}</a></td>
      <td>{{ cafe.memo }}</td>
      <td>{{ cafe.area.name }}</td>
      <td><a href="{{ cafe.website }}">{{ cafe.website }}</a></td>
    </tr>
  {% endfor %}
  </tbody>
</table>
</body>
</html>

  (修正後)

{% load static %}

<html lang="ja">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" type="text/css" href="{% static 'app_css/style.css' %}">
  {% if bootstrap_flg.value == "1" %}
    {% bootstrap_css %}
  {% endif %}
  <link rel="shortcut icon" href="{% static 'pj_image/armx8-1ibhc-001.ico' %}" type="image/vnd.microsoft.icon">
</head>
<body>
<table border="1">
  <thead>
    <tr>
      <th>カフェ</th>
      <th>特徴</th>
      <th>エリア</th>
      <th>サイト</th>
    </tr>
  </thead>
  <tbody>
  {% for cafe in cafe_list %}
    <tr>
      <td><a href="{% url 'app:detail' cafe.id %}">{{ cafe.name }}</a></td>
      <td>{{ cafe.memo }}</td>
      <td>{{ cafe.area.name }}</td>
      <td><a href="{{ cafe.website }}">{{ cafe.website }}</a></td>
    </tr>
  {% endfor %}
  </tbody>
</table>
</body>
</html>

7-4. 動作確認

 ブラウザを開き、"http://0.0.0.0:8000/app/"にアクセスし、
 一覧画面にBootstrap4のcssが使用されていることを確認します。

 FireShot Capture 011 -  - 0.0.0.0.png

参考元

Compose file version 3 reference
Docker Composeチュートリアル: herokuのPostgresをローカルにさくっとコピーする
Supported tags and respective Dockerfile links
はじめての Django アプリ作成、その 1
SQLのSELECT文を、DjangoのQuerySet APIで書いてみた
Djangoにおけるクラスベース汎用ビューの入門と使い方サンプル

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Macでtelnetコマンドを叩く

対象読者

  • 「松田〜Macでtelnetコマンド叩きたいんだけど〜。」という方

動作環境

  • OS: macOS Mojave バージョン 10.14.6

何ができるようになるか?

Macでtelnetコマンド叩ける。笑
そのまんま。笑

何故それをするか?

個人的な体験談なんだけど、何かしらの技術を書籍とかで学習する際簡単なソースコードの動作確認でtelnet使うことあるから。

どうやるか?

手段

  • brewでサクッとtelnetコマンドを入れる
  • curlコマンドでtelnetコマンドを代用する

brewでサクッとtelnetコマンドを入れる

brewインストール

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

telnetインストール

$ brew install telnet

curlコマンドでtelnetコマンドを代用する

一般的には以下。

$ curl -v telnet://{ホスト名}/{パス}:{ポート番号}

たとえば以下のような感じ。

$ curl telnet://example.com:443

参考

あとがたり

なんもねえわ。笑

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

macOS Catalina で python の開発環境を作るメモ

メモ随時更新予定

狙いとしては python の開発環境の構築

Mojave から Catalina に上げた環境で、普通にやってるとバージョンの違いで python3 とか pip3 で期待通りに動かなかったので pyenv あたりを利用してうまいこと動かないか試す。

本当は Docker とか使った方が良さそうだけどひとまず・・・

homebrew

ここからスタート。

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"

pyenv インストール

$ brew install pyenv
$ pyenv -v
pyenv 1.2.17

プロファイルの設定

$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n  eval "$(pyenv init -)"\nfi' >> ~/.bash_profile

https://github.com/pyenv/pyenv

ちなみに、zsh の場合には .zshrc に対して同様の設定を行えば良いみたいです。

Zsh note: Modify your ~/.zshrc file instead of ~/.bash_profile.
https://github.com/pyenv/pyenv

.zprofile ではなく、.zshrc な理由は不明。

反映

$ source ~/.bash_profile

バージョンを指定して python をインストール

インストール可能なバージョンを確認

$ pyenv install -l

使いたいバージョンをインストール

$ pyenv install 3.7.7

インストールの確認

$ pyenv versions
* system (set by /Users/ykinomt/.pyenv/version)
  3.7.7

バージョン切り替え

現状確認

$ python -V
Python 2.7.16

切り替え

$ pyenv global 3.7.7
$ python -V
Python 3.7.7

そのディレクトリ単位で切り替えるなら local を使う。

$ python -V
Python 2.7.16
$ pyenv local 3.7.7
$ python -V
Python 3.7.7

localを使った場合、そのディレクトリに .python-version というファイルが作成され、そのディレクトリでは指定されたバージョンで動く。
アプリケーションを作成する様な場合は local で指定した方が良いかも。

vscode の設定

特に必要ないが、インタープリタの設定で出てくるバージョンは VSCode 起動までにインストールされたモノみたいなので、上記の設定で新規にインストールした場合には一度 vscode を再起動しないと選択できないかも。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker/Kubernetesなど コマンド一覧

仕事および趣味で利用した、Docker/Kubernetesのコマンドの備忘。
ついでに使わないとすぐ忘れるLinuxなどその他色々コマンドの情報のせます。。

Docker

コマンド 概説
docker ps 稼働コンテナの一覧表示 実行中:docker ps
終了状態含む:docker ps -a
docker images ローカルで保持しているイメージリストを表示
docker rmi [id名] ローカルのイメージを削除 削除できない場合は、 docker rmi [id名] -f で実行する
-f:強制的に削除
docker build [-t リポジトリタグ] Dockerfileからイメージのビルド
docker pull [コンテナイメージ] コンテナイメージのダウンロード
docker run [コンテナイメージ] コンテナイメージを指定して起動
docker run -it [image名] shell コンテナを起動して対話型シェルを実行 docker run -it centos bash
docker logs [Container ID] ログ表示
docker hisotry [images ID] イメージへの履歴
docker tag ローカルイメージ名:タグ リモートリポジトリ:タグ名 ローカルリポジトリのイメージをリモートリポジトリ名にタグ付け
docker push タグ付けしたリモートリポジトリ名 リモートリポジトリへの登録
docker commit containerID image:tag コンテナイメージの登録
docker start containerID コンテナの開始
docker stop containerID コンテナの停止
docker stop $(docker ps -q) 稼働中の全コンテナの停止
docker network ls コンテナネットワークをリスト表示
docker network inspect [networkID] コンテナネットワークの詳細設定を表示
docker network create [ネットワーク名] コンテナネットワークを新規作成 docker network create mynet1
docker built -t イメージ名:tag名 DockerfileのPATH名 Dockerイメージの作成 docker build --tag mydaemon:0.1 ./Dockerfile

Kubernetes

コマンド 概説
docker ps 稼働コンテナの一覧表示
TD TD
TD TD

Linux

ほぼCent0Sの例です。

Cent0S

コマンド 概説
systemctl list-unit-files -t service サービス一覧と自動起動設定の確認 (旧 chkconfig --list)
cat /etc/redhat-release バージョン確認
yum list installed yumでインストールされた一覧の確認
nslookup dns(ip) DNSサーバーへの名前解決問い合わせ

参考

Docker reference
https://docs.docker.com/engine/reference/commandline/build/

Docker コマンドチートシート
https://qiita.com/wMETAw/items/34ba5c980e2a38e548db

awkコマンド
https://www.atmarkit.co.jp/ait/articles/1706/08/news015.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby】最新バージョンにしようとしてハマったこと

rbenvでバージョンがうまく切り替わらなかったことはありませんか?
Macのrbenvで最新バージョンにしようとしてハマったことを共有したいと思います。

最新バージョンまでの流れと状況

rbenvのバージョン一覧を確認

$ rbenv versions
=>
system
2.3.7
2.4.1
* 2.5.1 (set by /Users/use_name/.ruby-version)

Homebrewをアップデートして、rbenvをアップグレード

$ brew update
$ brew upgrade rbenv ruby-build

rbenvからインストールできるRubyのバージョンを確認

$ rbenv install -l

たくさん出てきますが2020年3月22日時点での安定最新バージョンの2.7.0をインストール

$ rbenv install 2.7.0

再度、rbenvのバージョン一覧を確認

$ rbenv versions
=>
system
2.3.7
2.4.1
* 2.5.1 (set by /Users/use_name/.ruby-version)
2.7.0

2.7.0がインストールされています。

rbenvのバージョンを切り替える

全体に反映ならglobal

rbenv global 2.7.0

特定のディレクトリのみならlocalを設定

rbenv local 2.7.0

切り替わって成功するはずですが切り替わりませんでした。

rbenvのバージョン一覧を確認

$ rbenv versions
=>
system
2.3.7
2.4.1
* 2.5.1 (set by /Users/use_name/.ruby-version)
2.7.0

2.5.1のままで変わっていない。

解決方法

viコマンドで/Users/use_name/.ruby-versionファイルの中身を確認

$ vi /Users/use_name/.ruby-version
=>
2.5.1

2.5.1と書いてある。(use_nameはrbenv-versionsで表示されているset byの後に書いてあるものを使う)

iキーを押してから2.7.0に変更(入力できない場合は、escキーを押してからiのキーを押す)

保存して抜けるためにescキーを押してから:wqと入力してエンターキーを押す。

rbenvのバージョン一覧を確認

$ rbenv versions
=>
system
2.3.7
2.4.1
2.5.1
* 2.7.0 (set by /Users/use_name/.ruby-version)

2.7.0に変わっている。

rubyのバージョンを確認

$ ruby -v
=>
ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin17]

最新バージョンに変わりました!!

参考記事

TECHACADEMY magazine
Rubyバージョンアップの方法

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Ubuntu Sambaではまったことメモ

Ubuntu でSamba を設定していて色々ハマったことのメモ

Windowsからは書き込み可、だがMacからは不可

 ディレクティブで[raspberry pi] という設定を定義して、そこに色々設定をしていたつもりだったが、Macからアクセスした際に、[homes]の設定が継承されていた模様。[homes]はデフォルトのsmb.conf記載で書き込み不許可であるため、書き込みができない動作となっているようだった。Windowsからは書き込みまでできていたため、Windowsからのアクセスでは設定はhomesまでフォールバックしていなかった模様。結局、[homes]ディレクティブを丸々削除すると、Macからも[raspberry pi]ディレクティブで設定が読まれるようになった(ようにみえる)。理由が今一つよくわからない。
 また、他の方の記事によると、
unix extensions = no
を、global ディレクティブ配下に定義することで解決した、との記事があったが、こちらは私の環境では定義済みであったため、該当しなかった。ここから得られる教訓としては、余計なものは書くべきでない、ということか。。。

参考URL: http://www.samba.gr.jp/project/translation/3.5/htmldocs/manpages-3/smb.conf.5.html

Windows のユーザアカウント制御の話

こちらはいまだ未解決で、暫定対処の状態だが、ユーザ認証が通らず、Windows10から正常にSamba接続ができない状態に陥った。
以下の記事が参考になりました。:
https://blog.treedown.net/entry/2019/06/03/010000

ntlm v2 の通信サポートの問題のようなので、運用しようとしている自宅環境で問題がないかを確認して、追記しようと思います。

以上、個人アカウントでの初投稿、自分用のメモでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

パソコンを買ってからpythonでプログラムを動かすまで

動作環境

Mac OS Catalina
ubuntu

この記事について

プログラミングに興味を持ってパソコンを買ってみたが、これから何をすればいいかわから
ない人に向けて、Macでプログラミングを始める際にはじめにすべきことをまとめました。
この記事ではパソコンを買ったばかりの状態から、初めてpythonプログラムを書いて、動か
せるようになることを目標にします。

環境構築 

まずは環境構築をします。環境構築というのは自分のパソコンでプログラムを書く準備をすることです。

pythonの環境構築には以下のものが必要です。

  • VSCode
  • Python3

また今回は必要ないですが、

  • jupyternotebook

こちらも後々必要になると思うので合わせて入れておきます。

順番に入れていきましょう。

各種インストールはMacとubuntuのどちらを使っているかによって異なるので,自分の使っている方のインストール方法を見てください.

VSCodeのインストール

プログラムを書いて動かすにはそもそもプログラムを書くための道具が必要です。これをテキストエディタと呼びます。VSCodeはテキストエディタの一種で、使い方が簡単なので初心者におすすめです。

Mac

こちらからダウンロードしてください

VSCode公式

スクリーンショット 2020-03-18 18.11.38.png

リンクをクリックすると画像のような画面が出てくるので、矢印の部分をクリックすると
ダウンロードされます。

そうすると、macの方でダウンロードフォルダに入ってると思うのでクリックして開きます。

スクリーンショット 2020-03-22 10.18.46.png

赤い矢印の部分がダウンロードフォルダです。

これでvscodeのインストールは完了しました。

ubuntu

こちらにアクセスして以下の画像の部分をクリックしていきインストールしてください.

VSCode公式

Screenshot from 2020-03-22 19-26-38.png

ダウンロードが完了すればホーム画面に戻ってください.
Screenshot from 2020-03-22 19-31-01.png

ファイルを開き

Screenshot from 2020-03-22 19-31-05.png

Downloads(またはダウンロード)を選択し

Screenshot from 2020-03-22 19-31-17.png

赤丸のようなファイルがあると思うのでそれをクリックしてください

Screenshot from 2020-03-22 19-31-22.png

その後別の画面が出てくるので,パスワードを打ち込んでしばらくすればインストール完了です.

Python3のインストール (Macのみ,ubuntuは飛ばしてください)

次にpython自体のインストールをします。

Macでは標準でpython2が入ってるのですが、最新のpythonはバージョン3以上なので、そちらを入れていきます。

python公式

こちらから最新版のpythonを選んでクリックするとダウンロードできます。

先ほどと同様にダウンロードフォルダに入ってるのでクリックして開くとダウンロードできます。

jupyternotebookのインストール

次にjupyternotebookを入れていきます。
こちらは先ほどのVSCodeと同じテキストエディタなのですが、VSCodeとは仕様だったり、使い所が異なります。今回は入れるだけなので詳しい説明は割愛します。

Mac

まずはターミナルを開きます。ターミナルとはパソコンに直接命令できるソフトのようなもので、アプリケーションフォルダのユーティリティの中に入ってます。

ターミナルを開けたら、以下をコピペで打ち込みます
(コピーしたいものを選択しながら、command+cでコピー、command+vでペーストできます)

pip install jupyter

しばらくするとインストールが完了するはずです。

同じようにターミナルで以下を打ち込んでブラウザでjupyternotebookが立ち上がれば成功です。

jupyter notebook

ubuntu

まずはターミナルを開きます。ターミナルとはパソコンに直接命令できるソフトのようなもので、CtrlとAltとTキーを同時に押せば黒い画面が出てきます.これがterminalです

Screenshot from 2020-03-22 19-48-51.png

その画面で以下のコマンドを打ち込んでください.

sudo apt install jupyter-notebook

するとパスワードが聞かれるので打ち込んでください.
しばらくするとインストールが完了します.
terminalで以下を打ち込んで画面が出てきたらちゃんとインストールされています.

jupyter notebook

Screenshot from 2020-03-22 20-01-47.png

プログラムの書き方と実行方法について

まずはプログラムを書きましょう。プログラムとはコンピュータに対する命令をまとめたようなもので、命令が複雑になる程、命令の手順が増えますよね。
その手順をまとめたものをファイルと言います。

プログラムを書いて実行する大まかな順序は以下の通りです。

  1. ファイルを作る
  2. 作ったファイルのプログラムを書く
  3. 実行する

Mac

まずはプログラムを書き込むためのファイルを作ります。

ターミナルで以下を打ち込んでください

touch test.py

そしてvscodeを開きます。

vscodeを開いたらcommon + oを押して先ほど作ったファイルを開きます。
test.pyという名前のファイルが存在するはずなので、それをクリックして右下の開くを押します。

スクリーンショット 2020-03-22 11.00.15.png

これでファイルを開けたのでプログラムを書いていきます。

今回はプログラムの意味については分からなくても構わないので、コピペでファイルに以下を貼り付けてください。

print("Hello World!")

これでプログラムが書けたので保存します。
(保存はcommand + sでできます。)

それではプログラムを実行してみましょう。

ターミナルで以下を打ち込んでください。

python3 test.py

すると先程書いたプログラムの結果が表示されます

ubuntu

まずはプログラムを書き込むためのファイルを作ります。

terminalを開きます(CtrlとAltとTキーを同時に押せば黒い画面が出てきます.)

Screenshot from 2020-03-22 19-48-51.png

その画面で以下を打ち込んでください

touch test.py

これで「test.py」という名前のファイルができました.

ls

と打ちこむとたしかに「test.py」という名前のファイルがありますね!

Screenshot from 2020-03-22 19-50-39.png

そして以下を打ち込むとvscodeで「test.py」のファイルを編集する画面を開くことができます.

code test.py

これでファイルを開けたのでプログラムを書いていきます。

今回はプログラムの意味については分からなくても構わないので、コピペでファイルに以下を貼り付けてください。(printと書いてあるので何かが表示されそうですね)

print("Hello World!")

これでプログラムが書けたので保存します。
保存は 「Ctrl + S」(Ctrlを押しながらSを押す) でできます。

それではプログラムを実行してみましょう。

ターミナルに戻って以下を打ち込んでください。

python3 test.py

すると先程書いたプログラムの結果が表示されます

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[ターミナル入門] ディレクトリ/ファイル操作

はじめに

[用語]
- ディレクトリ:フォルダのこと
- ホームディレクトリ:Finderを立ち上げた時始めに表示されるフォルダ
- カレントディレクトリ:今開いているフォルダの場所

[便利な小技]
- 上矢印キー(↑)でコマンドのヒストリーをさかのぼれる
- tabキーでディレクトリ・ファイル名の入力保管をしてくれる

ディレクトリパスの表示と移動

#カレントディレクトリを表示
pwd

#ホームディレクトリに移動
cd

#1つ上の階層に戻る
cd ..

#2つ上の階層に戻る
cd ../..

#指定ディレクトリに移動する
cd 移動先ディレクトリのパス

ディレクトリ/ファイルを表示

#カレントディレクトリ内のディレクトリ/ファイルを表示
ls

#カレントディレクトリ内の、隠しファイルを含むディレクトリ/ファイルを表示
ls -a

ディレクトリ/ファイルの作成と名前変更

#新規ディレクトリ作成
mkdir sample  // => sampleフォルダができる

#新規ファイル作成
touch sample.html  // => sample.htmlファイルができる

既存ディレクトリ/ファイルの移動と複製

#ファイル名を変更
mv sample.html sample2.html  // => sample.htmlをsample2.htmlにファイル名を変更

#ファイルを別のディレクトリに移動
mv sample.html dev/  // => sample.htmlをdevフォルダに移動

#ファイルを複製
cp sample.html dev/  // => sample.htmlをdevフォルダ内で複製
cp sample.html sample2.html  // => sample.htmlをsample2.htmlという名前で複製

##ディレクトリを複製
cp -r dir1/ dir2  // => dir1をdir2という名前で複製

Finerを開く

##Finerを開く
open . // => カレントディレクトリでFinderを開く
open ~/  // => ホームディレクトリをFinderで開く
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PDFを印刷したらフォントが変

最近OSをCatalinaにアップデートしました。Sidecarがとても便利ですね!

OSを変更してから初めてPDFを印刷しようとしたところ,以下の2つの問題が起こりました。(使用プリンタ:OKI の MC843)
1. プリンタジョブ画面で "Stopped Filter Failed" というエラーが出て,印刷できない
2. 印刷物のフォントが変(以下の画像)
Screen Shot 2020-03-22 at 4.28.45.png

1. 「エラー "Stopped Filter Failed"」の解決方法

プリンタを一旦削除,追加し直して再起動で解決。
 参考:Solved: Printing Pdf - error "Stopped Filter Failed" or Stopped - Unable to convert PostScript file

2. 「フォントが変」の解決方法(?)

OKI の Webサイトからドライバをインストールして解決しました。
解決したのに,サブタイトルを「解決方法(?)」としたのは,次のような気になることがあるからです。

気になること

1つ気になるのが,macOS ユーザーガイドのMacでプリンタを追加する-Apple サポートによると,

"プリンタに付属のソフトウェアや、製造元のWebサイトからのソフトウェアをインストールしないでください。"

とあるんですよね。理由が書いていないのですが,セキュリティの問題でしょうか...?ご存知の方はコメントいただけると嬉しいです。

なお,このユーザーガイドの通りにプリンタを追加すると,自動でドライバが AirPrint に選択されます。AirPrint でもうまく印刷できるファイルもありますが,ファイルによってはフォントを埋め込んでも,ビュワーを変えても上の画像のようなフォントになってしまうのです。

私自身,やらないでくださいと言われていること(製造元のWebサイトからのソフトウェアをインストール)をやっていいと思える根拠もなくやりたくないのですが,フォントが変すぎて読めたもんじゃないので試しました。なので試すか試さないかは自己責任でお願いします╰(╰.ω.)╯

おわりに

「フォントが変!」の他の解決方法や,"製造元のWebサイトからのソフトウェアをインストールしないでください"の理由をご存知の方,コメント等いただけますと嬉しいです!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む