mirror of
https://github.com/alangrainger/immich-public-proxy.git
synced 2024-12-28 03:41:58 +00:00
Merge pull request #2 from Tarow/main
feat(ci): add docker build&publish pipeline
This commit is contained in:
commit
5698e98fcd
9 changed files with 73 additions and 290 deletions
2
.dockerignore
Normal file
2
.dockerignore
Normal file
|
@ -0,0 +1,2 @@
|
|||
node_modules/
|
||||
dist/
|
49
.github/workflows/ci.yaml
vendored
Normal file
49
.github/workflows/ci.yaml
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
name: Create and publish a Docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build-and-push-image:
|
||||
runs-on: ubuntu-latest
|
||||
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3.2.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
/node_modules/
|
||||
/dist/
|
||||
/.idea/
|
||||
.env
|
||||
/package-lock.json
|
||||
|
|
12
Dockerfile
Normal file
12
Dockerfile
Normal file
|
@ -0,0 +1,12 @@
|
|||
FROM node:20-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm install --omit=dev
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm run build
|
||||
|
||||
CMD [ "node", "dist/index.js" ]
|
104
dist/immich.js
vendored
104
dist/immich.js
vendored
File diff suppressed because one or more lines are too long
94
dist/index.js
vendored
94
dist/index.js
vendored
File diff suppressed because one or more lines are too long
63
dist/render.js
vendored
63
dist/render.js
vendored
|
@ -1,63 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const tslib_1 = require("tslib");
|
||||
const immich_1 = tslib_1.__importDefault(require("./immich"));
|
||||
const types_1 = require("./types");
|
||||
class Render {
|
||||
assetBuffer(res, asset, size) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
||||
const data = yield immich_1.default.getAssetBuffer(asset, size);
|
||||
if (data) {
|
||||
for (const header of ['content-type', 'content-length']) {
|
||||
res.set(header, data.headers[header]);
|
||||
}
|
||||
res.send(Buffer.from(yield data.arrayBuffer()));
|
||||
}
|
||||
else {
|
||||
res.status(404).send();
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Render a gallery page for a given SharedLink, using EJS and lightGallery.
|
||||
*
|
||||
* @param res - ExpressJS Response
|
||||
* @param share - Immich `shared-link` containing the assets to show in the gallery
|
||||
* @param [openItem] - Immediately open a lightbox to the Nth item when the gallery loads
|
||||
*/
|
||||
gallery(res, share, openItem) {
|
||||
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
||||
const items = [];
|
||||
for (const asset of share.assets) {
|
||||
let video;
|
||||
if (asset.type === types_1.AssetType.video) {
|
||||
// Populate the data-video property
|
||||
video = JSON.stringify({
|
||||
source: [
|
||||
{
|
||||
src: immich_1.default.videoUrl(share.key, asset.id),
|
||||
type: yield immich_1.default.getContentType(asset)
|
||||
}
|
||||
],
|
||||
attributes: {
|
||||
preload: false,
|
||||
controls: true
|
||||
}
|
||||
});
|
||||
}
|
||||
items.push({
|
||||
originalUrl: immich_1.default.photoUrl(share.key, asset.id),
|
||||
thumbnailUrl: immich_1.default.photoUrl(share.key, asset.id, types_1.ImageSize.thumbnail),
|
||||
video
|
||||
});
|
||||
}
|
||||
res.render('gallery', {
|
||||
items,
|
||||
openItem
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
const render = new Render();
|
||||
exports.default = render;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL3JlbmRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw4REFBNkI7QUFFN0IsbUNBQWlFO0FBRWpFLE1BQU0sTUFBTTtJQUNKLFdBQVcsQ0FBRSxHQUFhLEVBQUUsS0FBWSxFQUFFLElBQWdCOztZQUM5RCxNQUFNLElBQUksR0FBRyxNQUFNLGdCQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQTtZQUNyRCxJQUFJLElBQUksRUFBRSxDQUFDO2dCQUNULEtBQUssTUFBTSxNQUFNLElBQUksQ0FBQyxjQUFjLEVBQUUsZ0JBQWdCLENBQUMsRUFBRSxDQUFDO29CQUN4RCxHQUFHLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7Z0JBQ3ZDLENBQUM7Z0JBQ0QsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQTtZQUNqRCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtZQUN4QixDQUFDO1FBQ0gsQ0FBQztLQUFBO0lBRUQ7Ozs7OztPQU1HO0lBQ0csT0FBTyxDQUFFLEdBQWEsRUFBRSxLQUFpQixFQUFFLFFBQWlCOztZQUNoRSxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUE7WUFDaEIsS0FBSyxNQUFNLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ2pDLElBQUksS0FBSyxDQUFBO2dCQUNULElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxpQkFBUyxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNuQyxtQ0FBbUM7b0JBQ25DLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO3dCQUNyQixNQUFNLEVBQUU7NEJBQ047Z0NBQ0UsR0FBRyxFQUFFLGdCQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQ0FDekMsSUFBSSxFQUFFLE1BQU0sZ0JBQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDOzZCQUN6Qzt5QkFDRjt3QkFDRCxVQUFVLEVBQUU7NEJBQ1YsT0FBTyxFQUFFLEtBQUs7NEJBQ2QsUUFBUSxFQUFFLElBQUk7eUJBQ2Y7cUJBQ0YsQ0FBQyxDQUFBO2dCQUNKLENBQUM7Z0JBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQztvQkFDVCxXQUFXLEVBQUUsZ0JBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUNqRCxZQUFZLEVBQUUsZ0JBQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLGlCQUFTLENBQUMsU0FBUyxDQUFDO29CQUN2RSxLQUFLO2lCQUNOLENBQUMsQ0FBQTtZQUNKLENBQUM7WUFDRCxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRTtnQkFDcEIsS0FBSztnQkFDTCxRQUFRO2FBQ1QsQ0FBQyxDQUFBO1FBQ0osQ0FBQztLQUFBO0NBQ0Y7QUFFRCxNQUFNLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFBO0FBRTNCLGtCQUFlLE1BQU0sQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBpbW1pY2ggZnJvbSAnLi9pbW1pY2gnXG5pbXBvcnQgeyBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3Mtc2VydmUtc3RhdGljLWNvcmUnXG5pbXBvcnQgeyBBc3NldCwgQXNzZXRUeXBlLCBJbWFnZVNpemUsIFNoYXJlZExpbmsgfSBmcm9tICcuL3R5cGVzJ1xuXG5jbGFzcyBSZW5kZXIge1xuICBhc3luYyBhc3NldEJ1ZmZlciAocmVzOiBSZXNwb25zZSwgYXNzZXQ6IEFzc2V0LCBzaXplPzogSW1hZ2VTaXplKSB7XG4gICAgY29uc3QgZGF0YSA9IGF3YWl0IGltbWljaC5nZXRBc3NldEJ1ZmZlcihhc3NldCwgc2l6ZSlcbiAgICBpZiAoZGF0YSkge1xuICAgICAgZm9yIChjb25zdCBoZWFkZXIgb2YgWydjb250ZW50LXR5cGUnLCAnY29udGVudC1sZW5ndGgnXSkge1xuICAgICAgICByZXMuc2V0KGhlYWRlciwgZGF0YS5oZWFkZXJzW2hlYWRlcl0pXG4gICAgICB9XG4gICAgICByZXMuc2VuZChCdWZmZXIuZnJvbShhd2FpdCBkYXRhLmFycmF5QnVmZmVyKCkpKVxuICAgIH0gZWxzZSB7XG4gICAgICByZXMuc3RhdHVzKDQwNCkuc2VuZCgpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbmRlciBhIGdhbGxlcnkgcGFnZSBmb3IgYSBnaXZlbiBTaGFyZWRMaW5rLCB1c2luZyBFSlMgYW5kIGxpZ2h0R2FsbGVyeS5cbiAgICpcbiAgICogQHBhcmFtIHJlcyAtIEV4cHJlc3NKUyBSZXNwb25zZVxuICAgKiBAcGFyYW0gc2hhcmUgLSBJbW1pY2ggYHNoYXJlZC1saW5rYCBjb250YWluaW5nIHRoZSBhc3NldHMgdG8gc2hvdyBpbiB0aGUgZ2FsbGVyeVxuICAgKiBAcGFyYW0gW29wZW5JdGVtXSAtIEltbWVkaWF0ZWx5IG9wZW4gYSBsaWdodGJveCB0byB0aGUgTnRoIGl0ZW0gd2hlbiB0aGUgZ2FsbGVyeSBsb2Fkc1xuICAgKi9cbiAgYXN5bmMgZ2FsbGVyeSAocmVzOiBSZXNwb25zZSwgc2hhcmU6IFNoYXJlZExpbmssIG9wZW5JdGVtPzogbnVtYmVyKSB7XG4gICAgY29uc3QgaXRlbXMgPSBbXVxuICAgIGZvciAoY29uc3QgYXNzZXQgb2Ygc2hhcmUuYXNzZXRzKSB7XG4gICAgICBsZXQgdmlkZW9cbiAgICAgIGlmIChhc3NldC50eXBlID09PSBBc3NldFR5cGUudmlkZW8pIHtcbiAgICAgICAgLy8gUG9wdWxhdGUgdGhlIGRhdGEtdmlkZW8gcHJvcGVydHlcbiAgICAgICAgdmlkZW8gPSBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgICAgc291cmNlOiBbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHNyYzogaW1taWNoLnZpZGVvVXJsKHNoYXJlLmtleSwgYXNzZXQuaWQpLFxuICAgICAgICAgICAgICB0eXBlOiBhd2FpdCBpbW1pY2guZ2V0Q29udGVudFR5cGUoYXNzZXQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgXSxcbiAgICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgICBwcmVsb2FkOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbnRyb2xzOiB0cnVlXG4gICAgICAgICAgfVxuICAgICAgICB9KVxuICAgICAgfVxuICAgICAgaXRlbXMucHVzaCh7XG4gICAgICAgIG9yaWdpbmFsVXJsOiBpbW1pY2gucGhvdG9Vcmwoc2hhcmUua2V5LCBhc3NldC5pZCksXG4gICAgICAgIHRodW1ibmFpbFVybDogaW1taWNoLnBob3RvVXJsKHNoYXJlLmtleSwgYXNzZXQuaWQsIEltYWdlU2l6ZS50aHVtYm5haWwpLFxuICAgICAgICB2aWRlb1xuICAgICAgfSlcbiAgICB9XG4gICAgcmVzLnJlbmRlcignZ2FsbGVyeScsIHtcbiAgICAgIGl0ZW1zLFxuICAgICAgb3Blbkl0ZW1cbiAgICB9KVxuICB9XG59XG5cbmNvbnN0IHJlbmRlciA9IG5ldyBSZW5kZXIoKVxuXG5leHBvcnQgZGVmYXVsdCByZW5kZXJcbiJdfQ==
|
14
dist/types.js
vendored
14
dist/types.js
vendored
|
@ -1,14 +0,0 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ImageSize = exports.AssetType = void 0;
|
||||
var AssetType;
|
||||
(function (AssetType) {
|
||||
AssetType["image"] = "IMAGE";
|
||||
AssetType["video"] = "VIDEO";
|
||||
})(AssetType || (exports.AssetType = AssetType = {}));
|
||||
var ImageSize;
|
||||
(function (ImageSize) {
|
||||
ImageSize["thumbnail"] = "thumbnail";
|
||||
ImageSize["original"] = "original";
|
||||
})(ImageSize || (exports.ImageSize = ImageSize = {}));
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBWSxTQUdYO0FBSEQsV0FBWSxTQUFTO0lBQ25CLDRCQUFlLENBQUE7SUFDZiw0QkFBZSxDQUFBO0FBQ2pCLENBQUMsRUFIVyxTQUFTLHlCQUFULFNBQVMsUUFHcEI7QUF1QkQsSUFBWSxTQUdYO0FBSEQsV0FBWSxTQUFTO0lBQ25CLG9DQUF1QixDQUFBO0lBQ3ZCLGtDQUFxQixDQUFBO0FBQ3ZCLENBQUMsRUFIVyxTQUFTLHlCQUFULFNBQVMsUUFHcEIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZW51bSBBc3NldFR5cGUge1xuICBpbWFnZSA9ICdJTUFHRScsXG4gIHZpZGVvID0gJ1ZJREVPJ1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFzc2V0IHtcbiAgaWQ6IHN0cmluZztcbiAga2V5OiBzdHJpbmc7XG4gIHR5cGU6IEFzc2V0VHlwZTtcbiAgaXNUcmFzaGVkOiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNoYXJlZExpbmsge1xuICBrZXk6IHN0cmluZztcbiAgdHlwZTogc3RyaW5nO1xuICBhc3NldHM6IEFzc2V0W107XG4gIGFsYnVtPzoge1xuICAgIGlkOiBzdHJpbmc7XG4gIH1cbiAgZXhwaXJlc0F0OiBzdHJpbmcgfCBudWxsO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEFsYnVtIHtcbiAgYXNzZXRzOiBBc3NldFtdXG59XG5cbmV4cG9ydCBlbnVtIEltYWdlU2l6ZSB7XG4gIHRodW1ibmFpbCA9ICd0aHVtYm5haWwnLFxuICBvcmlnaW5hbCA9ICdvcmlnaW5hbCdcbn1cbiJdfQ==
|
|
@ -1,19 +1,13 @@
|
|||
version: "3"
|
||||
|
||||
services:
|
||||
public-proxy:
|
||||
image: "node:22"
|
||||
immich-public-proxy:
|
||||
image: ghcr.io/alangrainger/immich-public-proxy:latest
|
||||
container_name: immich-public-proxy
|
||||
working_dir: /home/node/app
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
volumes:
|
||||
- ./:/home/node/app:Z
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- ${PORT}:3000
|
||||
command: bash -c "cd /home/node/app && npm install && npm start"
|
||||
restart: always
|
||||
healthcheck:
|
||||
test: (ps ax | grep -q "[n]ode dist/index.js" && echo "Ok") || exit 1
|
||||
interval: 60s
|
||||
start_period: 10s
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue