Skip to content

Commit

Permalink
Merge pull request #326 from tighten/tm/docker-install
Browse files Browse the repository at this point in the history
Docker Install
  • Loading branch information
tonysm authored Dec 16, 2024
2 parents 713f566 + 4468c35 commit 57228d2
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 54 deletions.
55 changes: 55 additions & 0 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Docker

on:
workflow_dispatch:
inputs:
tagInput:
description: 'Tag'
required: true

release:
types: [created]
tags:
- 'v*'

jobs:
build-and-push-image:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
-
name: Checkout
uses: actions/checkout@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKER_HUB_USER }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Determine version tag
id: version-tag
run: |
INPUT_VALUE="${{ github.event.inputs.tagInput }}"
if [ -z "$INPUT_VALUE" ]; then
INPUT_VALUE="${{ github.ref_name }}"
fi
echo "::set-output name=value::$INPUT_VALUE"
-
name: Build and push
uses: docker/build-push-action@v6
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: |
tighten/takeout:latest
tighten/takeout:${{ steps.version-tag.outputs.value }}
18 changes: 18 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM php:8.1-cli-alpine

ENV TAKEOUT_CONTAINER=1

COPY --from=docker/buildx-bin /buildx /usr/libexec/docker/cli-plugins/docker-buildx

# Install the PHP extensions & Docker
RUN apk add --no-cache --update docker openrc ncurses \
&& docker-php-ext-configure pcntl --enable-pcntl \
&& docker-php-ext-install -j$(nproc) pcntl \
&& rc-update add docker boot

WORKDIR /takeout

COPY builds/takeout /usr/local/bin/takeout

ENTRYPOINT ["takeout"]

65 changes: 60 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,46 @@ But you can also easily enable ElasticSearch, PostgreSQL, MSSQL, Mongo, Redis, a
## Requirements

