Docker
This commit is contained in:
49
.github/workflows/build.yml
vendored
Normal file
49
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Build Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}
|
||||
|
||||
jobs:
|
||||
build-image:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@v3
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
flavor: |
|
||||
latest=${{ github.ref == 'refs/heads/master' }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
18
Dockerfile
Normal file
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
# Build stage
|
||||
FROM node:lts as build
|
||||
|
||||
ARG BYTEBIN_URL="data/"
|
||||
ENV REACT_APP_BYTEBIN_URL="${BYTEBIN_URL}"
|
||||
|
||||
WORKDIR /app
|
||||
COPY package.json yarn.lock ./
|
||||
RUN yarn
|
||||
COPY . ./
|
||||
RUN yarn build
|
||||
|
||||
# Run stage
|
||||
FROM nginx:alpine
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=build /app/build /usr/share/nginx/html
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
EXPOSE 80/tcp
|
||||
19
README.md
19
README.md
@@ -1,8 +1,8 @@
|
||||
<h1 align="center">📋 paste</h1>
|
||||
|
||||
**paste is a simple web app for writing & sharing code.** It's my own take on conventional pastebin sites like *pastebin.com* or *hastebin*.
|
||||
**paste is a simple web app for writing & sharing code.** It's my own take on conventional pastebin sites like _pastebin.com_ or _hastebin_.
|
||||
|
||||
The frontend *(this repository)* is written using the React framework. The backend data storage is handled by a separate web service called [bytebin](https://github.com/lucko/bytebin).
|
||||
The frontend _(this repository)_ is written using the React framework. The backend data storage is handled by a separate web service called [bytebin](https://github.com/lucko/bytebin).
|
||||
|
||||
The user-interface is quite simple; it supports syntax highlighting, automatic indentation, many supported languages, themes, zooming in/out, linking to specific lines or sections, and more!
|
||||
|
||||
@@ -10,8 +10,8 @@ The user-interface is quite simple; it supports syntax highlighting, automatic i
|
||||
<img src="https://i.imgur.com/03rBijj.gif">
|
||||
</p>
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
I host a public instance of paste at [paste.lucko.me](https://paste.lucko.me). Please feel free to use it to share code/configs/whatever!
|
||||
|
||||
However please note that the (very-non-legally worded) [terms of service](https://github.com/lucko/bytebin#public-instances) for my public bytebin instance apply here too. If you come across any content which is illegal or infringes on copyright, please [get in touch](https://lucko.me/contact) and let me know so I can remove it.
|
||||
@@ -19,6 +19,7 @@ However please note that the (very-non-legally worded) [terms of service](https:
|
||||
Uploaded content is retained for 30 days then deleted.
|
||||
|
||||
### Host your own
|
||||
|
||||
If you want to host your own paste, first you need to compile it:
|
||||
|
||||
```bash
|
||||
@@ -32,9 +33,19 @@ yarn start
|
||||
|
||||
You can then follow the [create-react-app deployment documentation](https://create-react-app.dev/docs/deployment/) for how to host the build output. I personally recommend deploying to the cloud using a service like Netlify instead of hosting on your own webserver.
|
||||
|
||||
If you really want to self-host (including the bytebin data storage part), I suggest using Docker:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/lucko/paste
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
You should then (hopefully!) be able to access the application at `http://localhost:8080/`.
|
||||
|
||||
## API
|
||||
|
||||
paste uses [bytebin](https://github.com/lucko/bytebin) for data storage.
|
||||
|
||||
As a result, you can use the [bytebin API](https://github.com/lucko/bytebin#api-usage) to submit/read content programatically.
|
||||
|
||||
To set the language of a paste, use the `Content-Type` header with value `text/<language>` (e.g. `Content-Type: text/yaml` for a *.yml* file).
|
||||
To set the language of a paste, use the `Content-Type` header with value `text/<language>` (e.g. `Content-Type: text/yaml` for a _.yml_ file).
|
||||
|
||||
26
docker-compose.yml
Normal file
26
docker-compose.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
paste:
|
||||
image: paste
|
||||
|
||||
bytebin:
|
||||
image: ghcr.io/lucko/bytebin
|
||||
volumes:
|
||||
- data:/opt/bytebin/content
|
||||
environment:
|
||||
BYTEBIN_MISC_KEYLENGTH: 5
|
||||
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
command: ['nginx', '-g', 'daemon off;']
|
||||
depends_on:
|
||||
- paste
|
||||
- bytebin
|
||||
ports:
|
||||
- 8080:80
|
||||
volumes:
|
||||
- ./docker/reverseproxy-nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
||||
|
||||
volumes:
|
||||
data: {}
|
||||
18
docker/nginx.conf
Normal file
18
docker/nginx.conf
Normal file
@@ -0,0 +1,18 @@
|
||||
# nginx config file for a SPA (single page app)
|
||||
server {
|
||||
listen 80 default_server;
|
||||
|
||||
gzip on;
|
||||
gzip_min_length 1000;
|
||||
gzip_types text/plain text/xml application/javascript text/css;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/index.html /index.html;
|
||||
}
|
||||
|
||||
location ~ \.(?!html) {
|
||||
try_files $uri =404;
|
||||
}
|
||||
}
|
||||
29
docker/reverseproxy-nginx.conf
Normal file
29
docker/reverseproxy-nginx.conf
Normal file
@@ -0,0 +1,29 @@
|
||||
# nginx reverse proxy configuration for paste+bytebin
|
||||
server {
|
||||
listen 80 default_server;
|
||||
|
||||
# paste app
|
||||
location / {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
proxy_pass http://paste;
|
||||
}
|
||||
|
||||
# disable bytebin frontend
|
||||
location = /data/ {
|
||||
return 404;
|
||||
}
|
||||
|
||||
# proxy /data endpoint to bytebin
|
||||
location /data/ {
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
proxy_pass http://bytebin:8080/;
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
|
||||
import Editor from './components/Editor';
|
||||
import parseContentType from 'content-type-parser';
|
||||
import { languageIds } from './util/highlighting';
|
||||
import { bytebinUrl } from './util/constants';
|
||||
|
||||
function getPasteIdFromUrl() {
|
||||
const path = window.location.pathname;
|
||||
@@ -14,7 +15,7 @@ function getPasteIdFromUrl() {
|
||||
|
||||
async function loadFromBytebin(id) {
|
||||
try {
|
||||
const resp = await fetch('https://bytebin.lucko.me/' + id);
|
||||
const resp = await fetch(bytebinUrl + id);
|
||||
if (resp.ok) {
|
||||
const content = await resp.text();
|
||||
const type = parseLanguageFromContentType(
|
||||
|
||||
@@ -7,6 +7,7 @@ import copy from 'copy-to-clipboard';
|
||||
import { MenuButton, Button } from './Menu';
|
||||
import { languageIds } from '../util/highlighting';
|
||||
import themes from '../style/themes';
|
||||
import { postUrl } from '../util/constants';
|
||||
|
||||
export default function EditorControls({
|
||||
code,
|
||||
@@ -142,7 +143,7 @@ async function saveToBytebin(code, language) {
|
||||
const compressed = gzip(code);
|
||||
const contentType = langaugeToContentType(language);
|
||||
|
||||
const resp = await fetch('https://bytebin.lucko.me/post', {
|
||||
const resp = await fetch(postUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': contentType,
|
||||
|
||||
4
src/util/constants.js
Normal file
4
src/util/constants.js
Normal file
@@ -0,0 +1,4 @@
|
||||
export const bytebinUrl =
|
||||
process.env.REACT_APP_BYTEBIN_URL || 'https://bytebin.lucko.me/';
|
||||
|
||||
export const postUrl = bytebinUrl + 'post';
|
||||
Reference in New Issue
Block a user