ラベル vscode の投稿を表示しています。 すべての投稿を表示
ラベル vscode の投稿を表示しています。 すべての投稿を表示

2022年10月16日日曜日

VSCodeの拡張機能で「改行コード」を見える化する


こんにちは。よっしーです。

プログラムを書く時、Linux環境とWindows環境の両方を使っていると、
ソースファイルによって、改行コード が LF だったり CRLF だったりで
ごっちゃになってしまう場合がありませんか?

開発プロジェクトによって文字コードや改行コードが決まっていることも
多いと思いますが、文字コードや改行コードが間違っているために、
ソースファイルをコミットしなおし。なんてざらにありますよね...w

VSCode標準のエディタだと改行コードの見分けがつかないので、
私は拡張機能の「code-eol」を使用しています。


設定方法は簡単です。
  1. VSCodeの左下の「歯車」マークを選択
  2. 設定を選択
  3. 拡張機能 code-eol Configuration を選択
  4. settings.jsonで編集を選択
  5. settings.json の中身を編集して上書き保存
となります。



私の環境だと settings.json の 14行目に 以下を設定しており、
CRLFがあれば■NG■と改行コード位置に表示される設定にしています。
”code-eol.crlfCharactor": "■NG■"
(現在のプロジェクトでは、改行コードはLFと決まっているので。)

改行コードがLFのファイルは■NG■は表示されず、


CRLF が使われているファイルは以下のように表示されます。


これだと一目であれ?と気づくので、改行コード間違いを防ぐことが出来ます。

改行コードの違いでお困りのかたは、使ってみて下さい。ではまた~。

2021年9月17日金曜日

vscode #06 : Markdown PDF でフォント指定してPDF化

どうも、もりもりです。

今回はたまに出てくるvscodeネタです。 今となっては欠かせない人は多いのではないでしょうか。 社内ではレポートや議事録など、Excelで作成するドキュメントが多いのですが まぁ内容が確認できればOKなのでPDFでもOKにしてもらいました。 なのでMarkdownで書いて拡張機能の「Markdown PDF」を入れてPDF化してます。 がしかし!中国語フォントに。。。

と言うことで、「Markdown PDF」使用時のフォントの指定方法を紹介したいと思います。

拡張機能「Markdown PDF」

拡張機能は下記です。

CSSファイルを作成

cssファイルを作成します。ファイル名を付けて保存。 どこに保存してもいいですがPDF化するmdファイルと同階層に格納しておけば後で設定がラクです。 今回はメイリオを指定してみます。

md.css

body {
    font-family: "Meiryo";
}

code {
    font-family: "Meiryo";
}

設定にCSSファイルの相対パスを追加

vscodeの設定を開き(Windows : Ctrl + , / Mac : command + ,) 「markdown styles」で検索。下記設定に、PDF化したいファイルからの相対パスを入力し、OKをクリックするだけ。

今回の例ですと、.\md.cssとするだけ。

拡張機能自身が持っているスタイルを上書きするような記事もあったりしますが 更新時や何かの拍子に元に戻ってしまうこともあると思うので設定に追加する方がいいでしょう。

また、時と場合によってはフォントを変更したいこともあると思います。 なのでこちらの設定に追加する方法をオススメします。

ちなみに拡張機能が保持しているスタイルは下記にあります。(※Windowsの場合)

C:\Users\xxxx\.vscode\extensions\yzane.markdown-pdf-1.4.4\styles

あとはmdファイル内右クリックでPDF出力メニューを選択してサクッとPDF化するだけです。 それでは皆さま、良い vscode life を。

過去のvscode関連記事はこちらを↓↓↓
以上、もりもりでした。

2021年2月13日土曜日

vscode #05 : PlantUMLを使ってみる [Mac][Windows]

どうも、もりもりです。

以前ブログメンバーのよっしーさんの記事で、仕事先での設計書作成が「脱Excel」の流れになってきてるということで draw.ioの紹介がありましたが今回はUMLをテキストベースで書けるPlantUMLについて紹介したいと思います。

draw.ioの記事はこちら。


導入

PlantUMLはJavaが必要なのでまずはJavaを入れてください。Macの方はHomebrewで入れてもOKです。(というかそっちのがラク)
シーケンス図、アクティビティ図以外も使うならGraphvizも必要になるようです。

