diff --git a/404.html b/404.html index d8913332..eed78b25 100644 --- a/404.html +++ b/404.html @@ -4,7 +4,7 @@
docker-compose.yml
file",id:"the-docker-composeyml-file",level:3},{value:"Launch the rocket !",id:"launch-the-rocket-",level:3},{value:"Backup",id:"backup",level:3},{value:"Lespass : Multi tenant engine for membership, ticketing and online cashless refill.",id:"lespass--multi-tenant-engine-for-membership-ticketing-and-online-cashless-refill",level:2},{value:"Prepare the rocket launch",id:"prepare-the-rocket-launch-1",level:3},{value:"Create .env file and fill it with your own variable",id:"create-env-file-and-fill-it-with-your-own-variable-1",level:3},{value:"The docker-compose.yml
file",id:"the-docker-composeyml-file-1",level:3},{value:"Nginx rules",id:"nginx-rules-1",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"legal-warning",children:"Legal warning"}),"\n",(0,r.jsxs)(n.admonition,{type:"danger",children:[(0,r.jsxs)(n.p,{children:["Since January 1, 2018, in order to combat VAT fraud, all VAT-registered professionals recording\ncustomer payments using one of these software or systems are required to use secure, ",(0,r.jsx)(n.strong,{children:"certified hardware"}),"."]}),(0,r.jsxs)(n.p,{children:["A measure enshrined in\n",(0,r.jsx)(n.a,{href:"https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000042914666",children:"Article 286 3\xb0 bis of the General Tax Code"}),"\nand initially stemming from the 2016 Finance Act,\nwhen ",(0,r.jsx)(n.a,{href:"https://www.april.org/reglementation-des-systemes-de-caisse-les-logiciels-libres-de-mieux-en-mieux-pris-en-compte-par-berc",children:"April"}),"\nbecame involved in promoting and defending open-source\nsoftware with cashiering functions."]}),(0,r.jsxs)(n.p,{children:["If you're using ",(0,r.jsx)(n.a,{href:"/docs/presentation/tarifs",children:"TiBillet's Coop' and SaaS model"}),", you don't need to worry about any of\nthis : We provide you with the certificate."]}),(0,r.jsx)(n.p,{children:"But if you self-host your own cash register instance, you legally become the publisher, and we can't provide you with\nany legal documents to present to the tax authorities."}),(0,r.jsx)(n.p,{children:"I imagine that if you're here, it's to install it yourself ;)"}),(0,r.jsx)(n.p,{children:"Here you are informed!"})]}),"\n",(0,r.jsx)(n.p,{children:"More information here (in french) :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.economie.gouv.fr/entreprises/professionnels-logiciels-caisse",children:"https://www.economie.gouv.fr/entreprises/professionnels-logiciels-caisse"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.april.org/reglementation-des-systemes-de-caisse-les-logiciels-libres-de-mieux-en-mieux-pris-en-compte-par-berc",children:"https://www.april.org/reglementation-des-systemes-de-caisse-les-logiciels-libres-de-mieux-en-mieux-pris-en-compte-par-berc"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000042914666",children:"https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000042914666"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"introduction-to-engines",children:"Introduction to Engines"}),"\n",(0,r.jsx)(n.p,{children:"Tibillet is a software suite composed of several interoperable building blocks. The engines are :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/TiBillet/Fedow",children:"Fedow"}),": Federated and open wallet, the federation engine. A PoA and Rsa key based\nblockchain to\nshare membership assets, local currencies and\ntime for several Lespass and LaBoutik instances."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/TiBillet/Lespass",children:"Lespass"}),": Ticketing, booking, membership and landing page engines. Usefull too\nfor refill online with self scanned qrcode unique on each card."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/TiBillet/LaBoutik",children:"LaBoutik"}),": Cash register, cashless system with RFID / NFC chip and order-taking\nsystem."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"To get the full functionality of TiBillet, you need to install these three engines."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["One ",(0,r.jsx)(n.strong,{children:"Fedow"})," for multiple locations (RSA based PoA blockchain)"]}),"\n",(0,r.jsxs)(n.li,{children:["One ",(0,r.jsx)(n.strong,{children:"Lespass"})," for multiple locations (Django multi-tenant)"]}),"\n",(0,r.jsxs)(n.li,{children:["One ",(0,r.jsx)(n.strong,{children:"Laboutik"})," per location, which connects to a fedow and a lespass to join a federation."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{title:"Exemple",type:"note",children:(0,r.jsxs)(n.p,{children:["if you want to use the same NFC card to manage cashless at 2 festivals and 3 community caf\xe9s, you'll need 5\n",(0,r.jsx)(n.strong,{children:"LabouTik"}),", but only one ",(0,r.jsx)(n.strong,{children:"Fedow"})," for the federated asset, and one ",(0,r.jsx)(n.strong,{children:"Lespass"})," for the webpage of each venue.\nThe same applies if you want to manage a co-working subscription for a\ngroup of ",(0,r.jsx)(n.em,{children:"third place"})," in a given city/region/department."]})}),"\n",(0,r.jsx)(n.h1,{id:"requirements-",children:"Requirements :"}),"\n",(0,r.jsxs)(n.p,{children:["For security and performance reasons, we recommend that you separate the ",(0,r.jsx)(n.strong,{children:"Lespass"})," public area from the ",(0,r.jsx)(n.strong,{children:"LaBoutik"}),"\ncheckout and ",(0,r.jsx)(n.strong,{children:"Fedow"})," federation engines."]}),"\n",(0,r.jsx)(n.p,{children:"For dev' and test purpose, you can install everything on one VPS. Here the minimal requirements :"}),"\n",(0,r.jsx)(n.p,{children:"A linux server with :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"2 vCpu / 4Go Ram"}),"\n",(0,r.jsx)(n.li,{children:"Docker & Compose"}),"\n",(0,r.jsx)(n.li,{children:"1 domain with wildcard capacity"}),"\n",(0,r.jsx)(n.li,{children:"A Reverse proxy who handle 443 and 80 port (we use Traefik)"}),"\n",(0,r.jsxs)(n.li,{children:["A valid Stripe account with ",(0,r.jsx)(n.em,{children:"Stripe connect"})]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"You can find some ressource (in french) here :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://codecommun.coop/blog/sysadmin-mon-chaton-part1",children:"https://codecommun.coop/blog/sysadmin-mon-chaton-part1"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://codecommun.coop/blog/sysadmin-mon-chaton-part2",children:"https://codecommun.coop/blog/sysadmin-mon-chaton-part2"})}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"If you're ready for adventure, create a new folder \"TiBillet\", and let's start by installing a Fedow!"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"mkdir TiBillet && cd TiBillet\n"})}),"\n",(0,r.jsx)(n.h3,{id:"generate-many-fernet-key-and-django-secret-key",children:"Generate many Fernet key and django secret key"}),"\n",(0,r.jsx)(n.p,{children:"You will need 3 couple of Fernet/Django secret key."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Generate fernet key with the fedow image :\n# Choose one line and fill the .env file\ndocker run --rm tibillet/fedow:alpha1.2 poetry run python3 -c \"from cryptography.fernet import Fernet; print('\\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))\"\n\n# Generate django secret key with the fedow image :\n# Choose one line and fill the .env file\ndocker run --rm tibillet/fedow:alpha1.2 poetry run python3 -c \"from django.core.management.utils import get_random_secret_key; print('\\n'.join([get_random_secret_key() for i in range(0,30)]))\"\n"})}),"\n",(0,r.jsx)(n.h2,{id:"fedow--one-ring-to-rule-them-all",children:"Fedow : One ring to rule them all"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"mkdir TiBillet/Fedow && cd TiBillet/Fedow\n"})}),"\n",(0,r.jsx)(n.h3,{id:"create-env-file-and-fill-it-with-your-own-variable",children:"Create .env file and fill it with your own variable"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Create .env and fill with :\nSECRET_KEY='' # see upper to create one\nFERNET_KEY='' # see upper to create one\nDOMAIN='' # ex : fedow.domain.com\nSTRIPE_KEY='' # from your stripe account\n"})}),"\n",(0,r.jsx)(n.h3,{id:"prepare-the-rocket-launch",children:"Prepare the rocket launch"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Create frontend and backend network with docker\ndocker network create frontend\ndocker network create fedow_backend\n\n# prepare the logs, assets, database and nginx conf folder\nmkdir logs www database nginx\n"})}),"\n",(0,r.jsx)(n.h3,{id:"nginx-rules",children:"Nginx rules"}),"\n",(0,r.jsxs)(n.p,{children:["Cr\xe9ate the file with ",(0,r.jsx)(n.code,{children:"nano nginx/django.conf"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"server {\n listen 80;\n server_name localhost;\n\n access_log /logs/nginxAccess.log;\n error_log /logs/nginxError.log;\n\n location /static {\n root /www;\n }\n\n location /media {\n root /www;\n }\n\n location / {\n # everything is passed to Gunicorn\n proxy_pass http://fedow_django:8000;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header Host $host;\n proxy_redirect off;\n }\n}\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"the-docker-composeyml-file",children:["The ",(0,r.jsx)(n.code,{children:"docker-compose.yml"})," file"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"services:\n fedow_memcached:\n image: memcached:1.6\n container_name: fedow_memcached\n hostname: fedow_memcached\n restart: always\n networks:\n - fedow_backend\n \n fedow_django:\n image: tibillet/fedow:latest\n container_name: fedow_django\n hostname: fedow_django\n restart: always\n env_file: .env\n user: fedow\n volumes:\n - ./database:/home/fedow/Fedow/database\n - ./www:/home/fedow/Fedow/www\n - ./logs:/home/fedow/Fedow/logs\n links:\n - fedow_memcached:memcached\n networks:\n - fedow_backend\n\n fedow_nginx:\n image: nginx:latest\n restart: always\n container_name: fedow_nginx\n hostname: fedow_nginx\n volumes:\n - ./www:/www\n - ./logs:/logs\n - ./nginx:/etc/nginx/conf.d\n depends_on:\n - fedow_django\n links:\n - fedow_django:fedow_django\n labels:\n - traefik.enable=true\n - traefik.docker.network=frontend\n - traefik.http.routers.fedow_nginx.tls.certresolver=myresolver\n - traefik.http.routers.fedow_nginx.rule=Host(`$DOMAIN`)\n - traefik.http.services.fedow_nginx.loadbalancer.server.port=80\n networks:\n - frontend\n - fedow_backend\n\n\nnetworks:\n frontend:\n external: true\n fedow_backend:\n"})}),"\n",(0,r.jsx)(n.h3,{id:"launch-the-rocket-",children:"Launch the rocket !"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker compose up -d \n# To see the logs :\ndocker compose logs -f \n"})}),"\n",(0,r.jsxs)(n.p,{children:["And check to ",(0,r.jsx)(n.code,{children:"https://docker-compose.yml
file",id:"the-docker-composeyml-file",level:3},{value:"Launch the rocket !",id:"launch-the-rocket-",level:3},{value:"Backup",id:"backup",level:3},{value:"Lespass : Multi tenant engine for membership, ticketing and online cashless refill.",id:"lespass--multi-tenant-engine-for-membership-ticketing-and-online-cashless-refill",level:2},{value:"Prepare the rocket launch",id:"prepare-the-rocket-launch-1",level:3},{value:"Create .env file and fill it with your own variable",id:"create-env-file-and-fill-it-with-your-own-variable-1",level:3},{value:"Nginx rules",id:"nginx-rules-1",level:3},{value:"The docker-compose.yml
file",id:"the-docker-composeyml-file-1",level:3}];function c(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.h2,{id:"legal-warning",children:"Legal warning"}),"\n",(0,r.jsxs)(n.admonition,{type:"danger",children:[(0,r.jsxs)(n.p,{children:["Since January 1, 2018, in order to combat VAT fraud, all VAT-registered professionals recording\ncustomer payments using one of these software or systems are required to use secure, ",(0,r.jsx)(n.strong,{children:"certified hardware"}),"."]}),(0,r.jsxs)(n.p,{children:["A measure enshrined in\n",(0,r.jsx)(n.a,{href:"https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000042914666",children:"Article 286 3\xb0 bis of the General Tax Code"}),"\nand initially stemming from the 2016 Finance Act,\nwhen ",(0,r.jsx)(n.a,{href:"https://www.april.org/reglementation-des-systemes-de-caisse-les-logiciels-libres-de-mieux-en-mieux-pris-en-compte-par-berc",children:"April"}),"\nbecame involved in promoting and defending open-source\nsoftware with cashiering functions."]}),(0,r.jsxs)(n.p,{children:["If you're using ",(0,r.jsx)(n.a,{href:"/docs/presentation/tarifs",children:"TiBillet's Coop' and SaaS model"}),", you don't need to worry about any of\nthis : We provide you with the certificate."]}),(0,r.jsx)(n.p,{children:"But if you self-host your own cash register instance, you legally become the publisher, and we can't provide you with\nany legal documents to present to the tax authorities."}),(0,r.jsx)(n.p,{children:"I imagine that if you're here, it's to install it yourself ;)"}),(0,r.jsx)(n.p,{children:"Here you are informed!"})]}),"\n",(0,r.jsx)(n.p,{children:"More information here (in french) :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.economie.gouv.fr/entreprises/professionnels-logiciels-caisse",children:"https://www.economie.gouv.fr/entreprises/professionnels-logiciels-caisse"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.april.org/reglementation-des-systemes-de-caisse-les-logiciels-libres-de-mieux-en-mieux-pris-en-compte-par-berc",children:"https://www.april.org/reglementation-des-systemes-de-caisse-les-logiciels-libres-de-mieux-en-mieux-pris-en-compte-par-berc"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000042914666",children:"https://www.legifrance.gouv.fr/codes/article_lc/LEGIARTI000042914666"})}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"introduction-to-engines",children:"Introduction to Engines"}),"\n",(0,r.jsx)(n.p,{children:"Tibillet is a software suite composed of several interoperable building blocks. The engines are :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/TiBillet/Fedow",children:"Fedow"}),": Federated and open wallet, the federation engine. A PoA and Rsa key based\nblockchain to\nshare membership assets, local currencies and\ntime for several Lespass and LaBoutik instances."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/TiBillet/Lespass",children:"Lespass"}),": Ticketing, booking, membership and landing page engines. Usefull too\nfor refill online with self scanned qrcode unique on each card."]}),"\n"]}),"\n",(0,r.jsxs)(n.li,{children:["\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.a,{href:"https://github.com/TiBillet/LaBoutik",children:"LaBoutik"}),": Cash register, cashless system with RFID / NFC chip and order-taking\nsystem."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"To get the full functionality of TiBillet, you need to install these three engines."}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["One ",(0,r.jsx)(n.strong,{children:"Fedow"})," for multiple locations (RSA based PoA blockchain)"]}),"\n",(0,r.jsxs)(n.li,{children:["One ",(0,r.jsx)(n.strong,{children:"Lespass"})," for multiple locations (Django multi-tenant)"]}),"\n",(0,r.jsxs)(n.li,{children:["One ",(0,r.jsx)(n.strong,{children:"Laboutik"})," per location, which connects to a fedow and a lespass to join a federation."]}),"\n"]}),"\n",(0,r.jsx)(n.admonition,{title:"Exemple",type:"note",children:(0,r.jsxs)(n.p,{children:["if you want to use the same NFC card to manage cashless at 2 festivals and 3 community caf\xe9s, you'll need 5\n",(0,r.jsx)(n.strong,{children:"LabouTik"}),", but only one ",(0,r.jsx)(n.strong,{children:"Fedow"})," for the federated asset, and one ",(0,r.jsx)(n.strong,{children:"Lespass"})," for the webpage of each venue.\nThe same applies if you want to manage a co-working subscription for a\ngroup of ",(0,r.jsx)(n.em,{children:"third place"})," in a given city/region/department."]})}),"\n",(0,r.jsx)(n.h1,{id:"requirements-",children:"Requirements :"}),"\n",(0,r.jsxs)(n.p,{children:["For security and performance reasons, we recommend that you separate the ",(0,r.jsx)(n.strong,{children:"Lespass"})," public area from the ",(0,r.jsx)(n.strong,{children:"LaBoutik"}),"\ncheckout and ",(0,r.jsx)(n.strong,{children:"Fedow"})," federation engines."]}),"\n",(0,r.jsx)(n.p,{children:"For dev' and test purpose, you can install everything on one VPS. Here the minimal requirements :"}),"\n",(0,r.jsx)(n.p,{children:"A linux server with :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:"2 vCpu / 4Go Ram"}),"\n",(0,r.jsx)(n.li,{children:"Docker & Compose"}),"\n",(0,r.jsx)(n.li,{children:"1 domain with wildcard capacity"}),"\n",(0,r.jsx)(n.li,{children:"A Reverse proxy who handle 443 and 80 port (we use Traefik)"}),"\n",(0,r.jsxs)(n.li,{children:["A valid Stripe account with ",(0,r.jsx)(n.em,{children:"Stripe connect"})]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"You can find some ressource (in french) here :"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://codecommun.coop/blog/sysadmin-mon-chaton-part1",children:"https://codecommun.coop/blog/sysadmin-mon-chaton-part1"})}),"\n",(0,r.jsx)(n.li,{children:(0,r.jsx)(n.a,{href:"https://codecommun.coop/blog/sysadmin-mon-chaton-part2",children:"https://codecommun.coop/blog/sysadmin-mon-chaton-part2"})}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"If you're ready for adventure, create a new folder \"TiBillet\", and let's start by installing a Fedow!"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"mkdir TiBillet && cd TiBillet\n"})}),"\n",(0,r.jsx)(n.h3,{id:"generate-many-fernet-key-and-django-secret-key",children:"Generate many Fernet key and django secret key"}),"\n",(0,r.jsx)(n.p,{children:"You will need 3 couple of Fernet/Django secret key."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Generate fernet key with the fedow image :\n# Choose one line and fill the .env file\ndocker run --rm tibillet/fedow:alpha1.2 poetry run python3 -c \"from cryptography.fernet import Fernet; print('\\n'.join([Fernet.generate_key().decode('utf-8') for i in range(0,30)]))\"\n\n# Generate django secret key with the fedow image :\n# Choose one line and fill the .env file\ndocker run --rm tibillet/fedow:alpha1.2 poetry run python3 -c \"from django.core.management.utils import get_random_secret_key; print('\\n'.join([get_random_secret_key() for i in range(0,30)]))\"\n"})}),"\n",(0,r.jsx)(n.h2,{id:"fedow--one-ring-to-rule-them-all",children:"Fedow : One ring to rule them all"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"mkdir TiBillet/Fedow && cd TiBillet/Fedow\n"})}),"\n",(0,r.jsx)(n.h3,{id:"create-env-file-and-fill-it-with-your-own-variable",children:"Create .env file and fill it with your own variable"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Create .env and fill with :\nSECRET_KEY='' # see upper to create one\nFERNET_KEY='' # see upper to create one\nDOMAIN='' # ex : fedow.domain.com\nSTRIPE_KEY='' # from your stripe account\n"})}),"\n",(0,r.jsx)(n.h3,{id:"prepare-the-rocket-launch",children:"Prepare the rocket launch"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"# Create frontend and backend network with docker\ndocker network create frontend\ndocker network create fedow_backend\n\n# prepare the logs, assets, database and nginx conf folder\nmkdir logs www database nginx\n"})}),"\n",(0,r.jsx)(n.h3,{id:"nginx-rules",children:"Nginx rules"}),"\n",(0,r.jsxs)(n.p,{children:["Cr\xe9ate the file with ",(0,r.jsx)(n.code,{children:"nano nginx/django.conf"})]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{children:"server {\n listen 80;\n server_name localhost;\n\n access_log /logs/nginxAccess.log;\n error_log /logs/nginxError.log;\n\n location /static {\n root /www;\n }\n\n location /media {\n root /www;\n }\n\n location / {\n # everything is passed to Gunicorn\n proxy_pass http://fedow_django:8000;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header Host $host;\n proxy_redirect off;\n }\n}\n"})}),"\n",(0,r.jsxs)(n.h3,{id:"the-docker-composeyml-file",children:["The ",(0,r.jsx)(n.code,{children:"docker-compose.yml"})," file"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-yaml",children:"services:\n fedow_memcached:\n image: memcached:1.6\n container_name: fedow_memcached\n hostname: fedow_memcached\n restart: always\n networks:\n - fedow_backend\n \n fedow_django:\n image: tibillet/fedow:latest\n container_name: fedow_django\n hostname: fedow_django\n restart: always\n env_file: .env\n user: fedow\n volumes:\n - ./database:/home/fedow/Fedow/database\n - ./www:/home/fedow/Fedow/www\n - ./logs:/home/fedow/Fedow/logs\n links:\n - fedow_memcached:memcached\n networks:\n - fedow_backend\n\n fedow_nginx:\n image: nginx:latest\n restart: always\n container_name: fedow_nginx\n hostname: fedow_nginx\n volumes:\n - ./www:/www\n - ./logs:/logs\n - ./nginx:/etc/nginx/conf.d\n depends_on:\n - fedow_django\n links:\n - fedow_django:fedow_django\n labels:\n - traefik.enable=true\n - traefik.docker.network=frontend\n - traefik.http.routers.fedow_nginx.tls.certresolver=myresolver\n - traefik.http.routers.fedow_nginx.rule=Host(`$DOMAIN`)\n - traefik.http.services.fedow_nginx.loadbalancer.server.port=80\n networks:\n - frontend\n - fedow_backend\n\n\nnetworks:\n frontend:\n external: true\n fedow_backend:\n"})}),"\n",(0,r.jsx)(n.h3,{id:"launch-the-rocket-",children:"Launch the rocket !"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-bash",children:"docker compose up -d \n# To see the logs :\ndocker compose logs -f \n"})}),"\n",(0,r.jsxs)(n.p,{children:["And check to ",(0,r.jsx)(n.code,{children:"https://# prepare the logs, assets, backup and database folder
mkdir logs www backup database nginx
# Secret
DJANGO_SECRET='' # see upper to create one
FERNET_KEY='' # see upper to create one
STRIPE_KEY='' # from your stripe account
# or
STRIPE_KEY_TEST=''
STRIPE_TEST=0 # set to 1 for use stripe test env
# Database
POSTGRES_HOST='lespass_postgres'
POSTGRES_USER='lespass_postgres_user'
POSTGRES_PASSWORD='' # strong ! generate a new fernet for exemple.
POSTGRES_DB='lespass'
TIME_ZONE='Europe/Paris' # or where you are
PUBLIC='TiBillet Coop.' # The name of the root instance
FEDOW_DOMAIN='' # the same as Fedow
DOMAIN='' # for the wildcard : without subdomain ! ex : tibillet.coop, not lespass.tibillet.coop
SUB='' # the sub domain of your first place ex : if 'festival', it will be accessible on https://festival.tibillet.coop
META='' # the federated agenda for all events on all tenants. If 'agenda', it will be accessible, for exemple, on https://agenda.tibillet.coop
# For transactionnal email :
EMAIL_HOST=''
EMAIL_PORT=''
EMAIL_HOST_USER=''
EMAIL_HOST_PASSWORD=''
# Change only if needed :
CELERY_BROKER='redis://redis:6379/0'
CELERY_BACKEND='redis://redis:6379/0'
docker-compose.yml
fileservices:
lespass_postgres:
image: postgres:13-bookworm
restart: unless-stopped
container_name: lespass_postgres
hostname: lespass_postgres
volumes:
- ./database/data:/var/lib/postgresql/data
env_file: .env
networks:
- lespass_backend
lespas_memcached:
image : memcached:1.6
container_name: lespas_memcached
hostname: lespas_memcached
restart: always
networks:
- lespass_backend
lespas_redis:
container_name: lespas_redis
hostname: lespas_redis
image: redis:7.2.3-bookworm
restart: unless-stopped
networks:
- lespass_backend
lespass_django:
image: tibillet/lespass:latest
restart: unless-stopped
container_name: lespass_django
hostname: lespass_django
volumes:
- ./www:/DjangoFiles/www
- ./logs:/DjangoFiles/logs
- ./backup:/Backup
env_file: .env
depends_on:
- lespass_postgres
- lespas_redis
links:
- lespass_postgres:postgres
- lespas_redis:redis
- lespas_memcached:memcached
networks:
- lespass_backend
# command: "sleep infinity"
lespass_celery:
image: tibillet/lespass:latest
container_name: lespass_celery
hostname: lespass_celery
env_file: .env
depends_on:
- lespass_postgres
- lespas_redis
links:
- lespass_postgres:postgres
- lespas_redis:redis
- lespas_memcached:memcached
networks:
- lespass_backend
# command: "sleep infinity"
command: "poetry run celery -A TiBillet worker -l INFO"
lespass_nginx:
image: nginx:latest
container_name: lespass_nginx
hostname: lespass_nginx
links:
- lespass_django:lespass_django
volumes:
- ./www:/www
- ./logs:/logs
- ./nginx:/etc/nginx/conf.d
labels:
- traefik.enable=true
- traefik.docker.network=frontend
- traefik.http.routers.lespass_nginx.tls.certresolver=myresolver
- traefik.http.routers.lespass_nginx.rule=Host(`$DOMAIN`) || Host(`www.$DOMAIN`) || Host(`$META.$DOMAIN`) || Host(`$SUB.$DOMAIN`)
- traefik.http.services.lespass_nginx.loadbalancer.server.port=80
networks:
- frontend
- lespass_backend
networks:
frontend:
external: true
lespass_backend:
Créate the file with nano nginx/lespass.conf
server {
listen 80;
server_name localhost;
access_log /logs/nginxAccess.log;
error_log /logs/nginxError.log;
location /static {
root /www;
}
location /media {
root /www;
}
location / {
# everything is passed to Gunicorn
proxy_pass http://lespass_django:8002;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_http_version 1.1;
client_max_body_size 4M;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
}
}
server {
listen 80;
server_name localhost;
access_log /logs/nginxAccess.log;
error_log /logs/nginxError.log;
location /static {
root /www;
}
location /media {
root /www;
}
location / {
# everything is passed to Gunicorn
proxy_pass http://lespass_django:8002;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_http_version 1.1;
client_max_body_size 4M;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $server_name;
}
}
docker-compose.yml
fileservices:
lespass_postgres:
image: postgres:13-bookworm
restart: unless-stopped
container_name: lespass_postgres
hostname: lespass_postgres
volumes:
- ./database/data:/var/lib/postgresql/data
env_file: .env
networks:
- lespass_backend
lespas_memcached:
image : memcached:1.6
container_name: lespas_memcached
hostname: lespas_memcached
restart: always
networks:
- lespass_backend
lespas_redis:
container_name: lespas_redis
hostname: lespas_redis
image: redis:7.2.3-bookworm
restart: unless-stopped
networks:
- lespass_backend
lespass_django:
image: tibillet/lespass:latest
restart: unless-stopped
container_name: lespass_django
hostname: lespass_django
volumes:
- ./www:/DjangoFiles/www
- ./logs:/DjangoFiles/logs
- ./backup:/Backup
env_file: .env
depends_on:
- lespass_postgres
- lespas_redis
links:
- lespass_postgres:postgres
- lespas_redis:redis
- lespas_memcached:memcached
networks:
- lespass_backend
# command: "sleep infinity"
lespass_celery:
image: tibillet/lespass:latest
container_name: lespass_celery
hostname: lespass_celery
env_file: .env
depends_on:
- lespass_postgres
- lespas_redis
links:
- lespass_postgres:postgres
- lespas_redis:redis
- lespas_memcached:memcached
networks:
- lespass_backend
# command: "sleep infinity"
command: "poetry run celery -A TiBillet worker -l INFO"
lespass_nginx:
image: nginx:latest
container_name: lespass_nginx
hostname: lespass_nginx
links:
- lespass_django:lespass_django
volumes:
- ./www:/www
- ./logs:/logs
- ./nginx:/etc/nginx/conf.d
labels:
- traefik.enable=true
- traefik.docker.network=frontend
- traefik.http.routers.lespass_nginx.tls.certresolver=myresolver
- traefik.http.routers.lespass_nginx.rule=Host(`$DOMAIN`) || Host(`www.$DOMAIN`) || Host(`$META.$DOMAIN`) || Host(`$SUB.$DOMAIN`)
- traefik.http.services.lespass_nginx.loadbalancer.server.port=80
networks:
- frontend
- lespass_backend
networks:
frontend:
external: true
lespass_backend: