1
0
mirror of https://github.com/stonith404/pingvin-share.git synced 2024-06-30 06:30:11 +02:00

Change environment variables strategy

This commit is contained in:
Elias Schneider 2022-05-02 08:22:53 +02:00
parent 961967f57a
commit 1c90cf63ce
No known key found for this signature in database
GPG Key ID: D5EC1C72D93244FD
11 changed files with 67 additions and 26 deletions

View File

@ -1,4 +1,3 @@
APPWRITE_FUNCTION_API_KEY=
NEXT_PUBLIC_APPWRITE_HOST=http://localhost:86/v1
# Must be the same as in the _APP_STORAGE_LIMIT in the Appwrite env file
NEXT_PUBLIC_MAX_FILE_SIZE=300000000
PUBLIC_APPWRITE_HOST=http://localhost/v1
PUBLIC_MAX_FILE_SIZE="300000000" # Must be the same as in the _APP_STORAGE_LIMIT in the Appwrite env file

View File

@ -4,6 +4,12 @@ WORKDIR /opt/app
COPY package.json package-lock.json ./
RUN npm ci
FROM node:16-alpine AS builder
ENV NODE_ENV=production
WORKDIR /opt/app
COPY . .
COPY --from=deps /opt/app/node_modules ./node_modules
RUN npm run build
FROM node:16-alpine AS script-builder
WORKDIR /opt/app
@ -17,9 +23,11 @@ RUN ncc build index.ts
FROM node:16-alpine AS runner
WORKDIR /opt/app
ENV NODE_ENV=production
COPY . .
COPY --from=deps /opt/app/node_modules ./node_modules
COPY --from=builder /opt/app/next.config.js ./
COPY --from=builder /opt/app/public ./public
COPY --from=builder /opt/app/.next ./.next
COPY --from=builder /opt/app/node_modules ./node_modules
COPY --from=script-builder /opt/app/.setup/dist/index.js ./scripts/setup.js
EXPOSE 3000
CMD npm run build && npm start
CMD ["node_modules/.bin/next", "start"]

View File

@ -30,14 +30,14 @@ First of all you have to start the Docker container.
The container is now running. Now you have to setup the Appwrite structure, but no worries I made a setup script.
To start the script run `docker-compose exec pingvin-share node scripts/setup.js`.
To run the script run `docker-compose exec pingvin-share node scripts/setup.js`.
You're almost done, now you have to change your environment variables that they fit to your setup.
1. Go to your Appwrite console, visit "API Keys" and copy the "Functions API Key" secret to your clipboard.
2. Paste the key to the `APPWRITE_FUNCTION_API_KEY` variable in the `.env` file
3. Change `NEXT_PUBLIC_APPWRITE_HOST` in the `.env` file to the host where your Appwrite instance runs
4. Change `NEXT_PUBLIC_MAX_FILE_SIZE` in the `.env` file to the max file size limit you want
3. Change `PUBLIC_APPWRITE_HOST` in the `.env` file to the host where your Appwrite instance runs
4. Change `PUBLIC_MAX_FILE_SIZE` in the `.env` file to the max file size limit you want
## Known issues / Limitations
@ -45,7 +45,6 @@ Pingvin Share is currently in beta and there are issues and limitations that sho
- `DownloadAll` generates the zip file on the client side. This takes alot of time. Because of that I temporarily limited this function to maximal 150 MB.
- If a user knows the share id, he can list and download the files directly from the Appwrite API even if the share is secured by a password or a visitor limit.
- Because NextJS injects environments variables at build time, the website must be rebuilt when an environment variable changes. At the moment the container rebuilts the website after every restart. This takes some time.
## Contribute

View File

@ -6,5 +6,5 @@ services:
image: stonith404/pingvin-share
environment:
- APPWRITE_FUNCTION_API_KEY=${APPWRITE_FUNCTION_API_KEY}
- NEXT_PUBLIC_APPWRITE_HOST=${NEXT_PUBLIC_APPWRITE_HOST}
- NEXT_PUBLIC_MAX_FILE_SIZE=${NEXT_PUBLIC_MAX_FILE_SIZE}
- PUBLIC_APPWRITE_HOST=${PUBLIC_APPWRITE_HOST}
- PUBLIC_MAX_FILE_SIZE=${PUBLIC_MAX_FILE_SIZE}

View File

@ -7,7 +7,6 @@
"build": "next build",
"start": "next start",
"lint": "next lint",
"start:docker": "docker build -t pingvin-share:latest . && docker run pingvin-share:latest",
"init:appwrite": "cd .setup && npm install && npx ts-node index.ts",
"deploy": "docker buildx build -t stonith404/pingvin-share --platform linux/amd64,linux/arm64 --push ."
},