◆ Macの場合
$ brew install plantuml
$ brew install graphviz

※記事を書いた時点(2021/02/12)ではplantumlのインストール時にgraphvizも一緒に入ったようです。

◆ Windowsの場合
> winget install -e --id Oracle.JavaRuntimeEnvironment
> winget install graphviz

vscodeでプラグインをインストール

拡張機能より「plantuml」と入力して下記画像のプラグインをインストール

動作確認

xxxx.puという拡張子でファイルを作成します。

下記のようにファイルを作成して入力します。

sequence-sample.pu

@startuml
participant "View" as V
participant "User Class" as U

activate V
V -> V: click button
V -> U: create instance
activate U
V -> U: GetUsers()
U --> V: List
deactivate U
V -> V: bind users to GridView
@enduml

option + D(Windowsならalt + D)でプレビュー表示してみると、あらゴイゴイスー。

公式ドキュメントはこちらを。

画像出力

作成したUMLを画像に出力してみましょう。 Command + Shift + P(WindowsならCtrl + Shift + P)で 「uml」と入力します。 「Export Current Diagram」を選択し、「出力形式」を選択します。

markdownファイルに挿入するとこんな感じに。
※Darkテーマだとシーケンス図のメッセージが黒で見えなかったのでLightテーマにしてます。

さいごに

画像出力もできるし慣れてしまえばこっちの方がサクっと作れそうですね。 設計書をMarkdownやasciidocなどで作成してる人はぜひ使ってみてください。 mermaid.jsの方も以前チラッと触ってみたことがあり、同じようなUMLを作成できるのでまた違いなどが判れば紹介したいと思います。

以上、もりもりでした。

2020年11月24日火曜日

Blazor WebAssemblyをvscodeで触ってみた

どうも、もりもりです。

今月ついに.NET 5.0がリリースされましたね。 今回は.NETでSPA(SinglePageApplication)を実現できるWebフレームワークの BlazorWebAssemblyを触ってみました。 SPAとは、ページ遷移を行わない単一Webページで動作するWebアプリです。 一般的なWebアプリではJavaScriptを用いてSPAを実現しますが、 C#だけでできてしまうってC#erからしたら嬉しくないですか?

はじめに

Blazorには2種類のモデルがあり、サーバーサイドで動作するBlazor Serverと、 ブラウザ上で動作するBlazor WebAssemblyがあります。

Blazor Serverは、サーバー上の.NET Core環境で主な処理が行われ、サーバー側がブラウザのDOMを変更します。 Blazor WebAssemblyは、最初に.NETアセンブリとランタイムがブラウザにダウンロードされ ブラウザ上で.NETコードを実行し、別途プラグインなどは不要です。

vscodeでBlazor WebAssemblyプロジェクトを作成して、 さらにTodoMVC のようなTodoページを追加してみました。

プロジェクト作成

まずは任意の場所で下記コマンドを叩いてプロジェクトを作成します。

$ dotnet new blazorwasm -o BlazorWasmSample

プロジェクト構成

確認すると初めからテンプレート的な感じで3つほどページが用意されています。

BlazorWasmSample
  ├── App.razor
  ├── BlazorWasmSample.csprojs
  ├── Pages
  │   ├── Counter.razor
  │   ├── FetchData.razor
  │   └── Index.razor
  ├── Program.cs
  ├── Properties
  │   └── launchSettings.json
  ├── Shared
  │   ├── MainLayout.razor
  │   ├── MainLayout.razor.css
  │   ├── NavMenu.razor
  │   ├── NavMenu.razor.css
  │   └── SurveyPrompt.razor
  ├── _Imports.razor
  └── wwwroot
      ├── css
      │   ├── app.css
      │   ├── bootstrap
      │   │   ├── bootstrap.min.css
      │   │   └── bootstrap.min.css.map
      │   └── open-iconic
      │       ├── FONT-LICENSE
      │       ├── ICON-LICENSE
      │       ├── README.md
      │       └── font
      │           ├── css
      │           │   └── open-iconic-bootstrap.min.css
      │           └── fonts
      │               ├── open-iconic.eot
      │               ├── open-iconic.otf
      │               ├── open-iconic.svg
      │               ├── open-iconic.ttf
      │               └── open-iconic.woff
      ├── favicon.ico
      ├── index.html
      └── sample-data
          └── weather.json

