403 error while installing Puppeteer on Ubuntu
I’ve been using Puppeteer quite a lot for OG image generation. I’ve installed it many times without any issues, but on my last attempt, I kept getting a 403 error, when trying to download Chromium. So today I will share how I made it work, even though it is more of a workaround rather than an actual solution.
Installation
Since I’m usually using Browsershot from Spatie, I just follow the instructions on their requirements page with different Puppeteer version based on what is needed.
This time, however, it kept failing on the chromium installation step.
The 403 Error
For some reason, the link that was being used https://storage.googleapis.com/chrome-for-testing-public/125.0.6422.78/linux64/chrome-headless-shell-linux64.zip
kept throwing 403 when trying to download from my droplet. While working perfectly on my local machine. I tried to find the solution for this issue, but I just needed to make it work without losing too much time on it.
Skipping the download step
The error message suggests, that you can skip the download step and to do so you can use the PUPPETEER_SKIP_DOWNLOAD
env variable. So let’s do just that:
export PUPPETEER_SKIP_DOWNLOAD=true
You can verify, that this environment variable is being used by running the printenv
command.
The root user
Now when installing Puppeteer globally, you will have to use the sudo
which will make you a root user hence the environment variable we just set is not actually present. You can verify this by running sudo printenv
. As you can see it is not set.
Using existing environment variables
To overcome this issue, we just need to use the -E
flag, which will use existing environment variables. Here is a snippet from the man command explaining the flag:
-E, --preserve-env
Indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the user does not have permission to preserve the environment.
So this is the final command to run:
sudo -E npm install --location=global --unsafe-perm puppeteer
Installing chrome
Even though we have installed Puppeteer, we still don’t have Chrome installed. So we need to download the file on our local machine, because while it was throwing 403 on the droplet, locally it works fine. Then upload it to the droplet to your preferred location and finally specify the path to Puppeteer.
Specify the path
As I mentioned before - I’m using Browsershot to interact with Puppeteer. While there are probably many ways to make this work, I chose to create .env
variable with the path to my Chrome executable and then create a new Browsershot
class which extends the default one and sets the path (if exists) in the constructor.
Now I can just use my class instead of the default one and the path is always set for me. Here is the snippet of the custom Browsershot
class:
class Browsershot extends \Spatie\Browsershot\Browsershot
{
public function __construct(string $url = '', bool $deviceEmulate = false)
{
parent::__construct($url, $deviceEmulate);
if (! empty($path = config('browsershot.executable_path'))) {
$this->setChromePath($path);
}
}
}
And that’s it. If anyone knows the real solution to this issue I would be delighted if you get in touch with me on Twitter. Thanks in advance :)
Until next time,
Tony