docker compose에서phoenix 프로그램을 시작하기 전에

제목과 같이, 이것은 docker compose를 이용하여phoenix 프로그램을 시작하기 전의 비망록입니다.
시작하기 전의 절차를 반드시 잊어버릴 것 같아서 이 글을 썼을 때 기억도 고정시킬 수 있었다.
최소한이지만 vscode의remote-containers 설정 파일도 실었습니다.
"거기가 틀렸어"혹은 "이게 낫겠다"같은 게 있으면 알려주세요.

컨디션

  • mac OS
  • Docker Desctop for Mac
  • vscode
  • 제작 용기

  • phoenix
  • postgresql
  • 디렉토리 구조


    Docker file 예.docker-config 디렉터리에 모아 놓으세요.
    .env는 docker-compose입니다.yml에 사용된 환경 변수 등을 써야 하지만 vscode에서 사용할 때 "COMPOSE PROJECT NAME에 기록된.env 파일을 프로젝트의 루트 디렉터리 바로 아래에 설정하십시오"라는 말에 프로젝트의 루트 디렉터리에 저장됩니다.
    https://code.visualstudio.com/remote/advancedcontainers/set-docker-compose-project-name
    그 때문에env와 같은 층의 docker-compose에 놓아야 합니다.yml도 프로젝트의 루트 디렉터리에 있습니다.

    파일 설정


    Docker file 사용


    .docker-config/app/Dockerfile
    ├── .devcontainer
    │   └── devcontainer.json  <- vscode用docker設定ファイル
    │
    ├── .docker-config  // dockerfileを置くディレクトリ
    │   ├── app
    │   │   └── Dockerfile
    │   └── db
    │       └── Dockerfile
    ├── db
    │   └── data  // DBマウント用のディレクトリ
    │
    ├── .env  <- docker-composeで使う環境変数
    │
    └── docker-compose.yml
    
    설치RUN apt-get...에 필요할 수 있습니다.RUN mix do...에서 포엔식스와 관련된 라이브러리를 업데이트합니다.

    DB 서버용 Docker file


    .docker-confifg/db/Dockerfile
    FROM elixir:1.13.1-slim
    
    WORKDIR /workspace
    
    RUN apt-get update && apt-get install -y \
        inotify-tools \
        git \
        npm \
        && apt-get clean \
        && rm -rf /var/lib/apt/lists/*
    
    RUN mix do \
        local.hex --force, \
        local.rebar --force, \
        archive.install --force hex phx_new
    

    docker-compose.yml 및.env 파일


    docker-compose.yml
    FROM postgres:14.1-alpine
    
    ENV LANG ja_JP.utf8
    
    간략한 설명app, db: 서비스 이름(임의의 이름)build: Docker file을 배치할 디렉토리 지정(context)ports: {호스트 측 포트}: {컨테이너 측 포트}command: 컨테이너를 시작할 때 기본 명령volumes: 대부분 호스트 측과 용기 측을 마운트하는 데 사용되는 디렉터리
    build와volumes로 지정한 경로는 docker-compose입니다.yml 기준의 상대 경로입니다.
    node_modules 설치를 피하기 위해volumes를 따로 지정했습니다.node_modules:/workspace/assets/node_modules 섹션
    .env
    version: "3"
    
    services:
      app:
        build: ./.docker-config/app
        ports:
          - ${APP_PORT}:4000
        command: mix phx.server
        volumes:
          - .:/workspace
          - node_modules:/workspace/assets/node_modules
    
      db:
        build: ./.docker-config/db
        environment:
          - POSTGRES_USER=${POSTGRES_USER}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
        ports:
          - ${POSTGRES_PORT}:5432
        volumes:
          - ./db/data:/var/lib/postgresql/data
    
    volumes:
      node_modules:
    
    컨테이너 이름이 쉽게 이해되므로 COMPOSEPROJECT_네임을 잘 정의해 보겠습니다.
    (컨테이너 이름: {COMPOSE PROJECT NAME} 서비스 이름} {번호})
    docker-compose.yml 내containername 설정을 통해 용기 이름을 직접 지정할 수도 있습니다.

    devcontainer.json


    .devcontainer/devcontainer.json
    COMPOSE_PROJECT_NAME=phx_docker_sample
    
    APP_PORT=4000
    
    POSTGRES_USER=postgres
    POSTGRES_PASSWORD=postgres
    POSTGRES_PORT=5432
    

    실행 절차


    각종 설정 파일을 작성한 후
    프로젝트 만들기 -> 파일 약간 편집 -> DB-> 서버 시작
    의 흐름으로 전진한다.

    0. 동작 확인


    우선 각 컨테이너의 작동 여부를 확인한다.
    {
        // vscode上での表示名
        "name": "phoenix app",
        // devcontainer.jsonから見たときのdocker-compose.ymlの場所
        "dockerComposeFile": "../docker-compose.yml",
        // docker-compose.ymlで指定したサービス名
        "service": "app",
        // vs codeで開くディレクトリ
        "workspaceFolder": "/workspace",
    }
    
    > docker compose run --rm app mix --version
    ...
    Erlang/OTP 24 [erts-12.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]
    
    Mix 1.13.1 (compiled with Erlang/OTP 24)
    

    1. 프로젝트 제작


    확인되면 아이템 만들기.이번에 myapp라는 앱 이름으로 만들었어요.(사실이라면 COMPOSE PROJECT NAME과 이름이 같아야 함)
    > docker compose run --rm db psql --version
    psql (PostgreSQL) 14.1
    
    yes/no를 물었기 때문에 yes로 대답합니다.

    프로젝트를 만들 때 디렉터리 구조


    > docker compose run --rm app mix phx.new . --app myapp
    

    2. 파일 편집


    2.1. IP 주소 설정


    config/dev.exs를 먼저 편집합니다.
    기본적으로 http: [ip: {127, 0, 0, 1}, port: 4000] docker를 통해 연결할 수 있도록 http: [ip: {0, 0, 0, 0}, port: 4000] 변경합니다.
    config/dev.exs
    .
    ├── .devcontainer
    ├── .docker-config
    ├── .env
    ├── .formatter.exs
    ├── .gitignore
    ├── README.md
    ├── _build
    ├── assets
    ├── config
    ├── db
    ├── deps
    ├── docker-compose.yml
    ├── lib
    ├── mix.exs
    ├── mix.lock
    ├── priv
    └── test
    

    2.2. DB 구성


    config/dev.exs 내의 DB 연결 정보를 편집합니다.
    config/dev.exs
    ...
    config :mayapp, MyappWeb.Endpoint,
      # Binding to loopback ipv4 address prevents access from other machines.
      # Change to `ip: {0, 0, 0, 0}` to allow access from other machines.
      http: [ip: {0, 0, 0, 0}, port: 4000],
      check_origin: false,
      code_reloader: true,
    ...
    
    usename과password는 docker-compose입니다.yml 부분에서 설정한 것을 선택하십시오.
    hostname에서db의 용기 이름을 설정하십시오.
    설정이 잘 되면 서비스 이름("db")도 상관없지만, 자신의 환경에서 컨테이너 이름을 사용하지 않으면 연결할 수 없습니다. ->서비스 이름도 연결되어 있으니 아래에 소개해 드리겠습니다.
    hostname에 대해 여기서 토론합니다.
    https://elixirforum.com/t/docker-container-cannot-access-postgres/34489

    3. DB 만들기


    hostname을 컨테이너 이름으로 설정할 때
    ...
    config :myapp, Myapp.Repo,
      username: "postgres", # 編集 (POSTGRES_USER)
      password: "postgres", # 編集 (POSTGRES_PASSWORD)
      hostname: "phx_docker_sample_db_1", # 編集 (コンテナ名)
      database: "myapp_dev",
      show_sensitive_data_on_connection_error: true,
      pool_size: 10
      ...
    

    4. 시작


    > docker compose run --rm mix ecto.create
    
    자세히 보는 화면이 나오면 성공.🎊

    VScode에서 작업할 때


    먼저 가동된 컨테이너를 삭제한다.
    > docker compose up -d
    
    vscode로 항목을 열면 Reopen in Container?가 물어보기 때문에 선택합니다.또는 왼쪽 아래><에 겹쳐진 태그의 버튼을 눌러 선택Reopen in Container합니다.
    그러면 docker compose up을 실행한 상태로 app 용기에 넣습니다.

    이때, devcontainer.json에 쓰기 설정이 거의 없기 때문에 용기 안에 ElixirLS 등 확장 기능이 없어서 확장 기능의 은혜를 받을 수 없습니다.따라서 옆에 있는 탭의 확장 기능 중 하나를 선택하여 자신이 사용하고 싶은 확장 기능을 넣으세요.
    상세한 상황은 정부 자료를 참고하시오.
    https://code.visualstudio.com/docs/remote/devcontainerjson-reference
    extenstions와settings를 설정하면 편리합니다.
    참고로 지금은 vscode의remote containers 기능을 사용할 수 있는 시기입니다. docker compose run mix phx.new ... 제작 프로젝트 이후입니다.(프로젝트를 만들지 않으면 docker-composie.yml에서 설정한 명령을 실행할 수 없음mix phx.server프로젝트를 제작하는 단계에서remote containers를 시작하여 mix ecto.create 등의 작업을 진행하는 것이 비교적 수월할 수 있습니다.

    추기 1hostname을 서비스 이름으로 사용할 때

    docker compose up 컨테이너를 가동한 상태에 따라localhost를 서비스명("db")으로 설정한 상태도 통과되었다.
    config/dev.exs
    > docker compose down
    
    ...
    config :myapp, Myapp.Repo,
      username: "postgres",
      password: "postgres",
      hostname: "db", # 変更
      database: "myapp_dev",
      ...
    

    추기 2docker compoose 명령을 사용하지 않으려는 사람


    아마 이쪽이 비교적 편리할 것 같으니 적어 놓으세요.
    다음과 같이 docker-compose를 변경합니다.yml에 있는command를 삭제하고 tty를 진짜로 설정합니다.
    docker-compose.yml
    > docker compose up -d
    > docker compose exec app bash -c "mix ecto.create"
    Compiling 14 files (.ex)
    Generated myapp app
    The database for Myapp.Repo has already been created
    
    이렇게 하면phoenix 프로젝트가 없는 상태에서도remote-containers를 사용할 수 있습니다.
    디렉토리 구성은 Docker file, docker-compose와 같습니다.yml、.env、devcontainer.json을 썼으면 vscode로remote-containers를 시작합니다.
    그리고 컨테이너mix phx.new ... 또는 mix create.ecto에서 실행할 수 있습니다.config/dev.exs의 편집은 2입니다.파일 편집 항목과 같은 방법으로 진행하십시오.
    이럴 때 DB의hostname은 서비스 이름 ("db") 을 사용하면 됩니다.
    마지막으로 mix phx.server에 서버를 설치하여 사이트를 보면 완성됩니다.

    잡감


    docker compose에 대해서 조금 이해를 했는데 앞으로 더 적극적으로 사용하고 싶어요.

    참고 자료

  • Docker Compose를 통한 Elixir/Phoenix 개발 환경 구축
  • 다양한 개발기Phoenix도 움직일 수 있는 Docker file/docker-compose의 제작 방법
  • docker-compose로 만든 물건의 이름을 명확하게 지정하는 방법
  • 【Docker Compose】container_name이 아니라 COMPOSE입니다.PROJECT_NAME 변수를 사용하는 게 좋아요.
  • Docker Compose에서 VS Code Remote-Contaainess를 사용하십시오!
  • 좋은 웹페이지 즐겨찾기