ソースコードは下記に置いてます。

アプリ起動

ということで早速実行してみましょう。 BlazorWasmSampleまで移動して下記コマンドで実行します。

$ dotnet run

https://localhost:5001 にアクセスします。 シンプルで今風な感じの画面が表示されました。 Homeメニューには、おなじみの「Hello world」ですね。

Counterメニューをみてみましょう。 ボタンをポチポチするとカウントアップされていきます。

最後はFetch dataページです。 こちらはGrid的な表の画面です。 標準のtableなので編集やソートなどフィルタリングなどはできません。 このあたりはいい感じのパッケージがないかまた探してみます。

ソースを確認

Counterページのソースを確認してみましょう。

Counter.razor

@page "/counter"

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

これだけで書けてしまうんですね。 すごい。シンプル。

ボタンをクリックすると @code 内の変数 currentCount がインクリメントされ 画面上の @currentCount に反映されるようです。

Todoを追加してみる

◆ 追加 / 編集ファイル

では、TodoMVCのような ページを追加してみましょう。 追加、編集するファイルは下記の4つだけです。

BlazorWasmSample
  ├── Pages
  │   ├── [★] Todo.cs
  │   └── [★] Todo.razor
  ├── Shared
  │   ├── [★] NavMenu.razor
  ├── [★] TodoItem.cs
◆ TodoItemクラス追加

まずはTodoアイテムのクラスを追加します。

TodoItem.cs

public class TodoItem
{
    public string Content {get; set;}
    public bool IsDone {get; set;}
}
◆ Viewと処理を分けてファイルを追加

次に画面と処理ですが、コードが長くなってしまうのでrazorファイルにはViewのみとし、処理はpartialクラスにしてTodo.csと、ファイルを2つに分けて追加します。

Todo.razor

@page "/todo"

<h1>Todo</h1>

・・・

Todo.cs

namespace BlazorWasmSample.Pages
{
    public partial class Todo
    {
        ・・・
    }
}
◆ 入力したTodoアイテムを追加

Todoを入力してEnterでどんどん追加していくようにします。
※現状、Enterを2回押さないとリストに追加されないのでまた時間ある時にデバッグして調べてみます。。。

Todo.razor

<input style="width: 100%" placeholder="What needs to be done?" @bind="newItem" @onkeydown="@Enter" />

Todo.cs

// Todoアイテム全て
private List<TodoItem> allTodos = new List<TodoItem>();
// 追加するアイテム
private string newItem;
// 表示用のTodoアイテム
private List<TodoItem> todosForDisplay = new List<TodoItem>();
// 現在の表示状態
private State currentState;
// 表示状態
private enum State
{
    All,
    Active,
    Completed,
}

/// <summary>
/// アイテムを追加
/// </summary>
private void AddItem() {
    if (!string.IsNullOrWhiteSpace(newItem))
    {
        allTodos.Add(new TodoItem() { Content = newItem, });
        this.ShowTodo();
        newItem = string.Empty;
    }
}

/// <summary>
/// Todoアイテムを表示
/// </summary>
private void ShowTodo()
{
    switch (this.currentState)
    {
        case State.All:
            todosForDisplay = allTodos;
            break;
        case State.Active:
            todosForDisplay = allTodos.Where(x => !x.IsDone).ToList();
            break;
        case State.Completed:
            todosForDisplay = allTodos.Where(x => x.IsDone).ToList();
            break;
    }
}

/// <summary>
/// Enterキーイベント
/// </summary>
/// <param name="e">イベントデータ</param>
private void Enter(KeyboardEventArgs e)
{
    Console.WriteLine($"KeyboardEventArgs : Code[{e.Code}] Key[{e.Key}]");
    if (e.Key == "Enter")
    {
        this.AddItem();
    }
}
◆ Todoリスト表示

追加したアイテムは下記のように表示します。 TodoItem.IsDoneをCheckBoxに、TodoItem.ContentをTextBoxにバインドしてます。

