Amazon Linux 2でHeadless Chromeを動かす
Tags: amazonlinux2
Published: 2018-01-10 06:30:22

---
title: Amazon Linux 2でHeadless Chromeを動かす
published: true
description: Amazon Linuxでは、GUI向けのパッケージが提供されておらず、Headless Chromeを動かすに大変な手間が必要でした。 Amazon Linux 2になり、GUI向けのパッケージが提供され、Red Hat Enterprise Linux 7.4とほとんど変わらない手順でHeadless Chromeを動かせるようになりました。
tags: Amazon Linux 2
---


Amazon Linuxでは、GUI向けのパッケージが提供されていませんでした。Headless Chromeはlibgtk3に依存しており、Amazon Linuxにlibgtk3をインストールするのに大変な手間が必要でした。 Amazon Linux 2になり、GUI向けのパッケージが提供され、Red Hat Enterprise Linux 7.4とほとんど変わらない手順でHeadless Chromeを動かせるようになりました。

Amazon Linux 2にHeadless Chromeをインストールしてみましょう。

## EC2インスタンス 作成

Amazon Linux 2でAWS EC2インスタンスを作成します。

### 事前条件
[AWSコマンド](https://aws.amazon.com/jp/cli/)の設定が終わっているものとします。

- キーペア `chromium-on-amazon-linux2`
- SSH接続可能なセキュリティグループ `sg-77d46f0e`

があるとします。

## EC2インスタンス 作成


```
aws ec2 run-instances --image-id ami-2a34b64c --count 1 --instance-type t2.micro --key-name chromium-on-amazon-linux2 --security-group-ids sg-77d46f0e
{
    "Groups": [],
    "Instances": [
        {
            "AmiLaunchIndex": 0,
            "ImageId": "ami-2a34b64c",
            "InstanceId": "i-0f3efae9b9002b82e",
            "InstanceType": "t2.micro",
            "KeyName": "chromium-on-amazon-linux2",
            "LaunchTime": "2018-01-10T06:11:19.000Z",
            "Monitoring": {
                "State": "disabled"
            },
            "Placement": {
                "AvailabilityZone": "ap-northeast-1a",
                "GroupName": "",
                "Tenancy": "default"
            },
            "PrivateDnsName": "ip-172-31-6-102.ap-northeast-1.compute.internal",
            "PrivateIpAddress": "172.31.6.102",
            "ProductCodes": [],
            "PublicDnsName": "",
            "State": {
                "Code": 0,
                "Name": "pending"
            },
            "StateTransitionReason": "",
            "SubnetId": "subnet-6bca3b1c",
            "VpcId": "vpc-4c30c129",
            "Architecture": "x86_64",
            "BlockDeviceMappings": [],
            "ClientToken": "",
            "EbsOptimized": false,
            "Hypervisor": "xen",
            "NetworkInterfaces": [
                {
                    "Attachment": {
                        "AttachTime": "2018-01-10T06:11:19.000Z",
                        "AttachmentId": "eni-attach-a2db2748",
                        "DeleteOnTermination": true,
                        "DeviceIndex": 0,
                        "Status": "attaching"
                    },
                    "Description": "",
                    "Groups": [
                        {
                            "GroupName": "launch-wizard-1",
                            "GroupId": "sg-77d46f0e"
                        }
                    ],
                    "Ipv6Addresses": [],
                    "MacAddress": "06:31:39:4b:07:38",
                    "NetworkInterfaceId": "eni-e98d92d5",
                    "OwnerId": "016753510962",
                    "PrivateDnsName": "ip-172-31-6-102.ap-northeast-1.compute.internal",
                    "PrivateIpAddress": "172.31.6.102",
                    "PrivateIpAddresses": [
                        {
                            "Primary": true,
                            "PrivateDnsName": "ip-172-31-6-102.ap-northeast-1.compute.internal",
                            "PrivateIpAddress": "172.31.6.102"
                        }
                    ],
                    "SourceDestCheck": true,
                    "Status": "in-use",
                    "SubnetId": "subnet-6bca3b1c",
                    "VpcId": "vpc-4c30c129"
                }
            ],
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SecurityGroups": [
                {
                    "GroupName": "launch-wizard-1",
                    "GroupId": "sg-77d46f0e"
                }
            ],
            "SourceDestCheck": true,
            "StateReason": {
                "Code": "pending",
                "Message": "pending"
            },
            "VirtualizationType": "hvm"
        }
    ],
    "OwnerId": "016753510962",
    "ReservationId": "r-0d34db4dcac25c65f"
}
```

次に生成されたEC2インスタンスにSSHでログインします。


### SSH ログイン
PublicIpAddressはEC2インスタンス生成と同時には取得できません。
`InstanceId`の値を使って、PublicIpAddressを取得します。

```
aws ec2 describe-instances --instance-ids i-0f3efae9b9002b82e
{
    "Reservations": [
        {
            "Groups": [],
            "Instances": [
                {
                    "AmiLaunchIndex": 0,
                    "ImageId": "ami-2a34b64c",
                    "InstanceId": "i-0f3efae9b9002b82e",
                    "InstanceType": "t2.micro",
                    "KeyName": "chromium-on-amazon-linux2",
                    "LaunchTime": "2018-01-10T06:11:19.000Z",
                    "Monitoring": {
                        "State": "disabled"
                    },
                    "Placement": {
                        "AvailabilityZone": "ap-northeast-1a",
                        "GroupName": "",
                        "Tenancy": "default"
                    },
                    "PrivateDnsName": "ip-172-31-6-102.ap-northeast-1.compute.internal",
                    "PrivateIpAddress": "172.31.6.102",
                    "ProductCodes": [],
                    "PublicDnsName": "ec2-13-230-156-244.ap-northeast-1.compute.amazonaws.com",
                    "PublicIpAddress": "13.230.156.244",
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    },
                    "StateTransitionReason": "",
                    "SubnetId": "subnet-6bca3b1c",
                    "VpcId": "vpc-4c30c129",
                    "Architecture": "x86_64",
                    "BlockDeviceMappings": [
                        {
                            "DeviceName": "/dev/xvda",
                            "Ebs": {
                                "AttachTime": "2018-01-10T06:11:20.000Z",
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-068a21bf8110a0b90"
                            }
                        }
                    ],
                    "ClientToken": "",
                    "EbsOptimized": false,
                    "EnaSupport": true,
                    "Hypervisor": "xen",
                    "NetworkInterfaces": [
                        {
                            "Association": {
                                "IpOwnerId": "amazon",
                                "PublicDnsName": "ec2-13-230-156-244.ap-northeast-1.compute.amazonaws.com",
                                "PublicIp": "13.230.156.244"
                            },
                            "Attachment": {
                                "AttachTime": "2018-01-10T06:11:19.000Z",
                                "AttachmentId": "eni-attach-a2db2748",
                                "DeleteOnTermination": true,
                                "DeviceIndex": 0,
                                "Status": "attached"
                            },
                            "Description": "",
                            "Groups": [
                                {
                                    "GroupName": "launch-wizard-1",
                                    "GroupId": "sg-77d46f0e"
                                }
                            ],
                            "Ipv6Addresses": [],
                            "MacAddress": "06:31:39:4b:07:38",
                            "NetworkInterfaceId": "eni-e98d92d5",
                            "OwnerId": "016753510962",
                            "PrivateDnsName": "ip-172-31-6-102.ap-northeast-1.compute.internal",
                            "PrivateIpAddress": "172.31.6.102",
                            "PrivateIpAddresses": [
                                {
                                    "Association": {
                                        "IpOwnerId": "amazon",
                                        "PublicDnsName": "ec2-13-230-156-244.ap-northeast-1.compute.amazonaws.com",
                                        "PublicIp": "13.230.156.244"
                                    },
                                    "Primary": true,
                                    "PrivateDnsName": "ip-172-31-6-102.ap-northeast-1.compute.internal",
                                    "PrivateIpAddress": "172.31.6.102"
                                }
                            ],
                            "SourceDestCheck": true,
                            "Status": "in-use",
                            "SubnetId": "subnet-6bca3b1c",
                            "VpcId": "vpc-4c30c129"
                        }
                    ],
                    "RootDeviceName": "/dev/xvda",
                    "RootDeviceType": "ebs",
                    "SecurityGroups": [
                        {
                            "GroupName": "launch-wizard-1",
                            "GroupId": "sg-77d46f0e"
                        }
                    ],
                    "SourceDestCheck": true,
                    "VirtualizationType": "hvm"
                }
            ],
            "OwnerId": "016753510962",
            "ReservationId": "r-0d34db4dcac25c65f"
        }
    ]
}
```


```fish
ssh -i chromium-on-amazon-linux2.pem ec2-user@13.230.156.244
```


## 依存パッケージインストール

yumパッケージを更新します。

```
sudo yum update -y
```

Chromiumが依存するパッケージをインストールします。

```
sudo yum install pango.x86_64 libXcomposite.x86_64 libXcursor.x86_64 libXdamage.x86_64 libXext.x86_64 libXi.x86_64 libXtst.x86_64 cups-libs.x86_64 libXScrnSaver.x86_64 libXrandr.x86_64 GConf2.x86_64 alsa-lib.x86_64 atk.x86_64 gtk3.x86_64 ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc -y

```

この部分が今までのAmazon Linuxで実現しようとすると、大変な手間が掛かっていました。Amazon Linux 2では設定なしで、yumコマンドでインストールできます。
参考：[Installing Google Chrome On CentOS, Amazon Linux, or RHEL](https://intoli.com/blog/installing-google-chrome-on-centos/)

## Chromiumインストール

ここから少しズルをします。
[GoogleChrome/puppeteer: Headless Chrome Node API](https://github.com/GoogleChrome/puppeteer)はインストール時に、自動的にChromiumのバイナリをダウンロードします。
これを使います。

### Node.jsインストール

```
curl --silent --location https://rpm.nodesource.com/setup_8.x | sudo bash -
sudo yum -y install nodejs
```

### puppeteerインストール

```
npm init -y
npm i puppeteer
```

## 動作確認

次の内容のindex.jsを作ります。

```js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://example.com');

  // Get the "viewport" of the page, as reported by the page.
  const dimensions = await page.evaluate(() => {
    return {
      width: document.documentElement.clientWidth,
      height: document.documentElement.clientHeight,
      deviceScaleFactor: window.devicePixelRatio
    };
  });

  console.log('Dimensions:', dimensions);

  await browser.close();
})();
```

```
node .
```

で、実行します。


```
Dimensions: { width: 800, height: 600, deviceScaleFactor: 1 }
```

が表示されれば成功です！！

## 後始末

使い終わったEC2インスタンスを削除します。

```
aws ec2 terminate-instances --instance-ids i-0f3efae9b9002b82e
```