[docker] 도커설치 방법

도커설치방법
Ubuntu, Centos, Mac, window 운영체제 별로 설치 법이 있으니 공식 문서를 참조
Install Docker Engine | Docker Documentatio

컨테이너에서 도커를 사용하고 싶을때
ubuntu 환경에서 도커를 설치한 환경을 구성해야 할때 로컬환경이 ubuntu가 아니라면 도커 컨테이너를 통해 환경을 구성할 수 있다.

  • 로컬 도커설치
    • ubuntu 컨테이너 실행
      • 컨테이너에 도커 설치

설치방법은 동일하지만 컨테이너를 실행할때 --privileged 옵션을 통해 권한을 획득한 privileged 모드로 실행 해야한다. 그렇지 않으면 service docker start 명령어를 사용해도 도커가 실행되지 않는다.

Dockerfile 작성
docker-ce 설치시 타임존 선택 옵션이 주어지는데 이미지를 빌드할때 옵션을 선택 할 수 없으므로 타임존을 미리 설정해야 한다.

FROM ubuntu:latest

ENV TZ=Asia/Seoul
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

RUN apt-get update
RUN apt-get install -y \
        ca-certificates \
        curl \
        gnupg \
        lsb-release

RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
RUN echo \
      "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
      $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null

RUN apt-get update
RUN apt-get install -y docker-ce docker-ce-cli containerd.io

이미지 빌드

docker build . -t ubuntu:docker

컨테이너 생성

docker run -it --privileged ubuntu:docker

docker demon 실행

root@~:/# service docker status
 * Docker is not running
root@~:/# service docker start
 * Starting Docker: docker   

[javascript] window.open POST 값 보내기

$(".btn").click(function(){
    var url = 'test.test/test';
    var form = $("form");
    var target = '타이틀 제목';
    window.open(url, target, "width=500,height=500,resizable=yes,toolbar=yes,menubar=yes,location=yes");

    form.attr('action', url);
    form.attr('target', target); // window.open 타이틀과 매칭 되어야함
    form.attr('method', 'post');

    form.append('<input type="text" name="mb_id" value="foo">'); // 동적으로 값을 추가할때
    form.submit();
});

[php] phpwkhtmltopdf 패키지 설치와 사용방법

PDF관련 여러 패키지 문서를 확인해 보고 간단히 테스트 해봤지만 ‘phpwkhtmltopdf’ 만한 패키지가 없는것 같다.

요구사항

phpwkhtmltopdf 패키지는 wkhtmltopdf 라이브러리를 의존 하고 있기 때문에 반드시 설치 해야한다

apt-get insall wkhtmltopdf 으로 설치하게 되면 phpwkhtmltopdf 패키지의 PDF 병합 기능을 사용 할수 없으므로 공식사이트에서 제공 하는 설치파일로 설치하는것이 좋다.

  • wkhtmltopdf 의존성 패키지 설치
apt-get update && apt-get install -y \
        libfreetype6-dev \
        libfontconfig \
        zlib1g \
        libxrender1 \
        libxext6 \
        libx11-6 \
        fontconfig \
        xfonts-75dpi \
        xfonts-base
  • wkhtmltopdf 설치
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb

dpkg -i 'wkhtmltox_0.12.6-1.buster_amd64.deb'
  • phpwkhtmltopdf 설치
composer require mikehaertl/phpwkhtmltopdf

사용방법

  • 기본사용
use mikehaertl\wkhtmlto\Pdf;

// You can pass a filename, a HTML string, an URL or an options array to the constructor
$pdf = new Pdf('/path/to/page.html');

// On some systems you may have to set the path to the wkhtmltopdf executable
// $pdf->binary = 'C:\...';

if (!$pdf->saveAs('/path/to/page.pdf')) {
    $error = $pdf->getError();
    // ... handle error here
}
  • 커버 & table of content & PDF 이어붙이기
use mikehaertl\wkhtmlto\Pdf;

$pdf = new Pdf;
$pdf->addPage('/path/to/page.html');
$pdf->addPage('<html>....</html>');
$pdf->addPage('http://www.example.com');

// Add a cover (same sources as above are possible)
$pdf->addCover('/path/to/mycover.html');

// Add a Table of contents
$pdf->addToc();

// Save the PDF
if (!$pdf->saveAs('/path/to/report.pdf')) {
    $error = $pdf->getError();
    // ... handle error here
}