Todo.razor

<ul>
    @foreach (var item in todosForDisplay)
    {
        <li>
            <input type="checkbox" @bind="item.IsDone" />
            <input @bind="item.Content"/>
        </li>
    }
</ul>
◆ Todoアイテムのチェック変更

追加したアイテムのCheckをONにすると取消線を入れ文字色をグレーに、OFFにすると黒に戻すようスタイルと処理を追加します。

Todo.razor

<ul>
    @foreach (var item in todosForDisplay)
    {
        <li>
            <input type="checkbox" @bind="item.IsDone" />
            <input @bind="item.Content" style="color: @GetTextStyles(item).foreColor; text-decoration: @GetTextStyles(item).decoration"/>
        </li>
    }
</ul>

色と装飾をTupleで返します。

Todo.cs

/// <summary>
/// Todoアイテムのテキストスタイルを取得
/// </summary>
/// <param name="item">Todoアイテム</param>
/// <returns>文字色と取消線を付けるかどうかのセット</returns>
private (string foreColor, string decoration) GetTextStyles(TodoItem item)
{
    return item.IsDone ? ("lightgray", "line-through") : ("black", "none");
}
◆ 未完了アイテムの残数表示

未完了のActiveなTodoItemのカウントを左下に表示します。View側に直接LINQでバインドしちゃいます。

Todo.razor

@allTodos.Count(x => !x.IsDone) items left
◆ 表示内容の切り替え

全て / 未完了 / 完了と表示を切り替えるボタンを追加し、メソッドをView側でバインドする。

Todo.razor

<button @onclick="ShowAll">All</button>
<button @onclick="ShowActive">Active</button>
<button @onclick="ShowCompleted">Completed</button>

Todo.cs

/// <summary>
/// Todoアイテム全て表示
/// </summary>
private void ShowAll() {
    currentState = State.All;
    this.ShowTodo();
}

/// <summary>
/// Todo未完了アイテム表示
/// </summary>
private void ShowActive() {
    currentState = State.Active;
    this.ShowTodo();
}

/// <summary>
/// Todo完了アイテム表示
/// </summary>
private void ShowCompleted() {
    currentState = State.Completed;
    this.ShowTodo();>
}
◆ 完了アイテムのクリア

完了アイテムが一つ以上ある場合はClear completedボタンを表示するようにし、 クリックで完了アイテムをメモリから削除する。

Todo.razor

<button @onclick="ClearCompleted" style="display: @GetDisplay()">Clear completed</button>

Todo.cs

/// <summary>
/// Todo完了アイテムをクリア
/// </summary>
private void ClearCompleted()
{
    var completedTodos = allTodos.Where(x => x.IsDone);
    allTodos = allTodos.Except(completedTodos).ToList();
    this.ShowTodo();
}

/// <summary>
/// ClearCompletedボタン表示スタイルを取得
/// </summary>
/// <returns>表示スタイル [inline-block / none]</returns>
private string GetDisplay()
{
    return allTodos.Any(x => x.IsDone) ? "inline-block" : "none";
}
◆ メニューへTodoページを追加

最後に、Todo.razorで指定した @page "/todo" へのリンクをメニューに追加します。

NavMenu.razor

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="counter">
                <span class="oi oi-plus" aria-hidden="true"></span> Counter
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="fetchdata">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
            </NavLink>
        </li>
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="todo">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Todo
            </NavLink>
        </li>
    </ul>
</div>

さいごに

記事の内容は長くなってしまいましたが、思ってたよりもスッキリとコードが書けるのでサクっと作れてしまいました。 ただブラウザにランタイムや.NETアセンブリをダウンロードして実行するので機能の多いアプリにしてしまうとダウンロードに時間がかかってしまうようです。 それでも手軽にSPAをC#で作れちゃうってなかなかイイですね。

今回追加したTodoはスタイルとか特にセットしてないので味気ない感じになってますが MatBlazorのようなマテリアルデザインのUIフレームワークもあり 面白そうなので近々使ってみようと思います。

以上、もりもりでした。

2020年9月23日水曜日

VSCode + Python + Flask + Docker で環境構築 #03. 運用環境を構築してみる

