diff --git a/README.md b/README.md
index 39e4053..d78b1d5 100644
--- a/README.md
+++ b/README.md
@@ -4,41 +4,49 @@
PEPIC
-Pepic is a small self-hosted media proxy that helps me to upload, store, serve and convert pictures and videos on my own servers locally.
+Pepic is a small self-hosted media proxy that helps me to upload, store, serve and convert pictures and videos on my own servers.
Currently, I use it as a main storage for media files in my [pet-projects](https://github.com/vas3k/vas3k.club) and on [my blog](https://vas3k.blog).
-Pepic can upload and optimize media files in-flight to save you money and bandwidth. It's highly recommended to use it in combination with Cloudflare CDN for better caching.
+Pepic can upload and optimize media files in-flight to save you money and bandwidth. It's highly recommended to set ip up in combination with Cloudflare CDN for better caching.
-Internally, Pepic it uses [ffmpeg](https://ffmpeg.org/download.html) for videos and [vips](https://libvips.github.io/libvips/install.html) for images, which makes it quite fast and supports many media file formats.
+Internally it uses [ffmpeg](https://ffmpeg.org/download.html) for videos and [vips](https://libvips.github.io/libvips/install.html) for images, which makes it quite fast and supports many media file formats.
Images: **JPG, PNG, GIF, WEBP, SVG, HEIF, TIFF, AVIF, etc**
+
Video: **basically everything ffmpeg supports**
-Pepic is open source, however it's not meant to be used by anyone. Only if you're brave. Scroll down this README for better alternatives.
+Pepic is open source, however it's not meant to be used by anyone. Only if you're brave (like me). Scroll down this README for better alternatives.
-## Main Features
+## Features
-- **Local files upload**: Accept files in multipart/form-data or bytes and store them to a local directory.
+- **Local files uploads**: Upload files as multipart/form-data or as a simple byte stream and store them to a local directory.
- **Automatic GIF to video conversion**: Convert GIFs to videos because GIFs suck, slow down web pages, and don't support hardware acceleration.
-- **Media format conversion and optimization**: Convert and optimize media files on-the-fly.
+- **Image and video conversion and optimization**: Transcode and optimize media files on upload or on-the-fly.
- **Dynamic resizing**: Easily resize images in real-time by modifying the URL, which helps in reducing bandwidth and storage space on devices.
- **High performance**: Pepic uses native libraries like `ffmpeg` and `vips` for video and image processing to ensure high performance and fast processing times.
- **Local and containerized environments**: Designed to run smoothly in both local environments and within Docker containers, making it versatile for development and deployment.
-- **Custom configuration**: Flexible configuration options through `config.yml`, allowing adjustments to image size, quality, automatic conversion, templates, etc.
+- **Custom configuration**: Flexible configuration options through `[config.yml](./etc/pepic/config.yml)`, allowing adjustments to image size, quality, automatic conversion, templates, etc.
![](static/images/screenshot1.png)
## ๐ค How to Run
-1. Install `vips` and `ffmpeg` first, as they are external dependencies.
+1. Install `vips` and `ffmpeg` first, as they are external dependencies
```bash
brew install vips ffmpeg
```
-2. Use the following command to start a local server on [localhost:8118](http://localhost:8118).
+2. Clone this repo
+
+```bash
+git clone git@github.com:vas3k/pepic.git
+cd pepic
+```
+
+3. Run the following command to build and start the app
```bash
go run main.go serve --config ./etc/pepic/config.yml
@@ -46,31 +54,106 @@ go run main.go serve --config ./etc/pepic/config.yml
> โ ๏ธ If you're getting `invalid flag in pkg-config` error, run `brew install pkg-config` and `export CGO_CFLAGS_ALLOW="-Xpreprocessor"`. Then try `go run` again.
-3. Enjoy!
+3. Go to [localhost:8118](http://localhost:8118) and enjoy!
-## ๐ณ Running in Docker
+## ๐ณ Using Docker Compose
-1. Get [Docker](https://www.docker.com/get-started)
+You can find [docker-compose.example.yml](./docker-compose.example.yml) in this repo and adapt it to your own needs.
-2. Clone the repo
+1. Get [Docker](https://www.docker.com/get-started) and [Docker Compose](https://www.digitalocean.com/community/tutorial-collections/how-to-install-docker-compose)
+
+2. Download the Docker Compose example file and save it as `docker-compose.yml` on your local machine
```bash
-git clone git@github.com:vas3k/pepic.git
-cd pepic
+curl https://raw.githubusercontent.com/vas3k/pepic/master/docker-compose.example.yml -o docker-compose.yml
```
-3. Build and run the app
+3. Now run it
```bash
-docker build .
-docker run -p 8118:8118 -v ${PWD}/uploads:/app/uploads $(docker build -q .)
+docker-compose up
+```
+
+4. Go to [http://localhost:8118](http://localhost:8118) and try uploading something. You should see uploaded images or videos in the local directory (`./uploads`) after that.
+
+
+## ๐งถ Usage
+
+### Configuration options
+
+```yaml
+global:
+ host: 0.0.0.0
+ port: 8118
+ base_url: "http://0.0.0.0:8118/" # trailing slash is important
+ secret_code: "" # secret word to protect you from strangers (don't use your password here, it's stored as plain text)
+ max_upload_size: "500M" # number + K, M, G, T or P
+ file_tree_split_chars: 3 # abcde.jpg -> ab/cd/e.jpg (never change this after release!)
+
+storage:
+ type: fs
+ dir: uploads/
+
+images:
+ store_originals: false # use "true" if you want byte-by-byte match of uploaded files (useful for photo blogs)
+ original_length: 1900 # long side length in px to auto-resize originals (only if store_originals=false)
+ auto_convert: false # mime type to auto-convert uploaded images ("image/jpeg", "image/png" or false)
+ live_resize: true # enables special URLs that return resized images (increases storage usage)
+ jpeg_quality: 95 # default quality for any saved jpegs
+ png_compression: 0 # 0 - default, -1 - no compression, -2 - best speed, -3 - best compression (yes, with minus)
+ gif_convert: "video/mp4" # video format for auto-converting gifs (ignored on store_originals=true)
+
+videos:
+ store_originals: false # use "true" if you want to store original files (browser compatibility is on you)
+ original_length: 720 # resize uploaded videos (only if store_originals=false)
+ live_resize: false # turned off by default to save disk space and your cpu (always returns original)
+ auto_convert: "video/mp4" # mime type to auto-convert uploaded images (for example "video/mp4")
+ ffmpeg:
+ temp_dir: "/tmp" # temp directory for video transcoding
+ preset: "slow" # ultrafast, superfast, veryfast, faster, fast, medium, slow, slower, veryslow, placebo
+ crf: 24 # quality factor โ 0-51, where 0 is lossless, 51 โ pixelated shit. 23-28 recommended.
+ buffer_size: 1024000 # other standard ffmpeg params, you can google them
+ video_codec: "libx264"
+ video_bitrate: "1024k"
+ video_profile: "main"
+ audio_codec: "aac"
+ audio_bitrate: "128k"
+ mov_flags: "+faststart"
+ pix_fmt: "yuv420p"
+
+meta: # optional, only if you use web interface
+ image_templates: # add your custom templates here for easier copy-paste
+ - title: "URL"
+ template: "{{ file.Url }}"
+ - title: "Simple Markdown"
+ template: "![]({{ file.Url }})"
+ video_templates:
+ - title: "URL"
+ template: "{{ file.Url }}"
+ - title: "Simple Markdown"
+ template: "![]({{ file.Url }})"
+ multi_templates:
+ - title: "2 in a row"
+ template: "{% for file in files %}![]({{ file.Url }}) {% endfor %}"
+
```
-4. Go to [http://localhost:8118](http://localhost:8118) and try uploading something. You should see uploaded images or videos in the data directory (`./uploads`) after that.
+### Resizing images on demand
+
+If your image URL looks like this: **`https://imgs.com/file.jpg`**
+
+Add /500/ to its URL to get 500px (on the long side) version: **`https://imgs.com/500/file.jpg`**
+
+Works only if `live_resize` option is set to `true`. If `live_resize=false` โ it returns the original version. Same for video transcoding (where it's off by default).
+
+
+### Converting file formats on demand
+
+// Not implemented yet, sorry...
+
-5. Try to resize an image by adding a number of pixels to its URL. For example: `https://localhost:8118/file.jpg -> https://localhost:8118/500/file.jpg`
+![](static/images/screenshot2.png)
-6. Check out the [etc/pepic/config.yml](etc/pepic/config.yml) file. Some stuff is turned off by default. You can tweak them for yourself and rebuild the Docker again (step 3) to apply them.
## ๐ข Production Deployment
@@ -95,7 +178,7 @@ global:
Don't forget to mount upload volume to store files on host (or you can lose those files when the container is killed).
```bash
-docker run -p 8118:8118 -v /host/dir/uploads:/app/uploads --restart=always $(docker build -q .)
+docker run -p 8118:8118 -v /host/dir/uploads:/app/uploads --restart=unless-stopped $(docker build -q .)
```
If you prefer docker-compose, you can use it too. Check out the included [docker-compose.example.yml](docker-compose.example.yml).
diff --git a/docker-compose.example.yml b/docker-compose.example.yml
index 76ae7b5..d7663a2 100644
--- a/docker-compose.example.yml
+++ b/docker-compose.example.yml
@@ -1,7 +1,7 @@
version: "3.8"
services:
app:
- build: .
+ image: ghcr.io/vas3k/pepic:${GITHUB_SHA:-latest}
environment: # check out pepic/config/app.go for more env variables
- BASE_URL=https://i.vas3k.ru/
- STORAGE_DIR=/uploads
diff --git a/etc/pepic/config.yml b/etc/pepic/config.yml
index 0d71d78..f594b1b 100644
--- a/etc/pepic/config.yml
+++ b/etc/pepic/config.yml
@@ -16,12 +16,12 @@ images:
auto_convert: false # mime type to auto-convert uploaded images ("image/jpeg", "image/png" or false)
live_resize: true # enables special URLs that return resized images (increases storage usage)
jpeg_quality: 95 # default quality of any saved jpeg
- png_compression: 0 # 0 - default, -1 - no compression, -2 - best speed, -3 - best compression
+ png_compression: 0 # 0 - default, -1 - no compression, -2 - best speed, -3 - best compression (yes, with minus)
gif_convert: "video/mp4" # video format for auto-converting gifs (turned off then store_originals=true)
videos:
store_originals: false # use "true" if you want to store original files (browser compatibility is on you)
- original_length: 480 # resize uploaded videos (only if store_originals=false)
+ original_length: 720 # resize uploaded videos (only if store_originals=false)
live_resize: false # turned off by default to save disk space and your cpu (always returns original)
auto_convert: "video/mp4" # mime type to auto-convert uploaded images (for example "video/mp4")
ffmpeg:
@@ -30,15 +30,15 @@ videos:
crf: 24 # quality factor โ 0-51, where 0 is lossless, 51 โ pixelated shit. 23-28 recommended.
buffer_size: 1024000
video_codec: "libx264"
- video_bitrate: "512k"
+ video_bitrate: "1024k"
video_profile: "main"
audio_codec: "aac"
audio_bitrate: "128k"
mov_flags: "+faststart"
pix_fmt: "yuv420p"
-meta:
- image_templates: # you can add your custom blocks to make it easier to copy-paste
+meta: # optional, only if you use web interface
+ image_templates: # add your custom templates here for easier copy-paste
- title: "URL"
template: "{{ file.Url }}"
- title: "Simple Markdown"
diff --git a/static/images/screenshot2.png b/static/images/screenshot2.png
new file mode 100644
index 0000000..2babeea
Binary files /dev/null and b/static/images/screenshot2.png differ