// ... or send to client for inline display
if (!$pdf->send()) {
    $error = $pdf->getError();
    // ... handle error here
}

// ... or send to client as file download
if (!$pdf->send('report.pdf')) {
    $error = $pdf->getError();
    // ... handle error here
}

// ... or you can get the raw pdf as a string
$content = $pdf->toString();
  • 이미지 생성
use mikehaertl\wkhtmlto\Image;

// You can pass a filename, a HTML string, an URL or an options array to the constructor
$image = new Image('/path/to/page.html');
$image->saveAs('/path/to/page.png');

// ... or send to client for inline display
if (!$image->send()) {
    $error = $image->getError();
    // ... handle error here
}

// ... or send to client as file download
if (!$image->send('page.png')) {
    $error = $image->getError();
    // ... handle error here
}

PDF 한글이 깨지는 경우 한글 폰트를 설치하면 됨
링크 참고

apt-get install fontconfig
curl -o nanumfont.zip http://cdn.naver.com/naver/NanumFont/fontfiles/NanumFont_TTF_ALL.zip
unzip -d /usr/share/fonts/nanum nanumfont.zip
fc-cache -f -v

PDF 관련 패키지 리스트


바로 테스트하기 (도커 설치 필수)

https://github.com/jisung87kr/docker_phpwkhtmltopdf

[laravel]라라벨 서비스컨테이너

  1. 컨테이너 바인딩
    • 기본바인딩
      • 서비스컨테이너 바인딩
      • 서비스프로바이더 register() 에서 등록함
      • 일반클래스는 등록할 필요가 없으며 인터페이스 구현객체인 경우 등록해서 사용함
      • 인터페이스와 클로저를 파라미터로 전달하여 바인딩
      • 컨트롤러와 같은 클래스에서 바인딩한 인터페이스를 타입힌트로 지정하면 클로저에 정의한 구현체가 자동으로 의존성 주입됨
      • 예) PostController.php 생성자에 Transistor 인터페이스 타입힌트를 지정하면 구현체인 PodcastParser::class 주입
# AppServiceProvider.php

use App\Services\Transistor;
use App\Services\PodcastParser;

...
public function register()
{
    //
    $this->app->bind(Transistor::class, function ($app) {
        return new PodcastParser();
    });
}
...
# PostController.php

use App\Services\Transistor;
use App\Services\PodcastParser;

public function __construct(Transistor $transistor)
{
    $this->transistor = $transistor;
}

[php]php를 이용한 웹크롤링

의존성

composer.json

{
    "require": {
        "guzzlehttp/guzzle": "^7.0",
        "symfony/dom-crawler": "^5.3",
        "symfony/css-selector": "^5.3"
    }
}

요청과 응답페이지 요소탐색

use GuzzleHttp\Client;
use Symfony\Component\DomCrawler\Crawler;

$url = 'http://ujsstudio.com';
$client = new Client();
$res = $client->get($url);
$res = $res->getBody();
$html = (string)$res; // 문자열로 형변환
// dom 필터링
$crawler = new Crawler($html);
$nodeValues = $crawler->filter("#primary a")->each(function(Crawler $node, $i){
    return $node->attr('href');
});

페이지네이션 처리

use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Pool;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Symfony\Component\DomCrawler\Crawler;

$result = [];
$client = new Client();

// 페이지 조회 익명함수(제너레이터) 생성
$requests = function ($total) use ($client) {
    $uri = 'http://ujsstudio.com/page';
    for ($i = 0; $i < $total; $i++) {
        yield function() use ($client, $uri, &$i) {
            $uri = $uri.'/'.$i+1;
            return $client->getAsync($uri);
        };
    }
};

$pool = new Pool($client, $requests(10), [
        'concurrency' => 5,
        'fulfilled' => function (Response $response, $index) use (&$result) {
            $res = $response->getBody();
            $html = (string)$res;

            // 요소탐색
            $crawler = new Crawler($html);
            $nodeValues = $crawler->filter("#primary a")->each(function(Crawler $node, $i){
                return $node->attr('href');
            });

            $result[] = $nodeValues;
        },
        'rejected' => function (RequestException $reason, $index) {
            // this is delivered each failed request
        },
]);

$promise = $pool->promise();
$promise->wait();