どうも、最近うちの娘(3歳)が「アレクサ、テレビ付けて」と
リモコンを使わなくなったことに一抹の不安を覚える
もりもりです。

今回はFlaskアプリやサービスを作って公開する場合の運用環境についてです。

#01. Flaskアプリをdocker上で動かしてみる
#02. vscodeのRemote Developmentでデバッグしてみる
今回はこちら → #03. 運用環境を構築してみる

まずは

第1回、第2回で作ったコンテナをそのままどこかのクラウドサービスへ
デプロイしたらダメなの?というところですが
公式ドキュメントでは以下のように書かれています。

When running publicly rather than in development,
you should not use the built-in development server (``flask run``).
The development server is provided by Werkzeug for convenience,
but is not designed to be particularly efficient, stable, or secure.

Instead, use a production WSGI server.

ということのようです。
flask runで実行した開発サーバーを本番環境で使用するべきではないと。
効率性、安定性、セキュリティを意識して設計してはいないよと。

代わりに本番環境ではWSGIサーバーを使ってねと。

てなわけで、WebサーバーとAppサーバーを用意し
WebサーバーとFlaskを繋ぐインターフェース
WSGI (Web Server Gateway Interface) を利用して
通信する環境をコンテナで作成していきます。

今回使用するWSGIサーバーはuWSGIです。
Flask + Docker + Nginx + uWSGI で環境を作っていきたいと思います。

ちなみにWSGIの読み方は「ウィズギー」だそうです。

ディレクトリ構成


flask-product
  ├── app
  │ ├── Dockerfile
  │ ├── requirements.txt
  │ ├── run.py
  │ └── uwsgi.ini
  ├── web
  │ ├── Dockerfile
  │ └── nginx.conf
  └── docker-compose.yml

ソースコードはGithubにあります。


app/Dockerfile


WORKDIRを変更し、CMDを追加します。

# base image
FROM python:3.8.5

ARG project_dir=/var/www/

# workdir にファイル等追加
COPY requirements.txt $project_dir

# workdir
WORKDIR $project_dir

# upgrade pip
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt

CMD ["uwsgi","--ini","/var/www/uwsgi.ini"]

追加したCMDですが、 docker-compose.ymlに下記を追加しても問題ないと思います。(また試しときます。)
command: uwsgi --ini /var/www/uwsgi.ini

app/equirements.txt & run.py


uwsgiをインストールするので追加します。
Flask
uwsgi

app/uwsgi.ini


uWSGIの設定ファイルです。
[uwsgi]
wsgi-file = run.py
callable = app
master = true
processes = 1
socket = :3031

web/Dockerfile


公式イメージをベースとします。
# base image
FROM nginx:latest

CMD ["nginx", "-g", "daemon off;", "-c", "/etc/nginx/nginx.conf"]

web/nginx.conf


Nginxの設定ファイルです。
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    upstream uwsgi {
        server app-server:3031;
    }

    server {
        listen 80;
        charset utf-8;

        location / {
            include uwsgi_params;
            uwsgi_pass uwsgi;
        }

    }
}

31行目のホスト名にはdocker-compose.ymlで指定したapp側のホスト名を指定します。

docker-compose.yml


コンテナをapp-serverとweb-serverの2つに分けます。
ホスト名も忘れずに設定しておきます。
version: "3"

services:
    app:
        container_name: app-server
        hostname: app-server
        build: ./app
        volumes:
            - "./app:/var/www/"
        ports:
            - "3031:3031"
        environment:
            TZ: Asia/Tokyo
  
    web:
        container_name: web-server
        hostname: web-server
        build: ./web
        volumes:
            - "./web/nginx.conf:/etc/nginx/nginx.conf"
            # nginxのログをホストOS側に出力
            - "/tmp/nginx_log:/var/log/nginx"
        links:
            - app
        ports:
            - "4231:80"
        environment:
            TZ: Asia/Tokyo

コンテナを起動して動作確認


$ docker-compose up -d

コンテナが起動すればブラウザから下記にアクセスするだけです。

http://localhost:4231


はい、運用環境用のコンテナができました。
あとはNginxやuWSGIの設定を本番用にちゃんと設定してから
どこかのクラウドサービスへデプロイしてあげればよさそうですね。