View File

@ -10,6 +10,7 @@ import {
import { Dropzone as MantineDropzone, DropzoneStatus } from "@mantine/dropzone";
import React, { Dispatch, ForwardedRef, SetStateAction, useRef } from "react";
import { CloudUpload, Upload } from "tabler-icons-react";
import { useConfig } from "../../utils/config.util";
import toast from "../../utils/toast.util";
const useStyles = createStyles((theme) => ({
@ -52,13 +53,14 @@ const Dropzone = ({
setFiles: Dispatch<SetStateAction<File[]>>;
}) => {
const theme = useMantineTheme();
const config = useConfig()
const { classes } = useStyles();
const openRef = useRef<() => void>();
return (
<div className={classes.wrapper}>
<MantineDropzone
maxSize={parseInt(process.env["NEXT_PUBLIC_MAX_FILE_SIZE"] as string)}
maxSize={parseInt(config.APPWRITE_HOST)}
onReject={(e) => {
toast.error(e[0].errors[0].message);
}}

View File

@ -14,7 +14,9 @@ import "../../styles/globals.css";
import ThemeProvider from "../components/mantine/ThemeProvider";
import Header from "../components/navBar/NavBar";
import globalStyle from "../styles/global.style";
import aw from "../utils/appwrite.util";
import authUtil, { IsSignedInContext } from "../utils/auth.util";
import configUtil, { ConfigContext } from "../utils/config.util";
import { GlobalLoadingContext } from "../utils/loading.util";
function App(props: AppProps & { colorScheme: ColorScheme }) {
@ -26,13 +28,17 @@ function App(props: AppProps & { colorScheme: ColorScheme }) {
const [isLoading, setIsLoading] = useState(true);
const [isSignedIn, setIsSignedIn] = useState(false);
const checkIfSignedIn = async () => {
let environmentVariables: any = {};
const getInitalData = async () => {
setIsLoading(true);
environmentVariables = await configUtil.getGonfig();
aw.setEndpoint(environmentVariables.APPWRITE_HOST);
setIsSignedIn(await authUtil.isSignedIn());
setIsLoading(false);
};
useEffect(() => {
checkIfSignedIn();
getInitalData();
}, []);
return (
@ -44,13 +50,15 @@ function App(props: AppProps & { colorScheme: ColorScheme }) {
{isLoading ? (
<LoadingOverlay visible overlayOpacity={1} />
) : (
<IsSignedInContext.Provider value={isSignedIn}>
<LoadingOverlay visible={isLoading} overlayOpacity={1} />
<Header />
<Container>
<Component {...pageProps} />
</Container>
</IsSignedInContext.Provider>
<ConfigContext.Provider value={environmentVariables}>
<IsSignedInContext.Provider value={isSignedIn}>
<LoadingOverlay visible={isLoading} overlayOpacity={1} />
<Header />
<Container>
<Component {...pageProps} />
</Container>
</IsSignedInContext.Provider>
</ConfigContext.Provider>
)}
</GlobalLoadingContext.Provider>
</ModalsProvider>

15
src/pages/api/config.ts Normal file
View File

@ -0,0 +1,15 @@
import type { NextApiRequest, NextApiResponse } from "next";
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
let publicEnvironmentVariables: any = {};
Object.entries(process.env).forEach(([key, value]) => {
if (key.startsWith("PUBLIC")) {
key = key.replace("PUBLIC_", "");
publicEnvironmentVariables[key] = value;
}
});
res.setHeader("cache-control", "max-age=100");
res.status(200).json(publicEnvironmentVariables);
};
export default handler;

View File

@ -3,7 +3,6 @@ import { Appwrite } from "appwrite";
// SDK for client side (browser)
const aw = new Appwrite();
aw.setEndpoint(process.env["NEXT_PUBLIC_APPWRITE_HOST"] as string)
.setProject("pingvin-share");
aw.setProject("pingvin-share");
export default aw;

View File

@ -5,7 +5,7 @@ const client = new sdk.Client();
client
.setEndpoint(
(process.env["NEXT_PUBLIC_APPWRITE_HOST"] as string).replace(
(process.env["PUBLIC_APPWRITE_HOST"] as string).replace(
"localhost",
process.env.NODE_ENV == "production"
? "host.docker.internal"

12
src/utils/config.util.ts Normal file
View File

@ -0,0 +1,12 @@
import axios from "axios";
import { createContext, useContext } from "react";
export const ConfigContext = createContext<any>({});
export const useConfig = () => useContext(ConfigContext);
const getGonfig = async() => {
return (await axios.get("/api/config")).data;
};
export default { getGonfig };