- macOS, Linux, Windows 10 or WSL2
- [Composer](https://getcomposer.org/) installed
- Docker installed (macOS: [Docker for Mac](https://docs.docker.com/docker-for-mac/), Windows: [Docker for Windows](https://docs.docker.com/docker-for-windows/))

If you opt for the PHP/Composer installation (not recommended), you also need:

- PHP installed (latest major version)
- Composer installed

## Installation

Install Takeout with Composer by running:
The recommended way to install Takeout is the dockerized version via an alias (add this to your `~/.bashrc`, `~/.zshrc` or equivalent).

On Linux or macOS, use:

```bash
alias takeout="docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -it tighten/takeout:latest"
```

On Windows 10, if you're using Bash, use:

```bash
alias takeout="docker run --rm -v //var/run/docker.sock:/var/run/docker.sock -it tighten/takeout:latest"
```

On Windows 10, if you're using PowerShell, use:

```bash
function takeout { docker run --rm -v //var/run/docker.sock:/var/run/docker.sock -it tighten/takeout:latest $args }
```
That's it. You may now use Takeout on your terminal. The first time you use this alias, it will pull the Takeout image from Docker Hub.
To update the image, run `docker pull tighten/takeout` when you want to get the newest release.
Otherwise, if you have a PHP environment available, you may install Takeout via Composer:
```bash
composer global require "tightenco/takeout:~2.8"
composer global require "tightenco/takeout:~2.9"
```
Make sure the `~/.composer/vendor/bin` directory is in your system's "PATH".
If you use the PHP/Composer installation, make sure you're on the latest version of PHP. We'll only support the current major version of PHP using this installation approach.
## Usage
Expand Down Expand Up @@ -274,4 +302,31 @@ If you're working with us and are assigned to push a release, here's the easiest
6. [Draft a new release](https://github.com/tighten/takeout/releases/new) with both the tag version and release title of your tag (e.g. `v1.5.1`)
7. Use the "Generate release notes" button to generate release notes from the merged PRs.
8. Hit `Publish release`
9. Profit 😆
9. The new tag and release will trigger the [`docker-publish.yml`](.github/workflows/docker-publish.yml) workflow, which should take care of building and pushing the new image of the Docker container (see the "Building The Docker Image Manually" section below)
10. Profit 😆
## Building The Docker Image Manually
The important thing is to remember to build both `linux/amd64` and `linux/arm64` images. We rely on Docker's `buildx` command, which uses Docker's [BuildKit](https://github.com/moby/buildkit) behind the scenes, which allows us to build for multiple platforms, independently of the platform of the machine building the image.
You may build and publish a new version of the docker image using the following command:
```bash
docker buildx build --platform=linux/amd64,linux/arm64 -t tighten/takeout:latest --push .
```
If it's the first time you're building the image, you may get the following error:
```
ERROR: Multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use")
```
This means that you first need to create a builder container, which you maydo like so:
```bash
docker buildx create --use
```
After that, retrying the `buildx` command should work.
Please, note that building the container will simply copy the current version of the Takeout `phar` file at [builds/takeout](./builds/takeout) to inside the container and publish that, so make sure you have to most recent version built locally. If you don't, follow the release process to build the new version before building the Docker image.
19 changes: 5 additions & 14 deletions app/Shell/DockerTags.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,18 @@ public function getLatestTag(): string
public function getTags(): Collection
{
$response = json_decode($this->getTagsResponse()->getContents(), true);

$platform = $this->platform();

return collect($response['results'])
->when(in_array($platform, $this->armArchitectures, true), $this->armSupportedImagesOnlyFilter())
->when(! in_array($platform, $this->armArchitectures, true), $this->nonArmOnlySupportImagesFilter())
->when(in_array($platform, $this->armArchitectures, true), $this->onlyArmImagesFilter())
->when(! in_array($platform, $this->armArchitectures, true), $this->onlyNonArmImagesFilter())
->pluck('name')
->sort(new VersionComparator)
->values();
}

/**
* Return a function intended to filter tags, ensuring images that do not support arm architecture are filtered out.
*
* @return callable
*/
protected function armSupportedImagesOnlyFilter()
protected function onlyArmImagesFilter()
{
return function ($tags) {
return $tags->filter(function ($tag) {
Expand All @@ -76,12 +72,7 @@ protected function armSupportedImagesOnlyFilter()
};
}

/**
* Return a function intended to filter tags, that ensures are arm-only images are filtered out.
*
* @return callable
*/
protected function nonArmOnlySupportImagesFilter()
protected function onlyNonArmImagesFilter()
{
return function ($tags) {
return $tags->filter(function ($tag) {
Expand Down
29 changes: 20 additions & 9 deletions tests/Feature/DockerTagsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,19 @@
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use Mockery as M;
use Tests\Support\IntelDockerTags;
use Tests\Support\M1DockerTags;
use Tests\Support\FakePlatformDockerTags;
use Tests\TestCase;

class DockerTagsTest extends TestCase
{
public static function armPlatforms(): array
{
return [
[FakePlatformDockerTags::M1_ARM_PLATFORM],
[FakePlatformDockerTags::LINUX_ARM_PLATFORM],
];
}

/** @test */
function it_gets_the_latest_tag_not_named_latest()
{
Expand Down Expand Up @@ -45,14 +52,17 @@ function it_sorts_the_versions_naturally()
$this->assertEquals('17.2', $tags->shift());
}

/** @test */
function it_detects_arm64_based_images_when_running_on_arm64_based_host()
/**
* @test
*
* @dataProvider armPlatforms
*/
function it_detects_arm_based_images_when_running_on_arm64_based_host($platform)
{
$handlerStack = HandlerStack::create($this->mockImagesResponseHandler());
$client = new Client(['handler' => $handlerStack]);

/** @var DockerTags $dockerTags */
$dockerTags = M::mock(M1DockerTags::class, [$client, app(MySql::class)])->makePartial();
$dockerTags = (new FakePlatformDockerTags($client, app(MySql::class)))->withFakePlatform($platform);

$this->assertEquals('1.0.0-arm64', $dockerTags->getLatestTag());
}
Expand All @@ -63,8 +73,7 @@ function it_gets_latest_tag_on_intel_platform()
$handlerStack = HandlerStack::create($this->mockImagesResponseHandler());
$client = new Client(['handler' => $handlerStack]);

/** @var DockerTags $dockerTags */
$dockerTags = M::mock(IntelDockerTags::class, [$client, app(MySql::class)])->makePartial();
$dockerTags = (new FakePlatformDockerTags($client, app(MySql::class)))->withFakePlatform(FakePlatformDockerTags::INTEL_ARM_PLATFORM);

$this->assertEquals('1.0.0', $dockerTags->getLatestTag());
}
Expand All @@ -77,20 +86,22 @@ private function mockImagesResponseHandler()
[
'name' => 'latest',
'images' => [
['architecture' => 'x86_64'],
['architecture' => 'amd64'],
['architecture' => 'arm64'],
],
],
[
'name' => '1.0.0',
'images' => [
['architecture' => 'x86_64'],
['architecture' => 'amd64'],
],
],
[
'name' => '1.0.0-arm64',
'images' => [
['architecture' => 'arm64'],
['architecture' => 'aarch64'],
],
],
],
Expand Down
26 changes: 26 additions & 0 deletions tests/Support/FakePlatformDockerTags.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Tests\Support;

use App\Shell\DockerTags;

class FakePlatformDockerTags extends DockerTags
{
const M1_ARM_PLATFORM = 'arm64';
const LINUX_ARM_PLATFORM = 'aarch64';
const INTEL_ARM_PLATFORM = 'x86_64';

protected string $fakePlatform;

public function withFakePlatform(string $platform): self
{
$this->fakePlatform = $platform;

return $this;
}

protected function platform(): string
{
return $this->fakePlatform;
}
}
13 changes: 0 additions & 13 deletions tests/Support/IntelDockerTags.php

This file was deleted.

13 changes: 0 additions & 13 deletions tests/Support/M1DockerTags.php

This file was deleted.

0 comments on commit 57228d2

Please sign in to comment.