以上、もりもりでした。

2020年9月13日日曜日

VSCode + Python + Flask + Docker で環境構築 #02. vscodeのRemote Developmentでデバッグしてみる

どうも、もりもりです。

今回はPython + Flaskの開発環境をDocker上に持っていき
コンテナ上にあるソースをvscodeでデバッグしてみます。

#01. Flaskアプリをdocker上で動かしてみる
今回はこちら → #02. vscodeのRemote Developmentでデバッグしてみる
#03. 運用環境を構築してみる

拡張機能「Remote Development」をインストール


まずは拡張機能をインストールします。


Extension Packとなっており、インストールすると下記の3つがインストールされます。

・Remote - WSL
・Remote - Containers
・Remote - SSH

今回はコンテナ上のソースをデバッグするので「Remote - Containers」を使用。

ディレクトリ構成


flask-dev
  ├── .devcontainer
  │ └── devcontainer.json
  ├── .vscode
  │ └── launch.json
  ├── docker-compose.yml
  ├── Dockerfile
  ├── requirements.txt
  └── run.py

ソースコードはGithubにあります。


Dockerfile


前回と違い、今回はproject_dirは宣言するだけで、値を指定しません。

# base image
FROM python:3.8.5

ARG project_dir

# workdir にファイル等追加
ADD requirements.txt $project_dir

# workdir
# なければ新規作成
WORKDIR $project_dir

# upgrade pip
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

docker-compose.yml


project_dirをここで設定します。
volumesで作業場にマウントします。

version: '3'

services:
    web:
        container_name: dev_flask
        build:
            context: .
            args:
                project_dir: "/work/"
        ports:
            - "5000:5000"
        volumes:
            - ".:/work"
        environment:
            TZ: Asia/Tokyo
            FLASK_ENV: "development"
        command: "sleep infinity"

requirements.txt & run.py


前回のファイルそのままです。

devcontainer.json を追加


ウィンドウ左下の赤枠をクリックし、
「Remote-container: Add Development Container Configuration Files...」を選択
docker-compose.ymlから設定ファイルを作成するため
「From 'docker-compose.yml'」を選択
これでdevcontainer.jsonが作成されるので編集します。
dockerComposeFileにyamlファイルが2つ指定されていますが、
一つ上の階層にあるファイルのみ使用するため、
設定ファイルと同階層にあるdocker-compose.ymlは削除します。

{
    "name": "RemoteDevFlask",
    "dockerComposeFile": [
        "../docker-compose.yml",
        // "docker-compose.yml"
    ],
    "service": "web",
    "workspaceFolder": "/work",
    "settings": {
        "terminal.integrated.shell.linux": "/bin/bash"
    },
    "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance"
    ]
}

また、vscodeでPythonの開発するために必要な拡張機能を
コンテナにインストールするため、extensionsにPython関連の拡張機能を指定します。
指定する値は下記の赤枠のように、拡張機能名の右に表示されているIDです。

コンテナを開く


再度ウィンドウ左下にある赤枠部分をクリックし、
「Remote-Containers: Reopen in Container」を選択します。
無事にコンテナ上のProjectDir「work」を開くことができました。
vscodeの拡張機能を確認すると、コンテナ上には下記二つがインストールされていることがわかります。
(アイコン右下にリモートだと認識できるマークが付いている)
インストールされていないようであれば、通常と同様にコンテナに対して
画面から拡張機能をインストールすることが可能です。

デバッグ用設定ファイルを作成


vscodeのデバッグメニューを選択すると、まだデバッグするための設定ファイルがないため
下記のような表示になっています。
※ run.pyを開いた状態でデバッグメニューを選択する必要あり。

まずはlaunch.jsonを作成します。
今回はFlaskアプリのため「Flask」を選択
「run.py」を入力


ソースコードの任意の場所にブレークポイントをはり
いざデバッグ実行。
無事にデバッグできるようになりました。

開発環境をDocker化してしまえば、以下のようなメリットがありますね。
・自分のPCに無駄なものをインストールする必要がない
・メンバー全員が同じ環境で開発できる
・環境構築の手間が省ける
・運用環境と同じ環境でデバッグができる

