518 setup env command (#519)

* Created command and cleaned

* Simplified docker setup, created script to generate .env

* add git ignore file back
This commit is contained in:
Julien Nahum 2024-08-08 16:33:01 +02:00 committed by GitHub
parent 7888990e84
commit fd9067b470
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 225 additions and 196 deletions

View File

@ -12,7 +12,7 @@ FILESYSTEM_DRIVER=local
BROADCAST_CONNECTION=log BROADCAST_CONNECTION=log
CACHE_STORE=redis CACHE_STORE=redis
QUEUE_CONNECTION=redis QUEUE_CONNECTION=redis
SESSION_DRIVER=file SESSION_DRIVER=redis
SESSION_LIFETIME=120 SESSION_LIFETIME=120
MAIL_MAILER=log MAIL_MAILER=log

186
README.md
View File

@ -4,7 +4,6 @@
<img src="https://github.com/JhumanJ/OpnForm/blob/main/public/img/social-preview.jpg?raw=true"> <img src="https://github.com/JhumanJ/OpnForm/blob/main/public/img/social-preview.jpg?raw=true">
</p> </p>
<p align="center"> <p align="center">
<a href="https://github.com/JhumanJ/OpnForm/stargazers"><img src="https://img.shields.io/github/stars/JhumanJ/OpnForm" alt="Github Stars"></a> <a href="https://github.com/JhumanJ/OpnForm/stargazers"><img src="https://img.shields.io/github/stars/JhumanJ/OpnForm" alt="Github Stars"></a>
</a> </a>
@ -25,24 +24,25 @@
## Features ## Features
- No-code form builder, with infinite number of fields & submissions - No-code form builder, with infinite number of fields & submissions
- Text inputs, Date inputs, URL inputs, Phone inputs, Email inputs, Checkboxes, Select and Multi-Select inputs, Number Inputs, Star-ratings, File uploads & more - Text inputs, Date inputs, URL inputs, Phone inputs, Email inputs, Checkboxes, Select and Multi-Select inputs, Number Inputs, Star-ratings, File uploads & more
- Embed anywhere (on your website, in your Notion page, etc) - Embed anywhere (on your website, in your Notion page, etc)
- Email notifications (for both form owner & form respondents) - Email notifications (for both form owner & form respondents)
- Hidden fields - Hidden fields
- Form passwords - Form passwords
- URL form pre-fill - URL form pre-fill
- Slack integration - Slack integration
- Webhooks - Webhooks
- Form logic - Form logic
- Customize colors, add images or even some custom code - Customize colors, add images or even some custom code
- Captcha form protection - Captcha form protection
- Form closing date - Form closing date
- Limit the number of submissions allowed - Limit the number of submissions allowed
And much more! And much more!
## Bounties ## Bounties
Get paid for contributing to OpnForm! Here are our open bounties: Get paid for contributing to OpnForm! Here are our open bounties:
<a href="https://console.algora.io/org/OpnForm/bounties?status=open"> <a href="https://console.algora.io/org/OpnForm/bounties?status=open">
@ -60,38 +60,66 @@ It takes 1 minute to try out the builder for free. You'll have high availability
### Requirements ### Requirements
- PHP >= 8.0 - PHP >= 8.0
- MySQL/MariaDB or PostgreSQL - MySQL/MariaDB or PostgreSQL
- Node.js and NPM/Yarn/... to compile assets - Node.js and NPM/Yarn/... to compile assets
## Installation ## Installation
### Environment Setup
Before you can run the application, you need to set up the environment variables. We have provided a script that will automate the process of creating your `.env` files from the provided examples.
Follow these steps to set up your environment:
1. Make sure you have `openssl` installed, as it is required by the setup script to generate secure keys.
2. Run the setup script from the root of the project:
```bash
chmod +x ./scripts/setup-env.sh
./scripts/setup-env.sh
```
**If you are using Docker** and want to prepare a Docker-specific environment, run the script with the `--docker` flag:
```bash
./scripts/setup-env.sh --docker
```
3. After running the script, review the `.env` and `client/.env` files to ensure all settings are correct for your environment.
Remember to never commit your `.env` files to version control. They should be kept private as they contain sensitive information.
### Docker Installation 🐳 ### Docker Installation 🐳
OpnForm can be easily set up using Docker. Pre-built images are available on Docker Hub, which is the recommended method for most users. OpnForm can be easily set up using Docker. Pre-built images are available on Docker Hub, which is the recommended method for most users.
#### Prerequisites #### Prerequisites
- Docker
- Docker Compose - Docker
- Docker Compose
#### Quick Start #### Quick Start
1. Clone the repository: 1. Clone the repository:
```
git clone https://github.com/JhumanJ/OpnForm.git
cd OpnForm
```
2. Set up environment files: ```
``` git clone https://github.com/JhumanJ/OpnForm.git
cp .env.docker .env cd OpnForm
cp client/.env.docker client/.env ```
```
2. Set up environment files by running the provided setup script. For detailed instructions, refer to the [Environment Setup](#environment-setup) section above:
```bash
./scripts/setup-env.sh --docker
```
3. Start the application: 3. Start the application:
```
docker-compose up -d ```
``` docker-compose up -d
```
4. Access OpnForm at http://localhost 4. Access OpnForm at http://localhost
@ -99,59 +127,72 @@ OpnForm can be easily set up using Docker. Pre-built images are available on Doc
#### Customization #### Customization
- **Environment Variables**: Modify `.env` and `client/.env` files to customize your setup. For example, to enable email features, configure a [supported mail driver](https://laravel.com/docs/11.x/mail) in the `.env` file. - **Environment Variables**: Modify `.env` and `client/.env` files to customize your setup. For example, to enable email features, configure a [supported mail driver](https://laravel.com/docs/11.x/mail) in the `.env` file.
#### Upgrading #### Upgrading
1. Check the upgrade instructions for your target version in the documentation. 1. Check the upgrade instructions for your target version in the documentation.
2. Update your `docker-compose.yml` file if necessary. 2. Update your `docker-compose.yml` file if necessary.
3. Apply changes: 3. Apply changes:
``` ```
docker-compose up -d docker-compose up -d
``` ```
### Initial Login #### Initial Login
After installation, use these credentials to access the admin panel: After installation, use these credentials to access the admin panel:
- Email: `admin@opnform.com`
- Password: `password` - Email: `admin@opnform.com`
- Password: `password`
⚠️ Change these credentials immediately after your first login. ⚠️ Change these credentials immediately after your first login.
Note: Public registration is disabled in the self-hosted version. Use the admin account to invite additional users. Note: Public registration is disabled in the self-hosted version. Use the admin account to invite additional users.
### Building from Source #### Building from Source
For development or customization, you can build the Docker images locally: For development or customization, you can build the Docker images locally:
1. Build the images: 1. Build the images:
```
docker build -t opnform-ui:local -f docker/Dockerfile.client . ```
docker build -t opnform-api:local -f docker/Dockerfile.api . docker build -t opnform-ui:local -f docker/Dockerfile.client .
``` docker build -t opnform-api:local -f docker/Dockerfile.api .
```
2. Create a docker-compose override file: 2. Create a docker-compose override file:
```
cp docker-compose.override.yml.example docker-compose.override.yml
```
Edit the `docker-compose.override.yml` file to use your locally built images: ```
```yaml cp docker-compose.override.yml.example docker-compose.override.yml
services: ```
api:
image: opnform-api:local Edit the `docker-compose.override.yml` file to use your locally built images:
ui:
image: opnform-ui:local ```yaml
``` services:
api:
image: opnform-api:local
ui:
image: opnform-ui:local
```
3. Start the application: 3. Start the application:
``` ```
docker-compose up -d docker-compose up -d
``` ```
This method allows you to make changes to the source code and rebuild the images as needed. This method allows you to make changes to the source code and rebuild the images as needed.
#### Clearing all resources
To completely remove all Docker containers, networks, and volumes created by `docker-compose` and also remove all images used by these services, you can use the following command:
```bash
docker-compose down -v --rmi all
```
### Using Laravel Valet ### Using Laravel Valet
This section explains how to get started locally with the project. It's most likely relevant if you're trying to work on the project. This section explains how to get started locally with the project. It's most likely relevant if you're trying to work on the project.
First, let's work with the codebase and its dependencies. First, let's work with the codebase and its dependencies.
@ -160,8 +201,8 @@ First, let's work with the codebase and its dependencies.
git clone git@github.com:JhumanJ/OpnForm.git && cd OpnForm git clone git@github.com:JhumanJ/OpnForm.git && cd OpnForm
# Install PHP dependencies # Install PHP dependencies
composer install composer install
# Install JS dependencies # Install JS dependencies
cd client && npm install cd client && npm install
@ -183,9 +224,18 @@ php artisan jwt:secret # and select yes!
# Creates DB schemas # Creates DB schemas
php artisan migrate php artisan migrate
``` ```
Now, create an S3 bucket (or equivalent). Create an IAM user with access to this bucket, fill the environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION`, `AWS_BUCKET`. In your AWS bucket permissions, add the following under "Cross-origin resource sharing (CORS)":
Now, create an S3 bucket (or equivalent). Create an IAM user with access to this bucket, fill the environment variables: `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `AWS_DEFAULT_REGION`, `AWS_BUCKET`. In your AWS bucket permissions, add the following under "Cross-origin resource sharing (CORS)":
```json ```json
[ { "AllowedHeaders": [ "*" ], "AllowedMethods": [ "PUT", "POST", "GET", "DELETE" ], "AllowedOrigins": [ "*" ], "ExposeHeaders": [] } ] [
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["PUT", "POST", "GET", "DELETE"],
"AllowedOrigins": ["*"],
"ExposeHeaders": []
}
]
``` ```
🎉 Done! Enjoy your personal OpnForm instance at: [http://opnform.test](http://opnform.test). 🎉 Done! Enjoy your personal OpnForm instance at: [http://opnform.test](http://opnform.test).
@ -197,14 +247,16 @@ Now, create an S3 bucket (or equivalent). Create an IAM user with access to this
## Tech Stack ## Tech Stack
OpnForm is a standard web application built with: OpnForm is a standard web application built with:
- [Laravel](https://laravel.com/) PHP framework
- [NuxtJs](https://nuxt.com/) Front-end SSR framework - [Laravel](https://laravel.com/) PHP framework
- [Vue.js 3](https://vuejs.org/) Front-end framework - [NuxtJs](https://nuxt.com/) Front-end SSR framework
- [TailwindCSS](https://tailwindcss.com/) - [Vue.js 3](https://vuejs.org/) Front-end framework
- [TailwindCSS](https://tailwindcss.com/)
## Contribute ## Contribute
You're more than welcome to contribute to this project. We don't have guidelines on this yet, but we will soon. In the meantime, feel free to ask [any question here](https://github.com/JhumanJ/OpnForm/discussions). You're more than welcome to contribute to this project. We don't have guidelines on this yet, but we will soon. In the meantime, feel free to ask [any question here](https://github.com/JhumanJ/OpnForm/discussions).
## License ## License
OpnForm is open-source under the GNU Affero General Public License Version 3 (AGPLv3) or any later version. You can find it [here](https://github.com/JhumanJ/OpnForm/blob/main/LICENSE).
OpnForm is open-source under the GNU Affero General Public License Version 3 (AGPLv3) or any later version. You can find it [here](https://github.com/JhumanJ/OpnForm/blob/main/LICENSE).

View File

@ -1,7 +1,7 @@
NUXT_LOG_LEVEL= NUXT_LOG_LEVEL=
NUXT_PUBLIC_APP_URL=/ NUXT_PUBLIC_APP_URL=/
NUXT_PUBLIC_API_BASE=/api NUXT_PUBLIC_API_BASE=/api
NUXT_PRIVATE_API_BASE=http://localhost/api NUXT_PRIVATE_API_BASE=http://ingress/api
NUXT_PUBLIC_AI_FEATURES_ENABLED=false NUXT_PUBLIC_AI_FEATURES_ENABLED=false
NUXT_PUBLIC_AMPLITUDE_CODE= NUXT_PUBLIC_AMPLITUDE_CODE=
NUXT_PUBLIC_CRISP_WEBSITE_ID= NUXT_PUBLIC_CRISP_WEBSITE_ID=
@ -10,5 +10,4 @@ NUXT_PUBLIC_ENV=local
NUXT_PUBLIC_GOOGLE_ANALYTICS_CODE= NUXT_PUBLIC_GOOGLE_ANALYTICS_CODE=
NUXT_PUBLIC_H_CAPTCHA_SITE_KEY= NUXT_PUBLIC_H_CAPTCHA_SITE_KEY=
NUXT_PUBLIC_PAID_PLANS_ENABLED= NUXT_PUBLIC_PAID_PLANS_ENABLED=
NUXT_PUBLIC_S3_ENABLED=false NUXT_PUBLIC_S3_ENABLED=false
NUXT_API_SECRET=

View File

@ -10,8 +10,6 @@ services:
DB_USERNAME: ${DB_USERNAME:-forge} DB_USERNAME: ${DB_USERNAME:-forge}
DB_PASSWORD: ${DB_PASSWORD:-forge} DB_PASSWORD: ${DB_PASSWORD:-forge}
DB_CONNECTION: ${DB_CONNECTION:-pgsql} DB_CONNECTION: ${DB_CONNECTION:-pgsql}
LOG_LEVEL: ${LOG_LEVEL:-debug}
LOG_CHANNEL: ${LOG_CHANNEL:-errorlog}
AWS_ENDPOINT: http://minio:9000 AWS_ENDPOINT: http://minio:9000
AWS_ACCESS_KEY_ID: ${MINIO_ACCESS_KEY:-minio} AWS_ACCESS_KEY_ID: ${MINIO_ACCESS_KEY:-minio}
AWS_SECRET_ACCESS_KEY: ${MINIO_SECRET_KEY:-minio123} AWS_SECRET_ACCESS_KEY: ${MINIO_SECRET_KEY:-minio123}
@ -23,11 +21,13 @@ services:
env_file: ./.env env_file: ./.env
volumes: volumes:
- laravel-persist:/persist - laravel-persist:/persist
- secrets-config:/secrets - ./storage/logs:/usr/share/nginx/html/storage/logs
api-worker: api-worker:
<<: *api <<: *api
command: ./artisan queue:work command: ./artisan queue:work
volumes:
- ./storage/logs:/usr/share/nginx/html/storage/logs
ui: ui:
image: jhumanj/opnform-client:latest image: jhumanj/opnform-client:latest
@ -38,11 +38,8 @@ services:
env_file: env_file:
- ./client/.env - ./client/.env
volumes: volumes:
- secrets-config:/secrets
- ./client/.env:/app/.env - ./client/.env:/app/.env
redis: redis:
image: redis:7 image: redis:7
@ -65,4 +62,3 @@ services:
volumes: volumes:
laravel-persist: laravel-persist:
postgres-data: postgres-data:
secrets-config:

View File

@ -40,8 +40,6 @@ RUN chmod 777 -R storage
RUN php artisan package:discover --ansi RUN php artisan package:discover --ansi
COPY docker/php-fpm-entrypoint /usr/local/bin/opnform-entrypoint COPY docker/php-fpm-entrypoint /usr/local/bin/opnform-entrypoint
COPY docker/generate-api-secret.sh /usr/local/bin/
RUN ln -s /secrets/api.env .env
RUN chmod a+x /usr/local/bin/* RUN chmod a+x /usr/local/bin/*

View File

@ -26,7 +26,6 @@ FROM node:20-alpine
WORKDIR /app WORKDIR /app
COPY --from=javascript-builder /app/.output/ /app/ COPY --from=javascript-builder /app/.output/ /app/
RUN ls /app/ RUN ls /app/
RUN ln -s /secrets/client.env .env
ADD ./docker/node-entrypoint /entrypoint.sh ADD ./docker/node-entrypoint /entrypoint.sh
RUN chmod a+x /entrypoint.sh RUN chmod a+x /entrypoint.sh

View File

@ -1,42 +0,0 @@
#!/bin/bash -e
main() {
generate_api_secrets
}
generate_api_secrets() {
if ! is_configured; then
echo "Generating shared secret..."
SECRET="$(random_string)"
add_secret_to_env_file /secrets/client.env NUXT_API_SECRET "$SECRET"
add_secret_to_env_file /secrets/api.env FRONT_API_SECRET "$SECRET"
fi
}
random_string() {
array=()
for i in {a..z} {A..Z} {0..9};
do
array[$RANDOM]=$i
done
printf %s ${array[@]::8} $'\n'
}
add_secret_to_env_file() {
FILE=$1
TEMP_FILE=/tmp/env.$$
VAR=$2
VAL=$3
grep -q "^$VAR=" "$FILE" 2>/dev/null || ( echo "$VAR=" >> "$FILE" )
cp $FILE $TEMP_FILE
sed "s/^$VAR=.*$/$VAR=$VAL/" -i $TEMP_FILE
cat $TEMP_FILE > $FILE
}
is_configured() {
grep -q "FRONT_API_SECRET=.\+" .env 2>/dev/null
}
main

View File

@ -1,13 +1,9 @@
#!/bin/sh #!/bin/sh
main() { main() {
if [ "$1" == "bash" ]; then if [ "$1" = "bash" ]; then
"$@" "$@"
else else
wait_for_api_secret
if [ ! -f .env ] && [ -f /secrets/client.env ]; then
ln -sf /secrets/client.env .env
fi
if [ -f .env ]; then if [ -f .env ]; then
. .env . .env
else else
@ -16,15 +12,10 @@ main() {
run_server "$@" run_server "$@"
fi fi
} }
wait_for_api_secret() {
until [ -f /secrets/configured ]; do
echo "Waiting for api secret..."
sleep 1
done
}
run_server() { run_server() {
echo "Running " node "$@" echo "Running node $@"
"$@" "$@"
} }
main "$@" main "$@"

View File

@ -1,61 +1,22 @@
#!/bin/bash #!/bin/bash
main() { main() {
read_env
prep_file_permissions prep_file_permissions
prep_storage prep_storage
if is_master "$@"; then wait_for_db
prep_laravel_secrets apply_db_migrations
wait_for_db run_init_project
apply_db_migrations
run_init_project
mark_ready
else
wait_for_ready
wait_for_db
fi
read_env
run_server "$@" run_server "$@"
} }
is_master() { is_master() {
echo "$@" | grep -q php-fpm echo "$@" | grep -q php-fpm
} }
read_env() {
#set +x
[ -f .env ] || touch .env
. .env
#set -x
}
prep_file_permissions() { prep_file_permissions() {
chmod a+x ./artisan chmod a+x ./artisan
} }
prep_laravel_secrets() {
read_env
[ "x$APP_KEY" != "x" ] || {
echo "Generating Laravel key..."
grep -q "APP_KEY=" .env || {
echo "APP_KEY=" >> .env
}
./artisan key:generate
read_env
}
[ "x$JWT_SECRET" != "x" ] || {
echo "Generating Laravel Secret..."
./artisan jwt:secret -f
read_env
}
[ "x$FRONT_API_SECRET" != "x" ] || {
echo "Generating Shared Client Secret..."
/usr/local/bin/generate-api-secret.sh
read_env
}
echo "Done with secrets"
}
apply_db_migrations() { apply_db_migrations() {
echo "Running DB Migrations" echo "Running DB Migrations"
./artisan migrate ./artisan migrate
@ -66,28 +27,15 @@ run_init_project() {
./artisan app:init-project ./artisan app:init-project
} }
wait_for_ready() {
echo "Checking keys have been generated"
until [ -f /secrets/configured ]; do
sleep 1;
echo "Waiting for keys to generate"
done
}
mark_ready() {
touch /secrets/configured
}
wait_for_db() { wait_for_db() {
echo "Waiting for DB to be ready"
until ./artisan migrate:status 2>&1 | grep -q -E "(Migration table not found|Migration name)"; do until ./artisan migrate:status 2>&1 | grep -q -E "(Migration table not found|Migration name)"; do
echo "Waiting for DB to bootup"
sleep 1 sleep 1
done done
} }
run_server() { run_server() {
echo "Booting $@" echo "Starting server $@"
read_env
/usr/local/bin/docker-php-entrypoint "$@" /usr/local/bin/docker-php-entrypoint "$@"
} }
@ -112,4 +60,4 @@ prep_storage() {
ln -t . -sf /persist/storage ln -t . -sf /persist/storage
} }
main "$@" main "$@"

88
scripts/setup-env.sh Executable file
View File

@ -0,0 +1,88 @@
#!/bin/bash
set -e
# Welcome to the OpnForm environment setup script!
# Paths to the environment files
ENV_FILE=".env"
CLIENT_ENV_FILE="client/.env"
# Paths to the environment templates
ENV_EXAMPLE=".env.example"
CLIENT_ENV_EXAMPLE="client/.env.example"
# Check for the --docker flag to use Docker-specific environment settings
USE_DOCKER_ENV=false
for arg in "$@"; do
if [ "$arg" == "--docker" ]; then
USE_DOCKER_ENV=true
ENV_EXAMPLE=".env.docker"
CLIENT_ENV_EXAMPLE="client/.env.docker"
echo "OpnForm setup detected the --docker flag. Preparing Docker-specific environment..."
break
fi
done
# Function to generate a random string for secrets
generate_secret() {
LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 40 ; echo ''
}
# Function to generate a base64-encoded 32-byte string for keys
generate_base64_key() {
openssl rand -base64 32
}
# Function to set or update an environment variable within a file
set_env_value() {
local file=$1
local key=$2
local value=$3
local delimiter="|"
if grep -q "^$key=" "$file"; then
# Use different sed syntax based on the operating system
if [[ "$OSTYPE" == "darwin"* ]]; then
# macOS uses BSD sed, which requires an argument for -i
sed -i '' "s${delimiter}^$key=.*${delimiter}$key=$value${delimiter}" "$file"
else
# Linux uses GNU sed, which does not require an argument for -i
sed -i "s${delimiter}^$key=.*${delimiter}$key=$value${delimiter}" "$file"
fi
else
# Append a newline and the new key-value pair
echo -e "\n$key=$value" >> "$file"
fi
}
# Check if the main .env file exists
if [ -f "$ENV_FILE" ]; then
echo "OpnForm's main .env file is already in place. No further action is needed."
else
echo "Creating OpnForm's main .env file from the template..."
cp "$ENV_EXAMPLE" "$ENV_FILE"
# Secure your OpnForm instance with a unique APP_KEY
APP_KEY=$(generate_base64_key)
set_env_value "$ENV_FILE" "APP_KEY" "base64:$APP_KEY"
# Generate a JWT_SECRET to sign your tokens
JWT_SECRET=$(generate_secret)
set_env_value "$ENV_FILE" "JWT_SECRET" "$JWT_SECRET"
# Generate a shared secret for the client
SHARED_SECRET=$(generate_secret)
set_env_value "$ENV_FILE" "FRONT_API_SECRET" "$SHARED_SECRET"
fi
# Check if the client .env file exists
if [ -f "$CLIENT_ENV_FILE" ]; then
echo "OpnForm's client .env file is already configured. Moving on..."
else
echo "Creating OpnForm's client .env file from the template..."
cp "$CLIENT_ENV_EXAMPLE" "$CLIENT_ENV_FILE"
set_env_value "$CLIENT_ENV_FILE" "NUXT_API_SECRET" "$SHARED_SECRET"
fi
echo "✅ OpnForm environment setup is now complete. Enjoy building your forms!"

View File

@ -1,2 +1,2 @@
* *
!.gitignore !.gitignore