ただイイことばかりではなく、WindowsPCだとDocker環境の構築が少しややこしそう?
Windows10のバージョン2004からはWSL2(Windows subsystem for linux 2)のおかげで
Hyper-VなしでもLinuxコンテナを動かせるようになったとか?
まだ2004にアップデートしてないのでアップデートしたら試してみようと思います。


以上、もりもりでした。

2020年9月8日火曜日

VSCode + Python + Flask + Docker で環境構築 #01 : Flaskアプリをdocker上で動かしてみる

どうも、もりもりです。

最近Dockerとか触ってみてるので開発環境作ったり運用環境を作ったりといったところで
連載したいと思います。

こんな感じで。

今回はこちら → #01. Flaskアプリをdocker上で動かしてみる
#02. vscodeのRemote Developmentでデバッグしてみる
#03. 運用環境を構築してみる

まずはDocker上にPythonやらFlaskやらをインストールし、
ソースを置いて実行してホストPCからアクセスしてみる。

環境


・ macOS Catalina 10.15.6
・ VSCode 1.48
・ Docker 19.03.12
・ Docker Compose 1.26.2

ディレクトリ構成


flask_hello_world
  ├── docker-compose.yml
  ├── Dockerfile
  ├── requirements.txt
  └── run.py

ソースコードはGithubにあげてます。



Dockerfile


Python公式のイメージからDockerイメージを作成します。
# base image
FROM python:3.8.5

ARG project_dir=/work/

# workdir にファイル等追加
ADD run.py $project_dir
ADD requirements.txt $project_dir

# workdir
# なければ新規作成
WORKDIR $project_dir

# upgrade pip
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

# port
EXPOSE 5000

ENV PYTHONPATH "${PYTHONPATH}:/code/"
ENV FLASK_APP "/run.py"

docker-compose.yml


こちらはDockerイメージのビルド情報やコンテナ起動時の情報などを
定義するファイルです。

version: '3'

services:
    web:
        container_name: hello_flask
        build: .
        ports:
            - "5000:5000"
        tty: true
        environment:
            TZ: Asia/Tokyo
        command: flask run --host 0.0.0.0 --port 5000

requirements.txt


インストールしたいパッケージやバージョンを指定します。
flask

# バージョンまで指定する場合
# flask == 1.1.2

pip freeze で現在の環境にインストールされたパッケージと
バージョンを確認することができます。
よって下記を実行してそのままファイルへ書き出し。

$ pip freeze > requirements.txt

run.py


from flask import Flask

app = Flask(__name__)

@app.route("/")
def index():
    return "Hello Flask!"

@app.route("/hello/<name>")
def hello_someone(name):
    return "Hello " + name + " !"

コンテナを起動

下記コマンドでコンテナを起動します。
$ docker-compose up -d

動作確認


コンテナが起動すればブラウザから下記にアクセスするだけです。

http://localhost:5000

http://localhost:5000/hello/{name}
※ {name} の部分はご自由に置き換えてください。

コンテナを停止

コンテナを停止する際は下記コマンドを実行してください。
コンテナの起動や停止はDocker Desktopから行ってもOKです。
$ docker-compose stop


うん、とりあえず動きましたね。

次回は開発環境としてソースなどをコンテナにのせて
デバッグ実行できるようにしたいと思います。


以上、もりもりでした。

2020年7月6日月曜日

vscode #03 : 便利機能

こんばんは、もりもりです。

vscodeの便利機能 第三弾です。

今回は下記の拡張機能です。

vscodeでクラスやメソッドなどにコメントを書く際に便利な拡張機能です。

普段は仕事でVisualStudioを使用しているのですが
当たり前のように使っている機能で
vscodeにはデフォルトではない機能なんですねぇ。えぇ。
インストールするとこんな感じです。


「///」と入力するとコメントの雛形を作成してくれます。
サポートされてる言語は「C、C++、C#」ですが
Javaでも使用できました。
「/**」と入力するとJavadoc用のコメントとして雛形を作成してくれます。

地味かもですが非常にありがたい機能です。
vscodeでCやC#、Javaなどのコードを書くことがあればぜひお使いください!!!

過去のvscode便利機能はこちらを↓↓↓

以上、もりもりでした。